diff --git a/README.md b/README.md
index 49ebd555..70d3b5f7 100644
--- a/README.md
+++ b/README.md
@@ -5,14 +5,14 @@
-[![](https://raw.githubusercontent.com/PQCraft/PQCraft/master/Screenshot_20220918_210819.png)](#?)
+[![](https://raw.githubusercontent.com/PQCraft/PQCraft/master/Screenshot_20221128_010856.png)](#?)
---
### Contributing
@@ -36,7 +36,7 @@ OpenGL 3.3 or OpenGLES 3.0 support.
- To build for debugging, add `DEBUG=[level]` after `make` (eg. `make DEBUG=0 -j run`). This will build the executable with debug symbols, disable symbol stripping, and define the internal `DEBUG` macro with the level specified.
- To compile with using SDL2 instead of GLFW, add `USESDL2=y` after `make`.
- To compile using OpenGL ES instead of OpenGL, add `USEGLES=y` after `make`.
-- To change the target to the standalone server, add `SERVER=y` after `make`. This variable will change the object directory.
+- To change the target to the standalone server, add `MODULE=server` after `make`. This variable will change the object directory.
- To cross compile to Windows on a non-Windows OS, add `WINCROSS=y` after `make`. This variable will change the object directory and binary name.
- To compile a 32-bit binary on a 64-bit machine, add `M32=y` after `make`. This variable will change the object directory.
@@ -49,4 +49,4 @@ When using MSYS2, the MINGW64 environment is recommended and always use `MSYS2=y
---
### Notes
-- CaveCube can be installed on Arch Linux using the [cavecube](https://aur.archlinux.org/packages/cavecube) or [cavecube-bin](https://aur.archlinux.org/packages/cavecube-bin) package.
+- CaveCube can be installed on Arch Linux using the [cavecube](https://aur.archlinux.org/packages/cavecube), [cavecube-bin](https://aur.archlinux.org/packages/cavecube-bin), [cavecube-sdl2](https://aur.archlinux.org/packages/cavecube-sdl2), or [cavecube-sdl2-bin](https://aur.archlinux.org/packages/cavecube-sdl2-bin) AUR package.
diff --git a/TODO.md b/TODO.md
index f60dd2dd..bd0860a5 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,6 +3,7 @@
- More UI elements (buttons, text boxes, etc)
- UI interaction (elem states, tooltips, etc)
- Add `fit_width_to_text` and `fit_height_to_text` attrib
+ - Add `text_fmt` attrib
- Add items to hotbar
- Redo almost everything to do with chunks/blocks
- Add physics in `src/physics/`
@@ -43,4 +44,8 @@
### IN-PROGRESS:
### DONE:
-- Removed some left-over debugging code
+- Made internal messages more linear
+- Fixed memory issues
+- Updated README.md
+- Changed default loopDelay value from 5ms to 1ms
+- DEBUG=1+ is now required to print out detailed server start/stop info
diff --git a/extras/docs/world saves.txt b/extras/docs/world saves.txt
new file mode 100644
index 00000000..1c0da542
--- /dev/null
+++ b/extras/docs/world saves.txt
@@ -0,0 +1,25 @@
+/
+ server/
+ players/
+ [Player ID in 16 network order hex chars]
+
+ ...
+ config.cfg
+
+ world/
+ entities/
+ [Entity ID in 16 hex chars]
+
+ ...
+ chunks/
+ /
+ []
+
+ ...
+ state
+
+ dynamic.inf
+
+ static.inf
+
+
diff --git a/src/common/config.c b/src/common/config.c
index 4883892c..7ef1899b 100644
--- a/src/common/config.c
+++ b/src/common/config.c
@@ -274,6 +274,7 @@ struct config* openConfig(char* path) {
}
free(sect);
cfg->changed = false;
+ freeFile(fdata);
return cfg;
}
diff --git a/src/game/game.c b/src/game/game.c
index 57d02119..b5af17b4 100644
--- a/src/game/game.c
+++ b/src/game/game.c
@@ -299,7 +299,7 @@ bool doGame(char* addr, int port) {
tmpbuf[i] = malloc(4096);
}
declareConfigKey(config, "Game", "viewDist", "8", false);
- declareConfigKey(config, "Game", "loopDelay", "5000", false);
+ declareConfigKey(config, "Game", "loopDelay", "1000", false);
declareConfigKey(config, "Player", "name", "Player", false);
declareConfigKey(config, "Player", "skin", "", false);
chunks = allocChunks(atoi(getConfigKey(config, "Game", "viewDist")));
diff --git a/src/input/input.c b/src/input/input.c
index 2643ea35..4f3dd03c 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -69,6 +69,8 @@ char* input_sa_names[] = {
"single.rotBlockX",
"single.rotBlockY",
"single.rotBlockZ",
+ "single.chat",
+ "single.command",
"single.fullscreen",
"single.debug",
//"single.leftClick",
@@ -138,6 +140,8 @@ input_keys input_sa[INPUT_ACTION_SINGLE__MAX] = {
KEY('k', 'b', SDL_SCANCODE_R, 0, 0, 0),
KEY('k', 'b', SDL_SCANCODE_F, 0, 0, 0),
KEY('k', 'b', SDL_SCANCODE_C, 0, 0, 0),
+ KEY('k', 'b', SDL_SCANCODE_T, 0, 0, 0),
+ KEY('k', 'b', SDL_SCANCODE_SLASH, 0, 0, 0),
KEY('k', 'b', SDL_SCANCODE_F11, 0, 0, 0),
KEY('k', 'b', SDL_SCANCODE_F3, 0, 0, 0),
//KEY('m', 'b', SDL_BUTTON(1), 0, 0, 0),
@@ -162,6 +166,8 @@ input_keys input_sa[INPUT_ACTION_SINGLE__MAX] = {
KEY('k', 'b', GLFW_KEY_R, 0, 0, 0),
KEY('k', 'b', GLFW_KEY_F, 0, 0, 0),
KEY('k', 'b', GLFW_KEY_C, 0, 0, 0),
+ KEY('k', 'b', GLFW_KEY_T, 0, 0, 0),
+ KEY('k', 'b', GLFW_KEY_SLASH, 0, 0, 0),
KEY('k', 'b', GLFW_KEY_F11, 0, 0, 0),
KEY('k', 'b', GLFW_KEY_F3, 0, 0, 0),
//KEY('m', 'b', GLFW_MOUSE_BUTTON_LEFT, 0, 0, 0),
diff --git a/src/input/input.h b/src/input/input.h
index 22128214..78fda38c 100644
--- a/src/input/input.h
+++ b/src/input/input.h
@@ -47,6 +47,8 @@ enum {
/*INPUT_ACTION_SINGLE_ROT_X*/ INPUT_ACTION_SINGLE_VARIANT_NEXT,
/*INPUT_ACTION_SINGLE_ROT_Y*/ INPUT_ACTION_SINGLE_VARIANT_PREV,
INPUT_ACTION_SINGLE_ROT_Z,
+ INPUT_ACTION_SINGLE_CHAT,
+ INPUT_ACTION_SINGLE_COMMAND,
INPUT_ACTION_SINGLE_FULLSCR,
INPUT_ACTION_SINGLE_DEBUG,
//INPUT_ACTION_SINGLE_LCLICK, // move to INPUT_ACTION_UI
diff --git a/src/main/version.h b/src/main/version.h
index 5d6ff87d..4e93c875 100644
--- a/src/main/version.h
+++ b/src/main/version.h
@@ -3,7 +3,7 @@
#define VER_MAJOR 0
#define VER_MINOR 5
-#define VER_PATCH 2
+#define VER_PATCH 3
#define _STR(x) #x
#define STR(x) _STR(x)
diff --git a/src/renderer/renderer.c b/src/renderer/renderer.c
index 4bb230ca..c85a4dcf 100644
--- a/src/renderer/renderer.c
+++ b/src/renderer/renderer.c
@@ -440,16 +440,18 @@ struct msgdata_msg {
};
struct msgdata {
- bool valid;
int size;
+ int rptr;
+ int wptr;
struct msgdata_msg* msg;
- pthread_mutex_t lock;
uint64_t id;
+ pthread_mutex_t lock;
};
static force_inline void initMsgData(struct msgdata* mdata) {
- mdata->valid = true;
mdata->size = 0;
+ mdata->rptr = -1;
+ mdata->wptr = -1;
mdata->msg = malloc(0);
pthread_mutex_init(&mdata->lock, NULL);
}
@@ -466,30 +468,19 @@ static void deinitMsgData(struct msgdata* mdata) {
static force_inline void addMsg(struct msgdata* mdata, int64_t x, int64_t z, uint64_t id, bool dep, int lvl) {
pthread_mutex_lock(&mdata->lock);
- if (mdata->valid) {
- int index = -1;
- for (int i = 0; i < mdata->size; ++i) {
- /*if (mdata->msg[i].valid && mdata->msg[i].x == x && mdata->msg[i].z == z) {
- printf("dup: [%"PRId64", %"PRId64"] with [%d]\n", x, z, i);
- goto skip;
- } else*/ if (!mdata->msg[i].valid && index == -1) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- index = mdata->size++;
- mdata->msg = realloc(mdata->msg, mdata->size * sizeof(*mdata->msg));
- }
- //printf("adding [%d]/[%d]\n", index + 1, mdata->size);
- mdata->msg[index].valid = true;
- mdata->msg[index].dep = dep;
- mdata->msg[index].lvl = lvl;
- mdata->msg[index].x = x;
- mdata->msg[index].z = z;
- mdata->msg[index].id = (dep) ? id : mdata->id++;
- //skip:;
+ if (mdata->wptr < 0 || mdata->rptr >= mdata->size) {
+ mdata->rptr = 0;
+ mdata->size = 0;
}
+ mdata->wptr = mdata->size++;
+ //printf("[%lu]: wptr: [%d] size: [%d]\n", (uintptr_t)mdata, mdata->wptr, mdata->size);
+ mdata->msg = realloc(mdata->msg, mdata->size * sizeof(*mdata->msg));
+ mdata->msg[mdata->wptr].valid = true;
+ mdata->msg[mdata->wptr].dep = dep;
+ mdata->msg[mdata->wptr].lvl = lvl;
+ mdata->msg[mdata->wptr].x = x;
+ mdata->msg[mdata->wptr].z = z;
+ mdata->msg[mdata->wptr].id = (dep) ? id : mdata->id++;
pthread_mutex_unlock(&mdata->lock);
}
@@ -506,8 +497,8 @@ void setMeshChunkOff(int64_t x, int64_t z) {
static force_inline bool getNextMsg(struct msgdata* mdata, struct msgdata_msg* msg) {
pthread_mutex_lock(&mdata->lock);
- if (mdata->valid) {
- for (int i = 0; i < mdata->size; ++i) {
+ if (mdata->rptr >= 0) {
+ for (int i = mdata->rptr; i < mdata->size; ++i) {
if (mdata->msg[i].valid) {
msg->valid = mdata->msg[i].valid;
msg->dep = mdata->msg[i].dep;
@@ -516,6 +507,8 @@ static force_inline bool getNextMsg(struct msgdata* mdata, struct msgdata_msg* m
msg->z = mdata->msg[i].z;
msg->id = mdata->msg[i].id;
mdata->msg[i].valid = false;
+ mdata->rptr = i + 1;
+ //printf("[%lu]: rptr: [%d] size: [%d]\n", (uintptr_t)mdata, mdata->rptr, mdata->size);
pthread_mutex_unlock(&mdata->lock);
//printf("returning [%d]/[%d]\n", i + 1, mdata->size);
return true;
@@ -1035,6 +1028,7 @@ static force_inline void meshUIElem(struct meshdata* md, struct ui_data* elemdat
y += tch * s;
}
}
+ free(tdata);
p->x -= mx;
p->width += mx * 2;
p->y -= my;
diff --git a/src/renderer/ui.c b/src/renderer/ui.c
index ea6ecf53..5b3501a5 100644
--- a/src/renderer/ui.c
+++ b/src/renderer/ui.c
@@ -356,6 +356,7 @@ bool calcUIProperties(struct ui_data* elemdata) {
void freeUI(struct ui_data* elemdata) {
clearUIElems(elemdata);
glDeleteBuffers(1, &elemdata->renddata.VBO);
+ free(elemdata->data);
free(elemdata);
}
diff --git a/src/server/server.c b/src/server/server.c
index 0d7b3495..c5900717 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -24,22 +24,23 @@ struct msgdata_msg {
};
struct msgdata {
- bool valid;
int size;
+ int rptr;
+ int wptr;
struct msgdata_msg* msg;
pthread_mutex_t lock;
};
static force_inline void initMsgData(struct msgdata* mdata) {
- mdata->valid = true;
mdata->size = 0;
+ mdata->rptr = -1;
+ mdata->wptr = -1;
mdata->msg = malloc(0);
pthread_mutex_init(&mdata->lock, NULL);
}
static force_inline void deinitMsgData(struct msgdata* mdata) {
pthread_mutex_lock(&mdata->lock);
- mdata->valid = false;
free(mdata->msg);
pthread_mutex_unlock(&mdata->lock);
pthread_mutex_destroy(&mdata->lock);
@@ -47,36 +48,32 @@ static force_inline void deinitMsgData(struct msgdata* mdata) {
static force_inline void addMsg(struct msgdata* mdata, int id, void* data, uint64_t uuid, int uind) {
pthread_mutex_lock(&mdata->lock);
- if (mdata->valid) {
- int index = -1;
- for (int i = 0; i < mdata->size; ++i) {
- if (mdata->msg[i].id < 0) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- index = mdata->size++;
- mdata->msg = realloc(mdata->msg, mdata->size * sizeof(*mdata->msg));
- }
- mdata->msg[index].id = id;
- mdata->msg[index].data = data;
- mdata->msg[index].uuid = uuid;
- mdata->msg[index].uind = uind;
+ if (mdata->wptr < 0 || mdata->rptr >= mdata->size) {
+ mdata->rptr = 0;
+ mdata->size = 0;
}
+ mdata->wptr = mdata->size++;
+ //printf("[%lu]: wptr: [%d] size: [%d]\n", (uintptr_t)mdata, mdata->wptr, mdata->size);
+ mdata->msg = realloc(mdata->msg, mdata->size * sizeof(*mdata->msg));
+ mdata->msg[mdata->wptr].id = id;
+ mdata->msg[mdata->wptr].data = data;
+ mdata->msg[mdata->wptr].uuid = uuid;
+ mdata->msg[mdata->wptr].uind = uind;
pthread_mutex_unlock(&mdata->lock);
}
static force_inline bool getNextMsg(struct msgdata* mdata, struct msgdata_msg* msg) {
pthread_mutex_lock(&mdata->lock);
- if (mdata->valid) {
- for (int i = 0; i < mdata->size; ++i) {
+ if (mdata->rptr >= 0) {
+ for (int i = mdata->rptr; i < mdata->size; ++i) {
if (mdata->msg[i].id >= 0) {
msg->id = mdata->msg[i].id;
msg->data = mdata->msg[i].data;
msg->uuid = mdata->msg[i].uuid;
msg->uind = mdata->msg[i].uind;
mdata->msg[i].id = -1;
+ mdata->rptr = i + 1;
+ //printf("[%lu]: rptr: [%d] size: [%d]\n", (uintptr_t)mdata, mdata->rptr, mdata->size);
pthread_mutex_unlock(&mdata->lock);
return true;
}
@@ -88,14 +85,16 @@ static force_inline bool getNextMsg(struct msgdata* mdata, struct msgdata_msg* m
static force_inline bool getNextMsgForUUID(struct msgdata* mdata, struct msgdata_msg* msg, uint64_t uuid) {
pthread_mutex_lock(&mdata->lock);
- if (mdata->valid) {
- for (int i = 0; i < mdata->size; ++i) {
+ if (mdata->rptr >= 0) {
+ for (int i = mdata->rptr; i < mdata->size; ++i) {
if (mdata->msg[i].id >= 0 && mdata->msg[i].uuid == uuid) {
msg->id = mdata->msg[i].id;
msg->data = mdata->msg[i].data;
msg->uuid = mdata->msg[i].uuid;
msg->uind = mdata->msg[i].uind;
mdata->msg[i].id = -1;
+ mdata->rptr = i + 1;
+ //printf("[%lu]: rptr: [%d] size: [%d]\n", (uintptr_t)mdata, mdata->rptr, mdata->size);
pthread_mutex_unlock(&mdata->lock);
return true;
}
@@ -120,6 +119,7 @@ struct timerdata_timer {
int priority;
uint64_t interval;
uint64_t intertime;
+ bool ack;
};
struct timerdata {
@@ -218,6 +218,7 @@ static void* servtimerthread(void* vargs) {
enum {
_SERVER_TIMER1 = 512,
_SERVER_TIMER2,
+ _SERVER_TICK,
};
static struct timerdata servtimer;
@@ -352,7 +353,7 @@ static void* servthread(void* args) {
}
case _SERVER_USERCONNECT:; {
struct server_data_setskycolor* tmpdata = malloc(sizeof(*tmpdata));
- *tmpdata = (struct server_data_setskycolor){0x8A, 0xC9, 0xFF};
+ *tmpdata = (struct server_data_setskycolor){0xA0, 0xC8, 0xFF};
addMsg(&servmsgout[MSG_PRIO_HIGH], SERVER_SETSKYCOLOR, tmpdata, msg.uuid, msg.uind);
break;
}
@@ -579,7 +580,9 @@ int startServer(char* addr, int port, int mcli, char* world) {
return -1;
}
serveralive = true;
+ #if DBGLVL(1)
puts(" Initializing connection...");
+ #endif
port = servcxn->info.port;
setCxnBufSize(servcxn, SERVER_SNDBUF_SIZE, CLIENT_SNDBUF_SIZE);
pdata = calloc(maxclients, sizeof(*pdata));
@@ -589,28 +592,37 @@ int startServer(char* addr, int port, int mcli, char* world) {
for (int i = 0; i < MSG_PRIO__MAX; ++i) {
initMsgData(&servmsgout[i]);
}
+ #if DBGLVL(1)
puts(" Initializing noise...");
+ #endif
setRandSeed(0, 32464);
initNoiseTable(0);
initWorldgen();
+ #if DBGLVL(1)
puts(" Initializing timer and events...");
+ #endif
initTimerData(&servtimer);
addTimer(&servtimer, _SERVER_TIMER1, MSG_PRIO_LOW, 2000000);
addTimer(&servtimer, _SERVER_TIMER2, MSG_PRIO_LOW, 1200000);
+ addTimer(&servtimer, _SERVER_TICK, MSG_PRIO_HIGH, 50000);
#ifdef NAME_THREADS
char name[256];
char name2[256];
name[0] = 0;
name2[0] = 0;
#endif
+ #if DBGLVL(1)
puts(" Starting server network thread...");
+ #endif
pthread_create(&servnetthreadh, NULL, &servnetthread, NULL);
#ifdef NAME_THREADS
pthread_getname_np(servnetthreadh, name2, 256);
sprintf(name, "%s:snet", name2);
pthread_setname_np(servnetthreadh, name);
#endif
+ #if DBGLVL(1)
puts(" Starting server timer thread...");
+ #endif
pthread_create(&servtimerh, NULL, &servtimerthread, &servtimer);
#ifdef NAME_THREADS
pthread_getname_np(servtimerh, name2, 256);
@@ -622,7 +634,9 @@ int startServer(char* addr, int port, int mcli, char* world) {
name[0] = 0;
name2[0] = 0;
#endif
+ #if DBGLVL(1)
printf(" Starting server thread [%d]...\n", i);
+ #endif
pthread_create(&servpthreads[i], NULL, &servthread, (void*)(intptr_t)i);
#ifdef NAME_THREADS
pthread_getname_np(servpthreads[i], name2, 256);
@@ -644,18 +658,26 @@ void stopServer() {
printf(" Waiting for server thread [%d]...\n", i);
pthread_join(servpthreads[i], NULL);
}
+ #if DBGLVL(1)
puts(" Waiting for server network thread...");
+ #endif
pthread_join(servnetthreadh, NULL);
+ #if DBGLVL(1)
puts(" Waiting for server timer thread...");
+ #endif
pthread_join(servtimerh, NULL);
+ #if DBGLVL(1)
puts(" Closing connections...");
+ #endif
for (int i = 0; i < maxclients; ++i) {
if (pdata[i].valid) {
closeCxn(pdata[i].cxn);
}
}
closeCxn(servcxn);
+ #if DBGLVL(1)
puts(" Cleaning up...");
+ #endif
free(pdata);
deinitTimerData(&servtimer);
for (int i = 0; i < MSG_PRIO__MAX; ++i) {