Cleanup String file, integrate DisplayDevice into Platform

This commit is contained in:
UnknownShadow200 2018-10-15 00:35:35 +11:00
parent 3d1424774f
commit a146eb531c
21 changed files with 226 additions and 293 deletions

View File

@ -5,7 +5,6 @@
#include "Block.h"
#include "ExtMath.h"
#include "Funcs.h"
#include "Block.h"
#include "Game.h"
#include "GameStructs.h"
#include "Errors.h"

View File

@ -12,7 +12,7 @@
typedef enum SoundType_ {
SOUND_NONE, SOUND_WOOD, SOUND_GRAVEL, SOUND_GRASS,
SOUND_STONE, SOUND_METAL, SOUND_GLASS, SOUND_CLOTH,
SOUND_SAND, SOUND_SNOW, SOUND_COUNT,
SOUND_SAND, SOUND_SNOW, SOUND_COUNT
} SoundType;
extern const char* Sound_Names[SOUND_COUNT];
@ -23,7 +23,7 @@ typedef enum DrawType_ {
DRAW_TRANSPARENT_THICK, /* Same as Transparent, but all neighbour faces show. (e.g. leaves) */
DRAW_TRANSLUCENT, /* Blocks behind show (e.g. water). Pixels blend with other blocks behind. */
DRAW_GAS, /* Does not show (e.g. air). Can still be collided with. */
DRAW_SPRITE, /* Block renders as an X (e.g. sapling). Pixels either fully visible or invisible. */
DRAW_SPRITE /* Block renders as an X (e.g. sapling). Pixels either fully visible or invisible. */
} DrawType;
/* Describes the interaction a block has with a player when they collide with it. */
@ -35,7 +35,7 @@ typedef enum CollideType_ {
COLLIDE_SLIPPERY_ICE, /* Block is solid and fully slidable on. */
COLLIDE_LIQUID_WATER, /* Water style 'swimming'/'bobbing' interaction when player collides. */
COLLIDE_LIQUID_LAVA, /* Lava style 'swimming'/'bobbing' interaction when player collides. */
COLLIDE_CLIMB_ROPE, /* Rope/Ladder style climbing interaction when player collides. */
COLLIDE_CLIMB_ROPE /* Rope/Ladder style climbing interaction when player collides. */
} CollideType;
bool Block_IsLiquid[BLOCK_COUNT];

View File

@ -198,7 +198,6 @@
<ClInclude Include="ChunkUpdater.h" />
<ClInclude Include="Constants.h" />
<ClInclude Include="Bitmap.h" />
<ClInclude Include="DisplayDevice.h" />
<ClInclude Include="Drawer.h" />
<ClInclude Include="Drawer2D.h" />
<ClInclude Include="Entity.h" />
@ -263,7 +262,6 @@
<ClCompile Include="Chat.c" />
<ClCompile Include="ChunkUpdater.c" />
<ClCompile Include="Bitmap.c" />
<ClCompile Include="DisplayDevice.c" />
<ClCompile Include="Drawer.c" />
<ClCompile Include="Drawer2D.c" />
<ClCompile Include="EntityComponents.c" />

View File

@ -270,9 +270,6 @@
<ClInclude Include="PacketHandlers.h">
<Filter>Header Files\Network</Filter>
</ClInclude>
<ClInclude Include="DisplayDevice.h">
<Filter>Header Files\Platform</Filter>
</ClInclude>
<ClInclude Include="Window.h">
<Filter>Header Files\Platform</Filter>
</ClInclude>
@ -455,9 +452,6 @@
<ClCompile Include="AsyncDownloader.c">
<Filter>Source Files\Network</Filter>
</ClCompile>
<ClCompile Include="DisplayDevice.c">
<Filter>Source Files\Platform</Filter>
</ClCompile>
<ClCompile Include="EnvRenderer.c">
<Filter>Source Files\Rendering</Filter>
</ClCompile>

View File

@ -1,62 +0,0 @@
#include "DisplayDevice.h"
struct ColorFormat ColorFormat_FromBPP(int bpp) {
struct ColorFormat format = { 0 };
format.BitsPerPixel = bpp;
uint8_t rba;
switch (bpp) {
case 32:
format.R = 8; format.G = 8; format.B = 8; format.A = 8;
break;
case 24:
format.R = 8; format.G = 8; format.B = 8;
break;
case 16:
format.R = 5; format.G = 6; format.B = 5;
break;
case 15:
format.R = 5; format.G = 5; format.B = 5;
break;
case 8:
format.R = 3; format.G = 3; format.B = 2;
format.IsIndexed = true;
break;
case 4:
format.R = 2; format.G = 2; format.B = 1;
format.IsIndexed = true;
break;
case 1:
format.IsIndexed = true;
break;
default:
rba = (uint8_t)(bpp / 4);
format.R = rba; format.B = rba; format.A = rba;
format.G = (uint8_t)((bpp / 4) + (bpp % 4));
break;
}
return format;
}
struct ColorFormat ColorFormat_FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
struct ColorFormat format;
format.R = r; format.G = g; format.B = b; format.A = a;
format.BitsPerPixel = r + g + b + a;
format.IsIndexed = format.BitsPerPixel < 15 && format.BitsPerPixel != 0;
return format;
}
struct GraphicsMode GraphicsMode_Make(struct ColorFormat color, uint8_t depth, uint8_t stencil, uint8_t buffers) {
struct GraphicsMode mode;
mode.Format = color;
mode.DepthBits = depth;
mode.StencilBits = stencil;
mode.Buffers = buffers;
return mode;
}
struct GraphicsMode GraphicsMode_MakeDefault(void) {
int bpp = DisplayDevice_Default.BitsPerPixel;
struct ColorFormat format = ColorFormat_FromBPP(bpp);
return GraphicsMode_Make(format, 24, 0, 2);
}

View File

@ -1,37 +0,0 @@
#ifndef CC_DISPLAYDEVICE_H
#define CC_DISPLAYDEVICE_H
#include "Core.h"
/* Contains structs related to monitor displays.
Copyright 2017 ClassicalSharp | Licensed under BSD-3 | Based originally on OpenTK
*/
/* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK team.
* This notice may not be removed.
* See license.txt for licensing detailed licensing details.
*/
struct DisplayDevice { int BitsPerPixel; Rect2D Bounds; };
struct DisplayDevice DisplayDevice_Default;
void* DisplayDevice_Meta[3];
struct ColorFormat {
uint8_t R, G, B, A;
bool IsIndexed;
int BitsPerPixel;
};
struct ColorFormat ColorFormat_FromBPP(int bpp);
struct ColorFormat ColorFormat_FromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
struct GraphicsMode {
struct ColorFormat Format;
uint8_t DepthBits, StencilBits;
/* The number of buffers associated with this DisplayMode. */
uint8_t Buffers;
};
struct GraphicsMode GraphicsMode_Make(struct ColorFormat color, uint8_t depth, uint8_t stencil, uint8_t buffers);
/* Returns an GraphicsMode compatible with the underlying platform. */
struct GraphicsMode GraphicsMode_MakeDefault(void);
#endif

View File

@ -8,13 +8,13 @@
#include "Bitmap.h"
#include "Game.h"
void DrawTextArgs_Make(struct DrawTextArgs* args, STRING_REF const String* text, STRING_REF const FontDesc* font, bool useShadow) {
void DrawTextArgs_Make(struct DrawTextArgs* args, STRING_REF const String* text, const FontDesc* font, bool useShadow) {
args->Text = *text;
args->Font = *font;
args->UseShadow = useShadow;
}
void DrawTextArgs_MakeEmpty(struct DrawTextArgs* args, STRING_REF const FontDesc* font, bool useShadow) {
void DrawTextArgs_MakeEmpty(struct DrawTextArgs* args, const FontDesc* font, bool useShadow) {
args->Text = String_Empty;
args->Font = *font;
args->UseShadow = useShadow;
@ -31,39 +31,40 @@ void Drawer2D_MakeFont(FontDesc* desc, int size, int style) {
}
Bitmap Drawer2D_FontBitmap;
int Drawer2D_BoxSize = 8; /* avoid divide by 0 if default.png missing */
int Drawer2D_TileSize = 8; /* avoid divide by 0 if default.png missing */
/* So really 16 characters per row */
#define DRAWER2D_LOG2_CHARS_PER_ROW 4
int Drawer2D_Widths[256];
static void Drawer2D_CalculateTextWidths(void) {
int width = Drawer2D_FontBitmap.Width, height = Drawer2D_FontBitmap.Height;
int i;
int i, x, y, xx, tileX, tileY;
for (i = 0; i < Array_Elems(Drawer2D_Widths); i++) {
Drawer2D_Widths[i] = 0;
}
int x, y, xx;
for (y = 0; y < height; y++) {
int charY = (y / Drawer2D_BoxSize);
tileY = y / Drawer2D_TileSize;
uint32_t* row = Bitmap_GetRow(&Drawer2D_FontBitmap, y);
for (x = 0; x < width; x += Drawer2D_BoxSize) {
int charX = (x / Drawer2D_BoxSize);
for (x = 0; x < width; x += Drawer2D_TileSize) {
tileX = x / Drawer2D_TileSize;
i = tileX | (tileY << DRAWER2D_LOG2_CHARS_PER_ROW);
/* Iterate through each pixel of the given character, on the current scanline */
for (xx = Drawer2D_BoxSize - 1; xx >= 0; xx--) {
for (xx = Drawer2D_TileSize - 1; xx >= 0; xx--) {
uint32_t pixel = row[x + xx];
uint8_t a = PackedCol_ARGB_A(pixel);
if (a < 127) continue;
/* Check if this is the pixel furthest to the right, for the current character */
int index = charX | (charY << DRAWER2D_LOG2_CHARS_PER_ROW);
Drawer2D_Widths[index] = max(Drawer2D_Widths[index], xx + 1);
/* Check if this is the pixel furthest to the right, for the current character */
Drawer2D_Widths[i] = max(Drawer2D_Widths[i], xx + 1);
break;
}
}
}
Drawer2D_Widths[' '] = Drawer2D_BoxSize / 4;
Drawer2D_Widths[' '] = Drawer2D_TileSize / 4;
}
static void Drawer2D_FreeFontBitmap(void) {
@ -74,7 +75,7 @@ static void Drawer2D_FreeFontBitmap(void) {
void Drawer2D_SetFontBitmap(Bitmap* bmp) {
Drawer2D_FreeFontBitmap();
Drawer2D_FontBitmap = *bmp;
Drawer2D_BoxSize = bmp->Width >> DRAWER2D_LOG2_CHARS_PER_ROW;
Drawer2D_TileSize = bmp->Width >> DRAWER2D_LOG2_CHARS_PER_ROW;
Drawer2D_CalculateTextWidths();
}
@ -109,12 +110,13 @@ void Drawer2D_Free(void) { Drawer2D_FreeFontBitmap(); }
void Drawer2D_Rect(Bitmap* bmp, PackedCol col, int x, int y, int width, int height);
void Drawer2D_Clear(Bitmap* bmp, PackedCol col, int x, int y, int width, int height) {
int xx, yy;
uint32_t argb = PackedCol_ToARGB(col);
if (x < 0 || y < 0 || (x + width) > bmp->Width || (y + height) > bmp->Height) {
ErrorHandler_Fail("Drawer2D_Clear - tried to clear at invalid coords");
}
int xx, yy;
uint32_t argb = PackedCol_ToARGB(col);
for (yy = 0; yy < height; yy++) {
uint32_t* row = Bitmap_GetRow(bmp, y + yy) + x;
for (xx = 0; xx < width; xx++) { row[xx] = argb; }
@ -159,9 +161,9 @@ bool Drawer2D_ValidColCodeAt(const String* text, int i) {
bool Drawer2D_ValidColCode(char c) { return Drawer2D_GetCol(c).A > 0; }
bool Drawer2D_IsEmptyText(const String* text) {
if (!text->length) return true;
int i;
if (!text->length) return true;
for (i = 0; i < text->length; i++) {
if (text->buffer[i] != '&') return false;
if (!Drawer2D_ValidColCodeAt(text, i + 1)) return false;
@ -171,8 +173,9 @@ bool Drawer2D_IsEmptyText(const String* text) {
}
char Drawer2D_LastCol(const String* text, int start) {
if (start >= text->length) start = text->length - 1;
int i;
if (start >= text->length) start = text->length - 1;
for (i = start; i >= 0; i--) {
if (text->buffer[i] != '&') continue;
if (Drawer2D_ValidColCodeAt(text, i + 1)) {
@ -186,7 +189,7 @@ bool Drawer2D_IsWhiteCol(char c) { return c == '\0' || c == 'f' || c == 'F'; }
#define Drawer2D_ShadowOffset(point) (point / 8)
#define Drawer2D_XPadding(point) (Math_CeilDiv(point, 8))
static int Drawer2D_Width(int point, char c) {
return Math_CeilDiv(Drawer2D_Widths[(uint8_t)c] * point, Drawer2D_BoxSize);
return Math_CeilDiv(Drawer2D_Widths[(uint8_t)c] * point, Drawer2D_TileSize);
}
static int Drawer2D_AdjHeight(int point) { return Math_CeilDiv(point * 3, 2); }
@ -274,12 +277,12 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
int dstY = y + (yy + yPadding);
if (dstY >= bmp->Height) break;
int fontY = 0 + yy * Drawer2D_BoxSize / dstHeight;
int fontY = 0 + yy * Drawer2D_TileSize / dstHeight;
uint32_t* dstRow = Bitmap_GetRow(bmp, dstY);
for (i = 0; i < count; i++) {
int srcX = (coords[i] & 0x0F) * Drawer2D_BoxSize;
int srcY = (coords[i] >> 4) * Drawer2D_BoxSize;
int srcX = (coords[i] & 0x0F) * Drawer2D_TileSize;
int srcY = (coords[i] >> 4) * Drawer2D_TileSize;
uint32_t* fontRow = Bitmap_GetRow(&Drawer2D_FontBitmap, fontY + srcY);
int srcWidth = Drawer2D_Widths[coords[i]], dstWidth = dstWidths[i];

View File

@ -9,8 +9,8 @@
struct DrawTextArgs { String Text; FontDesc Font; bool UseShadow; };
struct Texture;
void DrawTextArgs_Make(struct DrawTextArgs* args, STRING_REF const String* text, STRING_REF const FontDesc* font, bool useShadow);
void DrawTextArgs_MakeEmpty(struct DrawTextArgs* args, STRING_REF const FontDesc* font, bool useShadow);
void DrawTextArgs_Make(struct DrawTextArgs* args, STRING_REF const String* text, const FontDesc* font, bool useShadow);
void DrawTextArgs_MakeEmpty(struct DrawTextArgs* args, const FontDesc* font, bool useShadow);
NOINLINE_ void Drawer2D_MakeFont(FontDesc* desc, int size, int style);
/* Whether chat text should be drawn and measuring using the currently bitmapped font,

View File

@ -34,7 +34,6 @@
#include "GraphicsCommon.h"
#include "Menus.h"
#include "Audio.h"
#include "DisplayDevice.h"
#include "Stream.h"
#include "Bitmap.h"
@ -736,10 +735,12 @@ uint64_t game_renderTimer;
void Game_Run(int width, int height, const String* title, struct DisplayDevice* device) {
int x = device->Bounds.X + (device->Bounds.Width - width) / 2;
int y = device->Bounds.Y + (device->Bounds.Height - height) / 2;
struct GraphicsMode mode = GraphicsMode_MakeDefault();
struct GraphicsMode mode;
GraphicsMode_MakeDefault(&mode);
Window_Create(x, y, width, height, title, &mode, device);
Window_SetVisible(true);
Game_Load();
Event_RaiseVoid(&WindowEvents_Resized);

View File

@ -13,7 +13,7 @@ VertexP3fT2fC4b* iso_vertices;
VertexP3fT2fC4b* iso_base_vertices;
GfxResourceID iso_vb;
bool iso_cacheInitalisesd;
bool iso_cacheInitalised;
PackedCol iso_colNormal, iso_colXSide, iso_colZSide, iso_colYBottom;
#define iso_cosX (0.86602540378443864f) /* cos(30 * MATH_DEG2RAD) */
#define iso_sinX (0.50000000000000000f) /* sin(30 * MATH_DEG2RAD) */
@ -25,20 +25,20 @@ Vector3 iso_pos;
int iso_lastTexIndex, iso_texIndex;
static void IsometricDrawer_RotateX(float cosA, float sinA) {
float y = cosA * iso_pos.Y + sinA * iso_pos.Z;
float y = cosA * iso_pos.Y + sinA * iso_pos.Z;
iso_pos.Z = -sinA * iso_pos.Y + cosA * iso_pos.Z;
iso_pos.Y = y;
}
static void IsometricDrawer_RotateY(float cosA, float sinA) {
float x = cosA * iso_pos.X - sinA * iso_pos.Z;
float x = cosA * iso_pos.X - sinA * iso_pos.Z;
iso_pos.Z = sinA * iso_pos.X + cosA * iso_pos.Z;
iso_pos.X = x;
}
static void IsometricDrawer_InitCache(void) {
if (iso_cacheInitalisesd) return;
iso_cacheInitalisesd = true;
if (iso_cacheInitalised) return;
iso_cacheInitalised = true;
PackedCol white = PACKEDCOL_WHITE;
iso_colNormal = white;
PackedCol_GetShaded(iso_colNormal, &iso_colXSide, &iso_colZSide, &iso_colYBottom);

View File

@ -665,7 +665,7 @@ typedef int (*FN_GLXSWAPINTERVAL)(int interval);
FN_GLXSWAPINTERVAL glXSwapIntervalSGI;
bool ctx_supports_vSync;
void GLContext_Init(struct GraphicsMode mode) {
void GLContext_Init(struct GraphicsMode* mode) {
ctx_Handle = glXCreateContext(win_display, &win_visual, NULL, true);
if (!ctx_Handle) {
@ -712,36 +712,32 @@ void GLContext_SetVSync(bool enabled) {
if (result != 0) {Platform_Log1("Set VSync failed, error: %i", &result); }
}
static void GLContext_GetAttribs(struct GraphicsMode mode, int* attribs) {
static void GLContext_GetAttribs(struct GraphicsMode* mode, int* attribs) {
int i = 0;
struct ColorFormat color = mode.Format;
/* See http://www-01.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.opengl/doc/openglrf/glXChooseFBConfig.htm%23glxchoosefbconfig */
/* See http://www-01.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.opengl/doc/openglrf/glXChooseVisual.htm%23b5c84be452rree */
/* for the attribute declarations. Note that the attributes are different than those used in Glx.ChooseVisual */
if (!color.IsIndexed) {
attribs[i++] = GLX_RGBA;
}
attribs[i++] = GLX_RED_SIZE; attribs[i++] = color.R;
attribs[i++] = GLX_GREEN_SIZE; attribs[i++] = color.G;
attribs[i++] = GLX_BLUE_SIZE; attribs[i++] = color.B;
attribs[i++] = GLX_ALPHA_SIZE; attribs[i++] = color.A;
if (!mode->IsIndexed) { attribs[i++] = GLX_RGBA; }
attribs[i++] = GLX_RED_SIZE; attribs[i++] = mode->R;
attribs[i++] = GLX_GREEN_SIZE; attribs[i++] = mode->G;
attribs[i++] = GLX_BLUE_SIZE; attribs[i++] = mode->B;
attribs[i++] = GLX_ALPHA_SIZE; attribs[i++] = mode->A;
if (mode.DepthBits) {
attribs[i++] = GLX_DEPTH_SIZE; attribs[i++] = mode.DepthBits;
if (mode->DepthBits) {
attribs[i++] = GLX_DEPTH_SIZE; attribs[i++] = mode->DepthBits;
}
if (mode.StencilBits) {
attribs[i++] = GLX_STENCIL_SIZE; attribs[i++] = mode.StencilBits;
}
if (mode.Buffers > 1) {
attribs[i++] = GLX_DOUBLEBUFFER;
if (mode->StencilBits) {
attribs[i++] = GLX_STENCIL_SIZE; attribs[i++] = mode->StencilBits;
}
if (mode->Buffers > 1) { attribs[i++] = GLX_DOUBLEBUFFER; }
attribs[i++] = 0;
}
static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode) {
int attribs[20];
GLContext_GetAttribs(*mode, attribs);
GLContext_GetAttribs(mode, attribs);
int major = 0, minor = 0, fbcount;
if (!glXQueryVersion(win_display, &major, &minor)) {
ErrorHandler_Fail("glXQueryVersion failed");

View File

@ -5,7 +5,6 @@
#include "Entity.h"
#include "World.h"
#include "Funcs.h"
#include "BlockID.h"
#include "Block.h"
#include "ErrorHandler.h"

View File

@ -1,7 +1,6 @@
#include "Platform.h"
#include "ErrorHandler.h"
#include "Stream.h"
#include "DisplayDevice.h"
#include "ExtMath.h"
#include "ErrorHandler.h"
#include "Drawer2D.h"
@ -84,6 +83,41 @@ ReturnCode ReturnCode_SocketWouldBlock = EWOULDBLOCK;
#endif
/*########################################################################################################################*
*------------------------------------------------------GraphicsMode-------------------------------------------------------*
*#########################################################################################################################*/
void GraphicsMode_Make(struct GraphicsMode* m, int bpp, int depth, int stencil, int buffers) {
m->DepthBits = depth;
m->StencilBits = stencil;
m->Buffers = buffers;
m->IsIndexed = bpp < 15;
m->BitsPerPixel = bpp;
m->A = 0;
switch (bpp) {
case 32:
m->R = 8; m->G = 8; m->B = 8; m->A = 8; break;
case 24:
m->R = 8; m->G = 8; m->B = 8; break;
case 16:
m->R = 5; m->G = 6; m->B = 5; break;
case 15:
m->R = 5; m->G = 5; m->B = 5; break;
case 8:
m->R = 3; m->G = 3; m->B = 2; break;
case 4:
m->R = 2; m->G = 2; m->B = 1; break;
default:
/* mode->R = 0; mode->G = 0; mode->B = 0; */
ErrorHandler_Fail2(bpp, "Unsupported bits per pixel"); break;
}
}
void GraphicsMode_MakeDefault(struct GraphicsMode* m) {
int bpp = DisplayDevice_Default.BitsPerPixel;
GraphicsMode_Make(m, bpp, 24, 0, 2);
}
/*########################################################################################################################*
*---------------------------------------------------------Memory----------------------------------------------------------*
*#########################################################################################################################*/

View File

@ -31,6 +31,21 @@ extern ReturnCode ReturnCode_SocketInProgess;
extern ReturnCode ReturnCode_SocketWouldBlock;
extern ReturnCode ReturnCode_InvalidArg;
/* Data for a display device. (usually a monitor) */
struct DisplayDevice { int BitsPerPixel; Rect2D Bounds; };
struct DisplayDevice DisplayDevice_Default;
void* DisplayDevice_Meta[3];
struct GraphicsMode {
int R,G,B,A, BitsPerPixel, IsIndexed; /* Colour buffer data */
int DepthBits, StencilBits; /* Z buffer data */
int Buffers; /* Number of buffers (usually 2 for double buffer) */
};
/* Creates a new GraphicsMode from the given data. */
void GraphicsMode_Make(struct GraphicsMode* m, int bpp, int depth, int stencil, int buffers);
/* Creates a GraphicsMode compatible with the default display device. */
void GraphicsMode_MakeDefault(struct GraphicsMode* m);
/* Encodes a string in platform specific format. (e.g. unicode on windows, UTF8 on linux) */
/* NOTE: Only useful for platform specific function calls - do NOT try to interpret the data. */
void Platform_ConvertString(void* dstPtr, const String* src);

View File

@ -283,10 +283,8 @@ static void MPConnection_FailConnect(ReturnCode result) {
}
static void MPConnection_TickConnect(void) {
ReturnCode err = 0; Socket_GetError(net_socket, &err);
if (err) {
MPConnection_FailConnect(err); return;
}
ReturnCode res = 0; Socket_GetError(net_socket, &res);
if (res) { MPConnection_FailConnect(res); return; }
TimeMS now = DateTime_CurrentUTC_MS();
bool poll_write = false;
@ -483,19 +481,21 @@ void ServerConnection_InitMultiplayer(void) {
static void MPConnection_OnNewMap(void) {
if (ServerConnection_IsSinglePlayer) return;
/* wipe all existing entity states */
int i;
if (ServerConnection_IsSinglePlayer) return;
/* wipe all existing entities */
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
Handlers_RemoveEntity((EntityID)i);
}
}
static void MPConnection_Reset(void) {
if (ServerConnection_IsSinglePlayer) return;
int i;
if (ServerConnection_IsSinglePlayer) return;
for (i = 0; i < OPCODE_COUNT; i++) {
Net_Handlers[i] = NULL;
Net_Handlers[i] = NULL;
Net_PacketSizes[i] = 0;
}

View File

@ -33,7 +33,7 @@ enum OPCODE_ {
OPCODE_SET_ENTITY_PROPERTY, OPCODE_TWO_WAY_PING,
OPCODE_SET_INVENTORY_ORDER,
OPCODE_COUNT,
OPCODE_COUNT
};
struct PickedPos;

View File

@ -5,29 +5,31 @@
#include "Platform.h"
#include "Stream.h"
String String_Init(STRING_REF char* buffer, uint16_t length, uint16_t capacity) {
String str = { buffer, length, capacity }; return str;
String String_Init(STRING_REF char* buffer, int length, int capacity) {
String s;
s.buffer = buffer; s.length = length; s.capacity = capacity;
return s;
}
String String_InitAndClear(STRING_REF char* buffer, uint16_t capacity) {
String String_InitAndClear(STRING_REF char* buffer, int capacity) {
String str = String_Init(buffer, 0, capacity);
int i;
for (i = 0; i < capacity; i++) { buffer[i] = '\0'; }
return str;
}
uint16_t String_CalcLen(const char* raw, uint16_t capacity) {
uint16_t length = 0;
int String_CalcLen(const char* raw, int capacity) {
int length = 0;
while (length < capacity && *raw) { raw++; length++; }
return length;
}
String String_FromRaw(STRING_REF char* buffer, uint16_t capacity) {
String String_FromRaw(STRING_REF char* buffer, int capacity) {
return String_Init(buffer, String_CalcLen(buffer, capacity), capacity);
}
String String_FromReadonly(STRING_REF const char* buffer) {
uint16_t len = String_CalcLen(buffer, UInt16_MaxValue);
int len = String_CalcLen(buffer, UInt16_MaxValue);
return String_Init(buffer, len, len);
}
@ -165,13 +167,12 @@ bool String_AppendUInt32(String* str, uint32_t num) {
return true;
}
/* Attempts to append an integer value to the end of a string, padding left with 0. */
bool String_AppendPaddedInt(String* str, int num, int minDigits) {
char digits[STRING_INT_CHARS];
int i;
int i, count;
for (i = 0; i < minDigits; i++) { digits[i] = '0'; }
int count = String_MakeUInt32(num, digits);
count = String_MakeUInt32(num, digits);
if (count < minDigits) count = minDigits;
for (i = count - 1; i >= 0; i--) {
@ -199,22 +200,24 @@ bool String_AppendUInt64(String* str, uint64_t num) {
}
bool String_AppendFloat(String* str, float num, int fracDigits) {
int i, whole, digit;
double frac;
if (num < 0.0f) {
if (!String_Append(str, '-')) return false;
String_Append(str, '-'); /* don't need to check success */
num = -num;
}
int wholePortion = (int)num;
if (!String_AppendUInt32(str, wholePortion)) return false;
whole = (int)num;
if (!String_AppendUInt32(str, whole)) return false;
double frac = (double)num - (double)wholePortion;
frac = (double)num - (double)whole;
if (frac == 0.0) return true;
if (!String_Append(str, '.')) return false;
String_Append(str, '.'); /* don't need to check success */
int i;
for (i = 0; i < fracDigits; i++) {
frac *= 10;
int digit = Math_AbsI((int)frac) % 10;
digit = Math_AbsI((int)frac) % 10;
if (!String_Append(str, '0' + digit)) return false;
}
return true;
@ -427,13 +430,16 @@ void String_Format3(String* str, const char* format, const void* a1, const void*
}
void String_Format4(String* str, const char* format, const void* a1, const void* a2, const void* a3, const void* a4) {
String formatStr = String_FromReadonly(format);
const void* args[4] = { a1, a2, a3, a4 };
const void* arg;
int i, j = 0, digits;
const void* args[4];
args[0] = a1; args[1] = a2; args[2] = a3; args[3] = a4;
for (i = 0; i < formatStr.length; i++) {
if (formatStr.buffer[i] != '%') { String_Append(str, formatStr.buffer[i]); continue; }
arg = args[j++];
const void* arg = args[j++];
switch (formatStr.buffer[++i]) {
case 'b':
String_AppendInt(str, *((uint8_t*)arg)); break;
@ -479,22 +485,22 @@ Codepoint Convert_ControlChars[32] = {
};
Codepoint Convert_ExtendedChars[129] = { 0x2302,
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
Codepoint Convert_CP437ToUnicode(char c) {
@ -566,12 +572,14 @@ static int Convert_CompareDigits(const char* digits, const char* magnitude) {
}
static bool Convert_TryParseDigits(const String* str, bool* negative, char* digits, int maxDigits) {
char* start = digits;
int offset = 0, i;
*negative = false;
if (!str->length) return false;
char* start = digits; digits += (maxDigits - 1);
digits += (maxDigits - 1);
/* Handle number signs */
int offset = 0, i = 0;
if (str->buffer[0] == '-') { *negative = true; offset = 1; }
if (str->buffer[0] == '+') { offset = 1; }
@ -636,36 +644,31 @@ bool Convert_TryParseUInt64(const String* str, uint64_t* value) {
bool Convert_TryParseFloat(const String* str, float* value) {
int i = 0;
bool negate = false;
double sum, whole, fract, divide = 10.0;
*value = 0.0f;
bool foundDecimalPoint = false;
double whole = 0.0, fract = 0.0, divide = 10.0;
/* Handle number signs */
bool negate = false;
if (!str->length) return false;
if (str->buffer[0] == '-') { negate = true; i++; }
if (str->buffer[0] == '+') { i++; }
/* TODO: CHECK THIS WORKS!!! */
for (; i < str->length; i++) {
for (whole = 0.0; i < str->length; i++) {
char c = str->buffer[i];
/* Floating point number can have . in it */
if (c == '.' || c == ',') {
if (foundDecimalPoint) return false;
foundDecimalPoint = true;
continue;
}
if (c == '.' || c == ',') { i++; break; }
if (c < '0' || c > '9') return false;
int digit = c - '0';
if (!foundDecimalPoint) {
whole *= 10; whole += digit;
} else {
fract += digit / divide; divide *= 10;
}
whole *= 10; whole += (c - '0');
}
double sum = whole + fract;
for (fract = 0.0; i < str->length; i++) {
char c = str->buffer[i];
if (c < '0' || c > '9') return false;
fract += (c - '0') / divide; divide *= 10;
}
sum = whole + fract;
if (negate) sum = -sum;
*value = (float)sum;
return true;
@ -727,6 +730,7 @@ String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, int i) {
}
void StringsBuffer_Add(StringsBuffer* buffer, const String* text) {
int textOffset;
/* StringsBuffer hasn't been initalised yet, do it here */
if (!buffer->_FlagsBufferSize) { StringsBuffer_Init(buffer); }
@ -739,15 +743,13 @@ void StringsBuffer_Add(StringsBuffer* buffer, const String* text) {
ErrorHandler_Fail("String too big to insert into StringsBuffer");
}
int textOffset = buffer->TotalLength;
textOffset = buffer->TotalLength;
if (textOffset + text->length >= buffer->_TextBufferSize) {
buffer->TextBuffer = Utils_Resize(buffer->TextBuffer, &buffer->_TextBufferSize,
1, STRINGSBUFFER_BUFFER_DEF_SIZE, 8192);
}
if (text->length) {
Mem_Copy(&buffer->TextBuffer[textOffset], text->buffer, text->length);
}
Mem_Copy(&buffer->TextBuffer[textOffset], text->buffer, text->length);
buffer->FlagsBuffer[buffer->Count] = text->length | (textOffset << STRINGSBUFFER_LEN_SHIFT);
buffer->Count++;
@ -756,27 +758,27 @@ void StringsBuffer_Add(StringsBuffer* buffer, const String* text) {
void StringsBuffer_Remove(StringsBuffer* buffer, int index) {
uint32_t flags, offset, len;
uint32_t i, offsetAdj;
if (index < 0 || index >= buffer->Count) ErrorHandler_Fail("Tried to remove String past StringsBuffer end");
flags = buffer->FlagsBuffer[index];
offset = flags >> STRINGSBUFFER_LEN_SHIFT;
len = flags & STRINGSBUFFER_LEN_MASK;
/* Imagine buffer is this: AAXXYYZZ, and want to delete X */
/* Start points to first character of Y */
/* End points to character past last character of Z */
uint32_t i, start = offset + len, end = buffer->TotalLength;
for (i = start; i < end; i++) {
/* Imagine buffer is this: AAXXYYZZ, and want to delete XX */
/* We iterate from first char of Y to last char of Z, */
/* shifting each character two to the left. */
for (i = offset + len; i < buffer->TotalLength; i++) {
buffer->TextBuffer[i - len] = buffer->TextBuffer[i];
}
/* adjust text offset of elements after this element */
/* Adjust text offset of elements after this element */
/* Elements may not be in order so most account for that */
uint32_t flagsLen = len << STRINGSBUFFER_LEN_SHIFT;
offsetAdj = len << STRINGSBUFFER_LEN_SHIFT;
for (i = index; i < buffer->Count; i++) {
buffer->FlagsBuffer[i] = buffer->FlagsBuffer[i + 1];
if (buffer->FlagsBuffer[i] >= flags) {
buffer->FlagsBuffer[i] -= flagsLen;
buffer->FlagsBuffer[i] -= offsetAdj;
}
}
@ -845,33 +847,27 @@ void WordWrap_GetCoords(int index, const String* lines, int numLines, int* coord
}
int WordWrap_GetBackLength(const String* text, int index) {
int start = index;
if (index <= 0) return 0;
if (index >= text->length) ErrorHandler_Fail("WordWrap_GetBackLength - index past end of string");
/* Go backward to the end of the previous word */
while (index > 0 && text->buffer[index] == ' ') index--;
/* Go backward to the start of the current word */
while (index > 0 && text->buffer[index] != ' ') index--;
int start = index;
bool lookingSpace = text->buffer[index] == ' ';
/* go back to the end of the previous word */
if (lookingSpace) {
while (index > 0 && text->buffer[index] == ' ') { index--; }
}
/* go back to the start of the current word */
while (index > 0 && text->buffer[index] != ' ') { index--; }
return start - index;
}
int WordWrap_GetForwardLength(const String* text, int index) {
int start = index, length = text->length;
if (index == -1) return 0;
if (index >= text->length) ErrorHandler_Fail("WordWrap_GetForwardLength - index past end of string");
int start = index, length = text->length;
bool lookingLetter = text->buffer[index] != ' ';
/* go forward to the end of the current word */
if (lookingLetter) {
while (index < length && text->buffer[index] != ' ') { index++; }
}
/* Go forward to the end of the word 'index' is currently in */
while (index < length && text->buffer[index] != ' ') index++;
/* Go forward to the start of the next word after 'index' */
while (index < length && text->buffer[index] == ' ') index++;
/* go forward to the start of the next word */
while (index < length && text->buffer[index] == ' ') { index++; }
return index - start;
}

View File

@ -22,29 +22,29 @@ typedef struct String_ {
} String;
/* Counts number of characters until a '\0' is found. */
uint16_t String_CalcLen(const char* raw, uint16_t capacity);
int String_CalcLen(const char* raw, int capacity);
/* Constant string that points to NULL and has 0 length. */
/* NOTE: Do NOT modify the contents of this string! */
const String String_Empty;
/* Constructs a string from the given arguments. */
String String_Init(STRING_REF char* buffer, uint16_t length, uint16_t capacity);
String String_Init(STRING_REF char* buffer, int length, int capacity);
/* Constructs a string from the given arguments, then sets all characters to '\0'. */
String String_InitAndClear(STRING_REF char* buffer, uint16_t capacity);
String String_InitAndClear(STRING_REF char* buffer, int capacity);
/* Constructs a string from a (maybe null terminated) buffer. */
NOINLINE_ String String_FromRaw(STRING_REF char* buffer, uint16_t capacity);
NOINLINE_ String String_FromRaw(STRING_REF char* buffer, int capacity);
/* Constructs a string from a null-terminated constant readonly buffer. */
NOINLINE_ String String_FromReadonly(STRING_REF const char* buffer);
/* Constructs a string from a compile time array, then sets all characters to '\0'. */
#define String_ClearedArray(buffer) String_InitAndClear(buffer, (uint16_t)sizeof(buffer))
#define String_ClearedArray(buffer) String_InitAndClear(buffer, sizeof(buffer))
/* Constructs a string from a compile time string constant */
#define String_FromConst(text) { text, (uint16_t)(sizeof(text) - 1), (uint16_t)(sizeof(text) - 1)}
#define String_FromConst(text) { text, (sizeof(text) - 1), (sizeof(text) - 1)}
/* Constructs a string from a compile time array */
#define String_FromArray(buffer) { buffer, 0, (uint16_t)sizeof(buffer)}
#define String_FromArray(buffer) { buffer, 0, sizeof(buffer)}
/* Constructs a string from a compile time array, that may have arbitary actual length of data at runtime */
#define String_FromRawArray(buffer) String_FromRaw(buffer, (uint16_t)sizeof(buffer))
#define String_FromRawArray(buffer) String_FromRaw(buffer, sizeof(buffer))
/* Constructs a string from a compile time array (leaving 1 byte of room for null terminator) */
#define String_NT_Array(buffer) { buffer, 0, (uint16_t)(sizeof(buffer) - 1)}
#define String_NT_Array(buffer) { buffer, 0, (sizeof(buffer) - 1)}
/* Removes all colour codes from the given string. */
NOINLINE_ void String_StripCols(String* str);
@ -79,8 +79,11 @@ NOINLINE_ bool String_AppendBool(String* str, bool value);
NOINLINE_ bool String_AppendInt(String* str, int num);
/* Appends the digits of an unsigned 32 bit integer to the end of a string. */
NOINLINE_ bool String_AppendUInt32(String* str, uint32_t num);
/* Attempts to append an integer value to the end of a string, padding left with 0. */
NOINLINE_ bool String_AppendPaddedInt(String* str, int num, int minDigits);
/* Appends the digits of an unsigned 64 bit integer to the end of a string. */
NOINLINE_ bool String_AppendUInt64(String* str, uint64_t num);
/* Appends the digits of a float as a decimal. */
/* NOTE: If the number is an integer, no decimal point is added. */
/* Otherwise, fracDigits digits are added after a decimal point. */
@ -162,8 +165,8 @@ NOINLINE_ bool Convert_TryParseBool(const String* str, bool* value);
#define STRINGSBUFFER_BUFFER_DEF_SIZE 4096
#define STRINGSBUFFER_FLAGS_DEF_ELEMS 256
typedef struct StringsBuffer_ {
char* TextBuffer;
uint32_t* FlagsBuffer;
char* TextBuffer; /* Raw characters of all entries */
uint32_t* FlagsBuffer; /* Private flags for each entry */
int Count, TotalLength;
/* internal state */
int _TextBufferSize, _FlagsBufferSize;

View File

@ -632,31 +632,27 @@ void Window_SetCursorVisible(bool visible) {
#ifndef CC_BUILD_D3D9
void GLContext_SelectGraphicsMode(struct GraphicsMode mode) {
struct ColorFormat color = mode.Format;
void GLContext_SelectGraphicsMode(struct GraphicsMode* mode) {
PIXELFORMATDESCRIPTOR pfd = { 0 };
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
/* TODO: PFD_SUPPORT_COMPOSITION FLAG? CHECK IF IT WORKS ON XP */
pfd.cColorBits = (uint8_t)(color.R + color.G + color.B);
pfd.cColorBits = mode->R + mode->G + mode->B;
pfd.iPixelType = color.IsIndexed ? PFD_TYPE_COLORINDEX : PFD_TYPE_RGBA;
pfd.cRedBits = color.R;
pfd.cGreenBits = color.G;
pfd.cBlueBits = color.B;
pfd.cAlphaBits = color.A;
pfd.iPixelType = mode->IsIndexed ? PFD_TYPE_COLORINDEX : PFD_TYPE_RGBA;
pfd.cRedBits = mode->R;
pfd.cGreenBits = mode->G;
pfd.cBlueBits = mode->B;
pfd.cAlphaBits = mode->A;
pfd.cDepthBits = mode.DepthBits;
pfd.cStencilBits = mode.StencilBits;
if (mode.DepthBits <= 0) pfd.dwFlags |= PFD_DEPTH_DONTCARE;
if (mode.Buffers > 1) pfd.dwFlags |= PFD_DOUBLEBUFFER;
pfd.cDepthBits = mode->DepthBits;
pfd.cStencilBits = mode->StencilBits;
if (mode->DepthBits <= 0) pfd.dwFlags |= PFD_DEPTH_DONTCARE;
if (mode->Buffers > 1) pfd.dwFlags |= PFD_DOUBLEBUFFER;
int modeIndex = ChoosePixelFormat(win_DC, &pfd);
if (modeIndex == 0) {
ErrorHandler_Fail("Requested graphics mode not available");
}
if (modeIndex == 0) { ErrorHandler_Fail("Requested graphics mode not available"); }
Mem_Set(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
@ -674,7 +670,7 @@ typedef BOOL (WINAPI *FN_WGLSWAPINTERVAL)(int interval);
FN_WGLSWAPINTERVAL wglSwapIntervalEXT;
bool ctx_supports_vSync;
void GLContext_Init(struct GraphicsMode mode) {
void GLContext_Init(struct GraphicsMode* mode) {
GLContext_SelectGraphicsMode(mode);
ctx_Handle = wglCreateContext(win_DC);
if (!ctx_Handle) {

View File

@ -1,7 +1,6 @@
#ifndef CC_WINDOW_H
#define CC_WINDOW_H
#include "String.h"
#include "DisplayDevice.h"
/* Abstracts creating and managing a native window.
Copyright 2017 ClassicalSharp | Licensed under BSD-3 | Based on OpenTK code
*/
@ -31,10 +30,10 @@
OTHER DEALINGS IN THE SOFTWARE.
*/
enum WINDOW_STATE {
WINDOW_STATE_NORMAL, WINDOW_STATE_MINIMISED,
WINDOW_STATE_MAXIMISED, WINDOW_STATE_FULLSCREEN,
};
typedef enum WindowState_ {
WINDOW_STATE_NORMAL, WINDOW_STATE_MINIMISED, WINDOW_STATE_MAXIMISED, WINDOW_STATE_FULLSCREEN
} WindowState;
struct GraphicsMode;
void Window_Create(int x, int y, int width, int height, const String* title, struct GraphicsMode* mode, struct DisplayDevice* device);
void Window_GetClipboardText(String* value);
@ -69,7 +68,7 @@ bool Window_GetCursorVisible(void);
void Window_SetCursorVisible(bool visible);
#ifndef CC_BUILD_D3D9
void GLContext_Init(struct GraphicsMode mode);
void GLContext_Init(struct GraphicsMode* mode);
void GLContext_Update(void);
void GLContext_Free(void);

View File

@ -1,5 +1,4 @@
#include "World.h"
#include "BlockID.h"
#include "ErrorHandler.h"
#include "String.h"
#include "Platform.h"