From 73b6d9f489b83db2382b5134c71dba5f388a9c2e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 17 May 2017 22:44:03 +1000 Subject: [PATCH] Start porting stream I/O to C --- ClassicalSharp/Map/Formats/MapCw.Exporter.cs | 2 +- ClassicalSharp/Map/Formats/NbtFile.cs | 2 - src/Client/Client.vcxproj | 2 + src/Client/Client.vcxproj.filters | 12 +++ src/Client/Stream.c | 104 +++++++++++++++++++ src/Client/Stream.h | 102 ++++++++++++++++++ src/Client/Typedefs.h | 2 +- src/Client/World.c | 1 + src/Client/World.h | 11 +- 9 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 src/Client/Stream.c create mode 100644 src/Client/Stream.h diff --git a/ClassicalSharp/Map/Formats/MapCw.Exporter.cs b/ClassicalSharp/Map/Formats/MapCw.Exporter.cs index 98ecf6f9c..110d22fcc 100644 --- a/ClassicalSharp/Map/Formats/MapCw.Exporter.cs +++ b/ClassicalSharp/Map/Formats/MapCw.Exporter.cs @@ -24,7 +24,7 @@ namespace ClassicalSharp.Map { nbt.Write(NbtTagType.Compound); nbt.Write("ClassicWorld"); nbt.Write(NbtTagType.Int8); - nbt.Write("FormatVersion"); nbt.WriteInt8(1); + nbt.Write("FormatVersion"); nbt.WriteUInt8(1); nbt.Write(NbtTagType.Int8Array); nbt.Write("UUID"); nbt.WriteInt32(16); diff --git a/ClassicalSharp/Map/Formats/NbtFile.cs b/ClassicalSharp/Map/Formats/NbtFile.cs index 30ad6dbe1..64a1f9394 100644 --- a/ClassicalSharp/Map/Formats/NbtFile.cs +++ b/ClassicalSharp/Map/Formats/NbtFile.cs @@ -47,8 +47,6 @@ namespace ClassicalSharp.Map { public void WriteInt16(short v) { writer.Write(IPAddress.HostToNetworkOrder(v)); } - public void WriteInt8(sbyte v) { writer.Write((byte)v); } - public void WriteUInt8(int v) { writer.Write((byte)v); } public void WriteUInt8(byte v) { writer.Write(v); } diff --git a/src/Client/Client.vcxproj b/src/Client/Client.vcxproj index 91486961d..a85e68db3 100644 --- a/src/Client/Client.vcxproj +++ b/src/Client/Client.vcxproj @@ -179,6 +179,7 @@ + @@ -222,6 +223,7 @@ + diff --git a/src/Client/Client.vcxproj.filters b/src/Client/Client.vcxproj.filters index 3e8ce1bde..eadea9629 100644 --- a/src/Client/Client.vcxproj.filters +++ b/src/Client/Client.vcxproj.filters @@ -94,6 +94,12 @@ {2134e4ed-c57e-40b2-b329-5f5b7b71a799} + + {759424b7-9977-45d7-9946-b6cc9875231b} + + + {82a3fbdf-5459-4e08-bff9-04dd23aa4342} + @@ -201,6 +207,9 @@ Header Files\Rendering + + Header Files\IO + @@ -287,5 +296,8 @@ Source Files\Rendering + + Source Files\IO + \ No newline at end of file diff --git a/src/Client/Stream.c b/src/Client/Stream.c new file mode 100644 index 000000000..bacd65682 --- /dev/null +++ b/src/Client/Stream.c @@ -0,0 +1,104 @@ +#include "Stream.h" + +/*void Stream_Read(Stream* stream, UInt8* buffer, UInt32 count) { + UInt32 read; + ReturnCode result = 0; + + while (count > 0) { + ReturnCode result = stream->Read(buffer, count, &read); + if (read == 0 || !ErrorHandler_Check(result)) { + error here or something + } + count -= read; + } +} + +void Stream_Write(Stream* stream, UInt8* buffer, UInt32 count) { + UInt32 totalWritten = 0; + while (count > 0) { + + } +}*/ + +// TODO: This one is called frequently, probably needs inline. +UInt8 Stream_ReadUInt8(Stream* stream) { + UInt8 result; + Stream_Read(stream, &result, sizeof(UInt8)); + return result; +} + +UInt16 Stream_ReadUInt16_LE(Stream* stream) { + UInt8 buffer[sizeof(UInt16)]; + Stream_Read(stream, buffer, sizeof(UInt16)); + return (UInt16)(buffer[0] | (buffer[1] << 8)); +} + +UInt16 Stream_ReadUInt16_BE(Stream* stream) { + UInt8 buffer[sizeof(UInt16)]; + Stream_Read(stream, buffer, sizeof(UInt16)); + return (UInt16)((buffer[0] << 8) | buffer[1]); +} + +UInt32 Stream_ReadUInt32_LE(Stream* stream) { + UInt8 buffer[sizeof(UInt32)]; + Stream_Read(stream, buffer, sizeof(UInt32)); + return (UInt32)( + (UInt32)buffer[0] | ((UInt32)buffer[1] << 8) | + ((UInt32)buffer[2] << 16) | ((UInt32)buffer[3] << 24)); +} + +UInt32 Stream_ReadUInt32_BE(Stream* stream) { + UInt8 buffer[sizeof(UInt32)]; + Stream_Read(stream, buffer, sizeof(UInt32)); + return (UInt32)( + ((UInt32)buffer[0] << 24) | ((UInt32)buffer[1] << 16) | + ((UInt32)buffer[2] << 8) | (UInt32)buffer[3]); +} + +UInt64 Stream_ReadUInt64_BE(Stream* stream) { + UInt8 buffer[sizeof(UInt64)]; + Stream_Read(stream, buffer, sizeof(UInt64)); + UInt32 hi = (UInt32)( + ((UInt32)buffer[0] << 24) | ((UInt32)buffer[1] << 16) | + ((UInt32)buffer[2] << 8) | (UInt32)buffer[3]); + UInt32 lo = (UInt32)( + ((UInt32)buffer[4] << 24) | ((UInt32)buffer[5] << 16) | + ((UInt32)buffer[6] << 8) | (UInt32)buffer[7]); + return (UInt64)(((UInt64)hi) << 32) | ((UInt64)lo); +} + + +void Stream_WriteUInt16_LE(Stream* stream, UInt16 value) { + UInt8 buffer[sizeof(UInt16)]; + buffer[0] = (UInt8)(value ); buffer[1] = (UInt8)(value >> 8 ); + Stream_Write(stream, buffer, sizeof(UInt16)); +} + +void Stream_WriteUInt16_BE(Stream* stream, UInt16 value) { + UInt8 buffer[sizeof(UInt16)]; + buffer[0] = (UInt8)(value >> 8 ); buffer[1] = (UInt8)(value ); + Stream_Write(stream, buffer, sizeof(UInt16)); +} + +void Stream_WriteUInt32_LE(Stream* stream, UInt32 value) { + UInt8 buffer[sizeof(UInt32)]; + buffer[0] = (UInt8)(value ); buffer[1] = (UInt8)(value >> 8 ); + buffer[2] = (UInt8)(value >> 16); buffer[3] = (UInt8)(value >> 24); + Stream_Write(stream, buffer, sizeof(UInt32)); +} + +void Stream_WriteUInt32_BE(Stream* stream, UInt32 value) { + UInt8 buffer[sizeof(UInt32)]; + buffer[0] = (UInt8)(value >> 24); buffer[1] = (UInt8)(value >> 16); + buffer[2] = (UInt8)(value >> 8 ); buffer[3] = (UInt8)(value); + Stream_Write(stream, buffer, sizeof(UInt32)); +} + +void Stream_WriteUInt64_BE(Stream* stream, UInt64 value) { + UInt8 buffer[sizeof(UInt64)]; + buffer[0] = (UInt8)(value >> 56); buffer[1] = (UInt8)(value >> 48); + buffer[2] = (UInt8)(value >> 40); buffer[3] = (UInt8)(value >> 32); + buffer[4] = (UInt8)(value >> 24); buffer[5] = (UInt8)(value >> 16); + buffer[6] = (UInt8)(value >> 8 ); buffer[7] = (UInt8)(value ); + Stream_Write(stream, buffer, sizeof(UInt64)); +} \ No newline at end of file diff --git a/src/Client/Stream.h b/src/Client/Stream.h new file mode 100644 index 000000000..daa77b4e8 --- /dev/null +++ b/src/Client/Stream.h @@ -0,0 +1,102 @@ +#ifndef CS_STREAM_H +#define CS_STREAM_H +#include "Typedefs.h" +#include "String.h" +#include "ErrorHandler.h" + +typedef ReturnCode (*Stream_Operation)(UInt8* data, UInt32 count, UInt32* modified); + +typedef ReturnCode (*Stream_Seek)(Int32 offset); + +typedef struct Stream { + + /* The name of the stream. */ + String Name; + + /* Performs a read operation on the stream. + Result is a ReturnCode, number of read bytes is output via pointer. */ + Stream_Operation Read; + + /* Performs a write operation on the stream. + Result is a ReturnCode, number of written bytes is output via pointer. */ + Stream_Operation Write; + + /* Moves backwards or forwards by given number of bytes in the stream. + Result is a ReturnCode. */ + Stream_Operation Seek; +} Stream; + + + +/* === block stream i/o operations */ + +/* Fully reads up to count bytes or fails. */ +void Stream_Read(Stream* stream, UInt8* buffer, UInt32 count); + +/* Fully writes up to count bytes or fails. */ +void Stream_Write(Stream* stream, UInt8* buffer, UInt32 count); + + + +/* === integer read operations === */ + +/* Reads an unsigned 8 bit integer from the given stream. */ +UInt8 Stream_ReadUInt8(Stream* stream); + +/* Reads a little endian unsigned 16 bit integer from the given stream. */ +UInt16 Stream_ReadUInt16_LE(Stream* stream); +/* Reads a little endian signed 16 bit integer from the given stream. */ +#define Stream_ReadInt16_LE(stream) (Int32)Stream_ReadUInt16_LE(stream) + +/* Reads a big endian unsigned 16 bit integer from the given stream. */ +UInt16 Stream_ReadUInt16_BE(Stream* stream); +/* Reads a big endian signed 16 bit integer from the given stream. */ +#define Stream_ReadInt16_BE(stream) (Int32)Stream_ReadUInt16_BE(stream) + +/* Reads a little endian unsigned 32 bit integer from the given stream. */ +UInt32 Stream_ReadUInt32_LE(Stream* stream); +/* Reads a little endian signed 32 bit integer from the given stream. */ +#define Stream_ReadInt32_LE(stream) (Int32)Stream_ReadUInt32_LE(stream) + +/* Reads a big endian unsigned 64 bit integer from the given stream. */ +UInt32 Stream_ReadUInt32_BE(Stream* stream); +/* Reads a big endian signed 64 bit integer from the given stream. */ +#define Stream_ReadInt32_BE(stream) (Int32)Stream_ReadUInt32_BE(stream) + +/* Reads a big endian unsigned 64 bit integer from the given stream. */ +UInt64 Stream_ReadUInt64_BE(Stream* stream); +/* Reads a big endian signed 64 bit integer from the given stream. */ +#define Stream_ReadInt64_BE(stream) (Int64)Stream_ReadUInt64_BE(stream) + + + +/* === integer write operations === */ + +/* Writes an unsigned 8 bit integer from the given stream. */ +#define Stream_WriteUInt8(stream, value) Stream_Write(stream, &value, sizeof(UInt8)); + +/* Writes a little endian unsigned 16 bit integer from the given stream. */ +void Stream_WriteUInt16_LE(Stream* stream, UInt16 value); +/* Writes a little endian signed 16 bit integer from the given stream. */ +#define Stream_WriteInt16_LE(stream, value) Stream_WriteUInt16_LE(stream, (UInt16)value) + +/* Writes a big endian unsigned 16 bit integer from the given stream. */ +void Stream_WriteUInt16_BE(Stream* stream, UInt16 value); +/* Writes a big endian signed 16 bit integer from the given stream. */ +#define Stream_WriteInt16_BE(stream, value) Stream_WriteUInt16_BE(stream, (UInt16)value) + +/* Writes a little endian unsigned 32 bit integer from the given stream. */ +void Stream_WriteUInt32_LE(Stream* stream, UInt32 value); +/* Writes a little endian signed 32 bit integer from the given stream. */ +#define Stream_WriteInt32_LE(stream, value) Stream_WriteUInt32_LE(stream, (UInt32)value) + +/* Writes a big endian unsigned 64 bit integer from the given stream. */ +void Stream_WriteUInt32_BE(Stream* stream, UInt32 value); +/* Writes a big endian signed 64 bit integer from the given stream. */ +#define Stream_WriteInt32_BE(stream, value) Stream_WriteUInt32_BE(stream, (UInt32)value) + +/* Writes a big endian unsigned 64 bit integer from the given stream. */ +void Stream_WriteUInt64_BE(Stream* stream, UInt64 value); +/* Writes a big endian signed 64 bit integer from the given stream. */ +#define Stream_WriteInt64_BE(stream, value) Stream_WriteUInt64_BE(stream, (UInt64)value) +#endif \ No newline at end of file diff --git a/src/Client/Typedefs.h b/src/Client/Typedefs.h index 6dd07593c..8b15a3bde 100644 --- a/src/Client/Typedefs.h +++ b/src/Client/Typedefs.h @@ -26,7 +26,7 @@ typedef int16_t Int16; typedef int32_t Int32; typedef int64_t Int64; #else -#error "I didn't add typedefs for this compiler. You'll need to define them in Typedefs.h!'" +#error "I didn't add typedefs for this compiler. You'll need to define them in Typedefs.h!" #endif typedef float Real32; diff --git a/src/Client/World.c b/src/Client/World.c index d44d0e6ab..3ecc5b6e6 100644 --- a/src/Client/World.c +++ b/src/Client/World.c @@ -19,6 +19,7 @@ void World_SetNewMap(BlockID* blocks, Int32 blocksSize, Int32 width, Int32 heigh if (blocksSize != (width * height * length)) { ErrorHandler_Fail("Blocks array size does not match volume of map"); } + World_OneY = width * length; if (WorldEnv_EdgeHeight == -1) { WorldEnv_EdgeHeight = height / 2; diff --git a/src/Client/World.h b/src/Client/World.h index 1f8872a59..6da0425e5 100644 --- a/src/Client/World.h +++ b/src/Client/World.h @@ -22,16 +22,19 @@ y = (index / World_Width) / World_Length; BlockID* World_Blocks = NULL; /* Size of blocks array. */ -Int32 World_BlocksSize = 0; +Int32 World_BlocksSize; /* Length of world on X axis.*/ -Int32 World_Width = 0; +Int32 World_Width; /* Length of world on Y axis (vertical).*/ -Int32 World_Height = 0; +Int32 World_Height; /* Length of world on Z axis.*/ -Int32 World_Length = 0; +Int32 World_Length; + +/* Amount a packed index must be changed by to advance Y coordinate. */ +Int32 World_OneY; /* Unique uuid/guid of this particular world. */ UInt8 World_Uuid[16];