actually save and load Block2

This commit is contained in:
UnknownShadow200 2019-02-03 15:28:19 +11:00
parent 7b11593288
commit e9b525f487
5 changed files with 47 additions and 15 deletions

View File

@ -421,6 +421,18 @@ static ReturnCode Nbt_ReadTag(uint8_t typeId, bool readTagName, struct Stream* s
/*########################################################################################################################* /*########################################################################################################################*
*--------------------------------------------------ClassicWorld format----------------------------------------------------* *--------------------------------------------------ClassicWorld format----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static void* Cw_GetBlocks(struct NbtTag* tag) {
void* ptr;
if (NbtTag_IsSmall(tag)) {
ptr = Mem_Alloc(tag->DataSize, 1, ".cw map blocks");
Mem_Copy(ptr, tag->Value.Small, tag->DataSize);
} else {
ptr = tag->Value.Big;
tag->Value.Big = NULL; /* So Nbt_ReadTag doesn't call Mem_Free on World.Blocks */
}
return ptr;
}
static void Cw_Callback_1(struct NbtTag* tag) { static void Cw_Callback_1(struct NbtTag* tag) {
if (IsTag(tag, "X")) { World.Width = NbtTag_U16(tag); return; } if (IsTag(tag, "X")) { World.Width = NbtTag_U16(tag); return; }
if (IsTag(tag, "Y")) { World.Height = NbtTag_U16(tag); return; } if (IsTag(tag, "Y")) { World.Height = NbtTag_U16(tag); return; }
@ -434,17 +446,14 @@ static void Cw_Callback_1(struct NbtTag* tag) {
if (IsTag(tag, "BlockArray")) { if (IsTag(tag, "BlockArray")) {
World.Volume = tag->DataSize; World.Volume = tag->DataSize;
if (NbtTag_IsSmall(tag)) { World.Blocks = Cw_GetBlocks(tag);
World.Blocks = Mem_Alloc(World.Volume, 1, ".cw map blocks");
Mem_Copy(World.Blocks, tag->Value.Small, tag->DataSize);
} else {
World.Blocks = tag->Value.Big;
tag->Value.Big = NULL; /* So Nbt_ReadTag doesn't call Mem_Free on World.Blocks */
}
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS
World.Blocks2 = World.Blocks; World.Blocks2 = World.Blocks;
#endif #endif
} }
#ifdef EXTENDED_BLOCKS
if (IsTag(tag, "BlockArray2")) World_SetMapUpper(Cw_GetBlocks(tag));
#endif
} }
static void Cw_Callback_2(struct NbtTag* tag) { static void Cw_Callback_2(struct NbtTag* tag) {
@ -892,6 +901,9 @@ NBT_DICT, 0,12, 'C','l','a','s','s','i','c','W','o','r','l','d',
NBT_END, NBT_END,
NBT_I8S, 0,10, 'B','l','o','c','k','A','r','r','a','y', 0,0,0,0, NBT_I8S, 0,10, 'B','l','o','c','k','A','r','r','a','y', 0,0,0,0,
}; };
static uint8_t cw_map2[18] = {
NBT_I8S, 0,11, 'B','l','o','c','k','A','r','r','a','y','2', 0,0,0,0,
};
static uint8_t cw_meta_cpe[303] = { static uint8_t cw_meta_cpe[303] = {
NBT_DICT, 0,8, 'M','e','t','a','d','a','t','a', NBT_DICT, 0,8, 'M','e','t','a','d','a','t','a',
NBT_DICT, 0,3, 'C','P','E', NBT_DICT, 0,3, 'C','P','E',
@ -1019,6 +1031,14 @@ ReturnCode Cw_Save(struct Stream* stream) {
if ((res = Stream_Write(stream, tmp, sizeof(cw_begin)))) return res; if ((res = Stream_Write(stream, tmp, sizeof(cw_begin)))) return res;
if ((res = Stream_Write(stream, World.Blocks, World.Volume))) return res; if ((res = Stream_Write(stream, World.Blocks, World.Volume))) return res;
if (World.Blocks != World.Blocks2) {
Mem_Copy(tmp, cw_map2, sizeof(cw_map2));
Stream_SetU32_BE(&tmp[14], World.Volume);
if ((res = Stream_Write(stream, tmp, sizeof(cw_map2)))) return res;
if ((res = Stream_Write(stream, World.Blocks2, World.Volume))) return res;
}
Mem_Copy(tmp, cw_meta_cpe, sizeof(cw_meta_cpe)); Mem_Copy(tmp, cw_meta_cpe, sizeof(cw_meta_cpe));
{ {
Stream_SetU16_BE(&tmp[44], (uint16_t)(LocalPlayer_Instance.ReachDistance * 32)); Stream_SetU16_BE(&tmp[44], (uint16_t)(LocalPlayer_Instance.ReachDistance * 32));

View File

@ -510,10 +510,9 @@ static void Classic_LevelFinalise(uint8_t* data) {
World_SetNewMap(map_blocks, width, height, length); World_SetNewMap(map_blocks, width, height, length);
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS
if (cpe_extBlocks) { /* defer allocation of second map array if possible */
/* defer allocation of scond map array if possible */ if (cpe_extBlocks && map2_blocks) {
World.Blocks2 = map2_blocks ? map2_blocks : map_blocks; World_SetMapUpper(map2_blocks);
Block_SetUsedCount(map2_blocks ? 768 : 256);
} }
#endif #endif

View File

@ -105,8 +105,8 @@ int main(int argc, char** argv) {
argsCount = Platform_GetCommandLineArgs(argc, argv, args); argsCount = Platform_GetCommandLineArgs(argc, argv, args);
/* NOTE: Make sure to comment this out before pushing a commit */ /* NOTE: Make sure to comment this out before pushing a commit */
/* String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); */ /* String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); */
/* String rawArgs = String_FromConst("UnknownShadow200"); */ String rawArgs = String_FromConst("UnknownShadow200");
/* argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); */ argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4);
if (argsCount == 0) { if (argsCount == 0) {
Launcher_Run(); Launcher_Run();

View File

@ -53,7 +53,11 @@ void World_SetNewMap(BlockRaw* blocks, int width, int height, int length) {
if (!World.Volume) World.Blocks = NULL; if (!World.Volume) World.Blocks = NULL;
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS
/* .cw maps may have set this to a non-NULL when importing */
if (!World.Blocks2) {
World.Blocks2 = World.Blocks; World.Blocks2 = World.Blocks;
Block_SetUsedCount(256);
}
#endif #endif
if (Env_EdgeHeight == -1) { if (Env_EdgeHeight == -1) {
@ -74,6 +78,13 @@ CC_NOINLINE void World_SetDimensions(int width, int height, int length) {
World.MaxZ = length - 1; World.MaxZ = length - 1;
} }
#ifdef EXTENDED_BLOCKS
void World_SetMapUpper(BlockRaw* blocks) {
World.Blocks2 = blocks;
Block_SetUsedCount(768);
}
#endif
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS
void World_SetBlock(int x, int y, int z, BlockID block) { void World_SetBlock(int x, int y, int z, BlockID block) {

View File

@ -47,6 +47,8 @@ CC_NOINLINE void World_SetDimensions(int width, int height, int length);
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS
extern int Block_IDMask; extern int Block_IDMask;
/* Sets World.Blocks2 and updates internal state for more than 256 blocks. */
void World_SetMapUpper(BlockRaw* blocks);
/* Gets the block at the given coordinates. */ /* Gets the block at the given coordinates. */
/* NOTE: Does NOT check that the coordinates are inside the map. */ /* NOTE: Does NOT check that the coordinates are inside the map. */