mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 11:06:06 -04:00
avoid blocks2 allocation in some cases
This commit is contained in:
parent
7e92d18f40
commit
30f5ae7947
@ -70,7 +70,7 @@ namespace ClassicalSharp {
|
|||||||
public static FastColour[] FogColour;
|
public static FastColour[] FogColour;
|
||||||
public static Vector3[] MinBB, MaxBB, RenderMinBB, RenderMaxBB;
|
public static Vector3[] MinBB, MaxBB, RenderMinBB, RenderMaxBB;
|
||||||
static uint[] DefinedCustomBlocks;
|
static uint[] DefinedCustomBlocks;
|
||||||
public static int MaxDefined, Count, IDMask;
|
public static int MaxUsed, Count, IDMask;
|
||||||
|
|
||||||
public static void Allocate(int count) {
|
public static void Allocate(int count) {
|
||||||
IsLiquid = new bool[count];
|
IsLiquid = new bool[count];
|
||||||
@ -100,9 +100,13 @@ namespace ClassicalSharp {
|
|||||||
RenderMaxBB = new Vector3[count];
|
RenderMaxBB = new Vector3[count];
|
||||||
|
|
||||||
DefinedCustomBlocks = new uint[count >> 5];
|
DefinedCustomBlocks = new uint[count >> 5];
|
||||||
MaxDefined = count - 1;
|
|
||||||
Count = count;
|
Count = count;
|
||||||
IDMask = Utils.NextPowerOf2(Count) - 1;
|
SetMaxUsed(count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetMaxUsed(int max) {
|
||||||
|
MaxUsed = max;
|
||||||
|
IDMask = Utils.NextPowerOf2(max + 1) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Reset() {
|
public static void Reset() {
|
||||||
|
@ -123,7 +123,7 @@ namespace ClassicalSharp.Entities {
|
|||||||
|
|
||||||
ModelBlock = Block.Air;
|
ModelBlock = Block.Air;
|
||||||
BlockID block;
|
BlockID block;
|
||||||
if (BlockID.TryParse(ModelName, out block) && block <= BlockInfo.MaxDefined) {
|
if (BlockID.TryParse(ModelName, out block) && block < BlockInfo.Count) {
|
||||||
ModelName = "block";
|
ModelName = "block";
|
||||||
ModelBlock = block;
|
ModelBlock = block;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace ClassicalSharp.Map {
|
|||||||
int i = (maxY * length + z) * width + x;
|
int i = (maxY * length + z) * width + x;
|
||||||
BlockRaw[] blocks = game.World.blocks;
|
BlockRaw[] blocks = game.World.blocks;
|
||||||
|
|
||||||
if (BlockInfo.MaxDefined < 256) {
|
if (BlockInfo.MaxUsed < 256) {
|
||||||
for (int y = maxY; y >= 0; y--, i -= oneY) {
|
for (int y = maxY; y >= 0; y--, i -= oneY) {
|
||||||
int block = blocks[i];
|
int block = blocks[i];
|
||||||
if (BlockInfo.BlocksLight[block]) {
|
if (BlockInfo.BlocksLight[block]) {
|
||||||
|
@ -117,7 +117,7 @@ namespace ClassicalSharp.Map {
|
|||||||
BlockRaw[] blocks = world.blocks;
|
BlockRaw[] blocks = world.blocks;
|
||||||
|
|
||||||
// Update if any blocks in the chunk are affected by light change
|
// Update if any blocks in the chunk are affected by light change
|
||||||
if (BlockInfo.MaxDefined < 256) {
|
if (BlockInfo.MaxUsed < 256) {
|
||||||
for (; y >= minY; y--, i -= world.OneY) {
|
for (; y >= minY; y--, i -= world.OneY) {
|
||||||
BlockID other = blocks[i];
|
BlockID other = blocks[i];
|
||||||
bool affected = y == nY ? Needs(block, other) : BlockInfo.Draw[other] != DrawType.Gas;
|
bool affected = y == nY ? Needs(block, other) : BlockInfo.Draw[other] != DrawType.Gas;
|
||||||
|
@ -71,7 +71,7 @@ namespace ClassicalSharp.Map {
|
|||||||
|
|
||||||
int elemsLeft = InitialHeightmapCoverage(x1, z1, xCount, zCount, skip);
|
int elemsLeft = InitialHeightmapCoverage(x1, z1, xCount, zCount, skip);
|
||||||
#if !ONLY_8BIT
|
#if !ONLY_8BIT
|
||||||
if (BlockInfo.MaxDefined >= 256) {
|
if (BlockInfo.MaxUsed >= 256) {
|
||||||
fixed (BlockRaw* mapPtr2 = game.World.blocks2) {
|
fixed (BlockRaw* mapPtr2 = game.World.blocks2) {
|
||||||
if (!CalculateHeightmapCoverage_16Bit(x1, z1, xCount, zCount, elemsLeft, skip, mapPtr, mapPtr2)) {
|
if (!CalculateHeightmapCoverage_16Bit(x1, z1, xCount, zCount, elemsLeft, skip, mapPtr, mapPtr2)) {
|
||||||
FinishHeightmapCoverage(x1, z1, xCount, zCount, skip);
|
FinishHeightmapCoverage(x1, z1, xCount, zCount, skip);
|
||||||
|
@ -66,7 +66,13 @@ namespace ClassicalSharp.Map {
|
|||||||
public void SetBlock(int x, int y, int z, BlockID blockId) {
|
public void SetBlock(int x, int y, int z, BlockID blockId) {
|
||||||
int i = (y * Length + z) * Width + x;
|
int i = (y * Length + z) * Width + x;
|
||||||
blocks[i] = (BlockRaw)blockId;
|
blocks[i] = (BlockRaw)blockId;
|
||||||
if (blocks == blocks2) return;
|
|
||||||
|
// defer allocation of second map array if possible
|
||||||
|
if (blocks == blocks2) {
|
||||||
|
if (blockId < 256) return;
|
||||||
|
blocks2 = new BlockRaw[blocks.Length];
|
||||||
|
BlockInfo.SetMaxUsed(767);
|
||||||
|
}
|
||||||
blocks2[i] = (BlockRaw)(blockId >> 8);
|
blocks2[i] = (BlockRaw)(blockId >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ namespace ClassicalSharp {
|
|||||||
bool allSolid = false;
|
bool allSolid = false;
|
||||||
fixed (BlockRaw* mapPtr = map.blocks) {
|
fixed (BlockRaw* mapPtr = map.blocks) {
|
||||||
#if !ONLY_8BIT
|
#if !ONLY_8BIT
|
||||||
if (BlockInfo.MaxDefined >= 256) {
|
if (BlockInfo.MaxUsed >= 256) {
|
||||||
ReadChunkData_16Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid);
|
ReadChunkData_16Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid);
|
||||||
} else {
|
} else {
|
||||||
ReadChunkData_8Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid);
|
ReadChunkData_8Bit(x1, y1, z1, mapPtr, ref allAir, ref allSolid);
|
||||||
|
@ -198,6 +198,7 @@ namespace ClassicalSharp.Network {
|
|||||||
|
|
||||||
reader.ExtendedPositions = false; reader.ExtendedBlocks = false;
|
reader.ExtendedPositions = false; reader.ExtendedBlocks = false;
|
||||||
writer.ExtendedPositions = false; writer.ExtendedBlocks = false;
|
writer.ExtendedPositions = false; writer.ExtendedBlocks = false;
|
||||||
|
BlockInfo.SetMaxUsed(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Action[] handlers = new Action[256];
|
internal Action[] handlers = new Action[256];
|
||||||
|
@ -324,13 +324,14 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
int value = reader.ReadInt32();
|
int value = reader.ReadInt32();
|
||||||
WorldEnv env = game.World.Env;
|
WorldEnv env = game.World.Env;
|
||||||
Utils.Clamp(ref value, -0xFFFFFF, 0xFFFFFF);
|
Utils.Clamp(ref value, -0xFFFFFF, 0xFFFFFF);
|
||||||
|
int maxBlock = BlockInfo.Count - 1;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
Utils.Clamp(ref value, 0, BlockInfo.MaxDefined);
|
Utils.Clamp(ref value, 0, maxBlock);
|
||||||
env.SetSidesBlock((BlockID)value); break;
|
env.SetSidesBlock((BlockID)value); break;
|
||||||
case 1:
|
case 1:
|
||||||
Utils.Clamp(ref value, 0, BlockInfo.MaxDefined);
|
Utils.Clamp(ref value, 0, maxBlock);
|
||||||
env.SetEdgeBlock((BlockID)value); break;
|
env.SetEdgeBlock((BlockID)value); break;
|
||||||
case 2:
|
case 2:
|
||||||
env.SetEdgeLevel(value); break;
|
env.SetEdgeLevel(value); break;
|
||||||
|
@ -46,7 +46,7 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
DateTime mapReceiveStart;
|
DateTime mapReceiveStart;
|
||||||
DeflateStream gzipStream;
|
DeflateStream gzipStream;
|
||||||
GZipHeaderReader gzipHeader;
|
GZipHeaderReader gzipHeader;
|
||||||
int mapSizeIndex, mapIndex;
|
int mapSizeIndex, mapIndex, mapVolume;
|
||||||
byte[] mapSize = new byte[4], map;
|
byte[] mapSize = new byte[4], map;
|
||||||
FixedBufferStream mapPartStream;
|
FixedBufferStream mapPartStream;
|
||||||
Screen prevScreen;
|
Screen prevScreen;
|
||||||
@ -78,13 +78,10 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
|
|
||||||
// Fast map puts volume in header, doesn't bother with gzip
|
// Fast map puts volume in header, doesn't bother with gzip
|
||||||
if (net.cpeData.fastMap) {
|
if (net.cpeData.fastMap) {
|
||||||
int size = reader.ReadInt32();
|
mapVolume = reader.ReadInt32();
|
||||||
gzipHeader.done = true;
|
gzipHeader.done = true;
|
||||||
mapSizeIndex = 4;
|
mapSizeIndex = 4;
|
||||||
map = new byte[size];
|
map = new byte[mapVolume];
|
||||||
#if !ONLY_8BIT
|
|
||||||
if (reader.ExtendedBlocks) map2 = new byte[size];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,15 +147,14 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
|
|
||||||
if (mapSizeIndex == 4) {
|
if (mapSizeIndex == 4) {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
int size = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
|
mapVolume = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
|
||||||
map = new byte[size];
|
map = new byte[mapVolume];
|
||||||
#if !ONLY_8BIT
|
|
||||||
if (reader.ExtendedBlocks) map2 = new byte[size];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !ONLY_8BIT
|
#if !ONLY_8BIT
|
||||||
if (reader.ExtendedBlocks && value != 0) {
|
if (reader.ExtendedBlocks && value != 0) {
|
||||||
|
// Only allocate map2 when needed
|
||||||
|
if (map2 == null) map2 = new byte[mapVolume];
|
||||||
mapIndex2 += gzipStream2.Read(map2, mapIndex2, map2.Length - mapIndex2);
|
mapIndex2 += gzipStream2.Read(map2, mapIndex2, map2.Length - mapIndex2);
|
||||||
} else {
|
} else {
|
||||||
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
|
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
|
||||||
@ -181,7 +177,7 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
}
|
}
|
||||||
prevScreen = null;
|
prevScreen = null;
|
||||||
|
|
||||||
int mapWidth = reader.ReadUInt16();
|
int mapWidth = reader.ReadUInt16();
|
||||||
int mapHeight = reader.ReadUInt16();
|
int mapHeight = reader.ReadUInt16();
|
||||||
int mapLength = reader.ReadUInt16();
|
int mapLength = reader.ReadUInt16();
|
||||||
|
|
||||||
@ -190,7 +186,11 @@ namespace ClassicalSharp.Network.Protocols {
|
|||||||
|
|
||||||
game.World.SetNewMap(map, mapWidth, mapHeight, mapLength);
|
game.World.SetNewMap(map, mapWidth, mapHeight, mapLength);
|
||||||
#if !ONLY_8BIT
|
#if !ONLY_8BIT
|
||||||
if (reader.ExtendedBlocks) game.World.blocks2 = map2;
|
if (reader.ExtendedBlocks) {
|
||||||
|
// defer allocation of scond map array if possible
|
||||||
|
game.World.blocks2 = map2 == null ? map : map2;
|
||||||
|
BlockInfo.SetMaxUsed(map2 == null ? 255 : 767);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
game.WorldEvents.RaiseOnNewMapLoaded();
|
game.WorldEvents.RaiseOnNewMapLoaded();
|
||||||
net.wom.CheckSendWomID();
|
net.wom.CheckSendWomID();
|
||||||
|
@ -161,7 +161,7 @@ namespace ClassicalSharp.Renderers {
|
|||||||
int i = (maxY * length + z) * width + x;
|
int i = (maxY * length + z) * width + x;
|
||||||
BlockRaw[] blocks = map.blocks;
|
BlockRaw[] blocks = map.blocks;
|
||||||
|
|
||||||
if (BlockInfo.MaxDefined < 256) {
|
if (BlockInfo.MaxUsed < 256) {
|
||||||
for (int y = maxY; y >= 0; y--, i -= oneY) {
|
for (int y = maxY; y >= 0; y--, i -= oneY) {
|
||||||
byte draw = BlockInfo.Draw[blocks[i]];
|
byte draw = BlockInfo.Draw[blocks[i]];
|
||||||
if (!(draw == DrawType.Gas || draw == DrawType.Sprite)) {
|
if (!(draw == DrawType.Gas || draw == DrawType.Sprite)) {
|
||||||
|
@ -31,28 +31,28 @@ typedef struct GuiElementVTABLE_ {
|
|||||||
typedef struct GuiElement_ { GuiElementVTABLE* VTABLE; } GuiElement;
|
typedef struct GuiElement_ { GuiElementVTABLE* VTABLE; } GuiElement;
|
||||||
void GuiElement_Reset(GuiElement* elem);
|
void GuiElement_Reset(GuiElement* elem);
|
||||||
|
|
||||||
/*
|
|
||||||
HandlesAllInput; / Whether this screen handles all input. Prevents user interacting with the world
|
#define Screen_Layout GuiElementVTABLE* VTABLE; \
|
||||||
BlocksWorld; / Whether this screen completely and opaquely covers the game world behind it
|
bool HandlesAllInput; /* Whether this screen handles all input. Prevents user interacting with the world */ \
|
||||||
HidesHUD; / Whether this screen hides the normal in-game HUD
|
bool BlocksWorld; /* Whether this screen completely and opaquely covers the game world behind it */ \
|
||||||
RenderHUDOver; / Whether the normal in-game HUD should be drawn over the top of this screen */
|
bool HidesHUD; /* Whether this screen hides the normal in-game HUD */ \
|
||||||
#define Screen_Layout GuiElementVTABLE* VTABLE; bool HandlesAllInput, BlocksWorld; \
|
bool RenderHUDOver; /* Whether the normal in-game HUD should be drawn over the top of this screen */ \
|
||||||
bool HidesHUD, RenderHUDOver; void (*OnResize)(GuiElement* elem);
|
void (*OnResize)(GuiElement* elem);
|
||||||
|
|
||||||
/* Represents a container of widgets and other 2D elements. May cover entire window. */
|
/* Represents a container of widgets and other 2D elements. May cover entire window. */
|
||||||
typedef struct Screen_ { Screen_Layout } Screen;
|
typedef struct Screen_ { Screen_Layout } Screen;
|
||||||
void Screen_Reset(Screen* screen);
|
void Screen_Reset(Screen* screen);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
X, Y, Width, Height; / Top left corner, and dimensions, of this widget
|
|
||||||
Active; / Whether this widget is currently being moused over
|
|
||||||
Disabled; / Whether widget is prevented from being interacted with
|
|
||||||
HorAnchor, VerAnchor; / Specifies the reference point for when this widget is resized
|
|
||||||
XOffset, YOffset; / Offset from the reference point */
|
|
||||||
typedef void (*Widget_LeftClick)(GuiElement* screenElem, GuiElement* widget);
|
typedef void (*Widget_LeftClick)(GuiElement* screenElem, GuiElement* widget);
|
||||||
#define Widget_Layout GuiElementVTABLE* VTABLE; Int32 X, Y, Width, Height; bool Active, Disabled; \
|
#define Widget_Layout GuiElementVTABLE* VTABLE; \
|
||||||
UInt8 HorAnchor, VerAnchor; Int32 XOffset, YOffset; void (*Reposition)(GuiElement* elem); Widget_LeftClick MenuClick;
|
Int32 X, Y, Width, Height; /* Top left corner, and dimensions, of this widget */ \
|
||||||
|
bool Active; /* Whether this widget is currently being moused over*/ \
|
||||||
|
bool Disabled; /* Whether widget is prevented from being interacted with */ \
|
||||||
|
UInt8 HorAnchor, VerAnchor; /* Specifies the reference point for when this widget is resized */ \
|
||||||
|
Int32 XOffset, YOffset; /* Offset from the reference point */ \
|
||||||
|
void (*Reposition)(GuiElement* elem); \
|
||||||
|
Widget_LeftClick MenuClick;
|
||||||
|
|
||||||
/* Represents an individual 2D gui component. */
|
/* Represents an individual 2D gui component. */
|
||||||
typedef struct Widget_ { Widget_Layout } Widget;
|
typedef struct Widget_ { Widget_Layout } Widget;
|
||||||
@ -60,6 +60,7 @@ void Widget_DoReposition(GuiElement* elem);
|
|||||||
void Widget_Init(Widget* widget);
|
void Widget_Init(Widget* widget);
|
||||||
bool Widget_Contains(Widget* widget, Int32 x, Int32 y);
|
bool Widget_Contains(Widget* widget, Int32 x, Int32 y);
|
||||||
|
|
||||||
|
|
||||||
GfxResourceID Gui_GuiTex, Gui_GuiClassicTex, Gui_IconsTex;
|
GfxResourceID Gui_GuiTex, Gui_GuiClassicTex, Gui_IconsTex;
|
||||||
Screen* Gui_HUD;
|
Screen* Gui_HUD;
|
||||||
Screen* Gui_Active;
|
Screen* Gui_Active;
|
||||||
|
@ -588,9 +588,8 @@ void TableWidget_MakeDescTex(TableWidget* widget, BlockID block) {
|
|||||||
TableWidget_UpdateDescTexPos(widget);
|
TableWidget_UpdateDescTexPos(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TableWidget_RowEmpty(Int32 i) {
|
bool TableWidget_RowEmpty(TableWidget* widget, Int32 i) {
|
||||||
BlockID[] map = game.Inventory.Map;
|
Int32 max = min(i + widget->ElementsPerRow, (Int32)Array_Elems(Inventory_Map));
|
||||||
int max = Math.Min(i + ElementsPerRow, map.Length);
|
|
||||||
|
|
||||||
Int32 j;
|
Int32 j;
|
||||||
for (j = i; j < max; j++) {
|
for (j = i; j < max; j++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user