Rearranged to prepare for server code. Added simple enet based softmodem for testing in Linux.

This commit is contained in:
Scott Duensing 2021-11-16 21:15:09 -06:00
parent 30c8947936
commit 9f066b6e92
50 changed files with 8584 additions and 8204 deletions

43
LICENSE
View file

@ -27,6 +27,11 @@ DOS Serial Library
https://github.com/kstenerud/DOS-Serial-Library
Attribution
ENet
----
https://github.com/zpl-c/enet
MIT
MemWatch
--------
http://www.linkdata.se/sourcecode/memwatch/
@ -42,11 +47,6 @@ SDL2
https://www.libsdl.org/
BSD 3-Clause
SDL2_Net
--------
https://www.libsdl.org/
BSD 3-Clause
stb_ds.h
--------
https://github.com/nothings/stb
@ -56,3 +56,36 @@ stb_image.h
-----------
https://github.com/nothings/stb
Public Domain
Font Converter
==============
MemWatch
--------
http://www.linkdata.se/sourcecode/memwatch/
GPL2
stb_image.h
-----------
https://github.com/nothings/stb
Public Domain
Server
======
ENet
----
https://github.com/zpl-c/enet
MIT
MemWatch
--------
http://www.linkdata.se/sourcecode/memwatch/
GPL2
stb_ds.h
--------
https://github.com/nothings/stb
Public Domain

View file

@ -27,12 +27,13 @@ DEBUG = -g
## CHANGE THIS ##
TARGET = client
SRCDIR = src
SHARED = ../shared
OBJDIR = obj
BINDIR = bin
## CHANGE THIS ##
# CFLAGS, LDFLAGS, CPPFLAGS, PREFIX can be overriden on CLI
CFLAGS := $(DEBUG) -I$(SRCDIR) -I$(SRCDIR)/system -I$(SRCDIR)/dos -I$(SRCDIR)/gui -I$(SRCDIR)/thirdparty -I$(SRCDIR)/thirdparty/memwatch -I$(SRCDIR)/thirdparty/serial
CFLAGS := $(DEBUG) -I$(SRCDIR) -I$(SRCDIR)/system -I$(SRCDIR)/dos -I$(SRCDIR)/gui -I$(SRCDIR)/thirdparty -I$(SRCDIR)/thirdparty/serial -I$(SHARED) -I$(SHARED)/thirdparty
CPPFLAGS :=
LDFLAGS :=
PREFIX := /usr/local
@ -52,7 +53,7 @@ ALL_LDLIBS := -lc
# Source, Binaries, Dependencies
SRC := $(shell find $(SRCDIR) -type f -name '*.c' | grep -v '/linux/')
SRC := $(shell find $(SRCDIR) -type f -name '*.c' | grep -v '/linux/' && find $(SHARED) -type f -name '*.c')
OBJ := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(SRC:.c=.o))
DEP := $(OBJ:.o=.d)
BIN := $(BINDIR)/$(TARGET)

View file

@ -23,6 +23,7 @@ TEMPLATE = app
CONFIG -= qt
DESTDIR = $$OUT_PWD/bin
SHARED = $$PWD/../shared
DOS_HEADERS = \
src/thirdparty/serial/serial.h
@ -34,15 +35,19 @@ DOS_SOURCES = \
src/dos/vesa.c
LINUX_INCLUDES = \
$$PWD/src/linux
$$PWD/src/linux \
$$SHARED/thirdparty/enet/include
LINUX_HEADERS =
LINUX_HEADERS = \
$$SHARED/thirdparty/enet/include/enet.h
LINUX_SOURCES = \
src/linux/linux.c
INCLUDEPATH += \
$$LINUX_INCLUDES \
$$SHARED \
$$SHARED/thirdparty \
$$PWD/src/thirdparty \
$$PWD/src/system \
$$PWD/src/gui \
@ -50,16 +55,18 @@ INCLUDEPATH += \
HEADERS = \
$$LINUX_HEADERS \
$$SHARED/stddclmr.h \
$$SHARED/thirdparty/stb_ds.h \
$$SHARED/thirdparty/stb_image.h \
$$SHARED/thirdparty/memwatch/memwatch.h \
src/system/comport.h \
src/thirdparty/minicoro/minicoro.h \
src/settings.h \
src/system/color.h \
src/system/memory.h \
src/system/surface.h \
src/system/taglist.h \
src/test.h \
src/thirdparty/stb_ds.h \
src/thirdparty/stb_image.h \
src/thirdparty/memwatch/memwatch.h \
src/thirdparty/minicoro/minicoro.h \
src/system/keyboard.h \
src/system/task.h \
src/system/timer.h \
@ -85,13 +92,12 @@ HEADERS = \
src/gui/widget.h \
src/gui/window.h \
src/gui/image.h \
src/stddclmr.h \
src/welcome.h
SOURCES = \
$$LINUX_SOURCES \
$$SHARED/thirdparty/memwatch/memwatch.c \
src/system/memory.c \
src/thirdparty/memwatch/memwatch.c \
src/settings.c \
src/system/surface.c \
src/system/taglist.c \
@ -120,11 +126,12 @@ SOURCES = \
src/welcome.c
LIBS = \
-lSDL2 \
-lSDL2_net
-lSDL2
OTHER_FILES = \
Makefile.djgpp \
$$DOS_HEADERS \
$$DOS_SOURCES \
build.sh
build.sh \
test.sh \
test.conf

View file

@ -20,11 +20,15 @@
#include <SDL2/SDL.h>
#define ENET_IMPLEMENTATION
#include "enet.h"
#include "os.h"
#include "mouse.h"
#include "vesa.h"
#include "surface.h"
#include "comport.h"
#define SECONDS_IN_DAY 86400
@ -32,30 +36,46 @@
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
#define TIMER_INTERVAL (1000 / TICKS_PER_SECOND)
#define COM_BUFFER_SIZE 2048
#define MODEM_RESULT_OK 1
#define MODEM_RESULT_ERROR 2
static MouseT _mouse;
static SDL_Window *_window = NULL;
static SDL_Renderer *_renderer = NULL;
static SDL_Surface *_surface = NULL;
static SDL_Texture *_texture = NULL;
static uint16_t _width = 0;
static uint16_t _height = 0;
static uint8_t _windowScale = 1;
static uint8_t _alt = 0;
static uint8_t _control = 0;
static uint8_t _shift = 0;
static uint8_t _ASCII = 0;
static uint8_t _scanCode = 0;
static uint8_t _extended = 0;
static uint8_t _ASCIIKeep = 0;
static uint8_t _scanCodeKeep = 0;
static uint8_t _keyPressed = 0;
static uint8_t _debounce = 0;
static long _timerTicks = 0;
static SDL_Window *_window = NULL;
static SDL_Renderer *_renderer = NULL;
static SDL_Surface *_surface = NULL;
static SDL_Texture *_texture = NULL;
static uint16_t _width = 0;
static uint16_t _height = 0;
static uint8_t _windowScale = 1;
static uint8_t _alt = 0;
static uint8_t _control = 0;
static uint8_t _shift = 0;
static uint8_t _ASCII = 0;
static uint8_t _scanCode = 0;
static uint8_t _extended = 0;
static uint8_t _ASCIIKeep = 0;
static uint8_t _scanCodeKeep = 0;
static uint8_t _keyPressed = 0;
static uint8_t _debounce = 0;
static long _timerTicks = 0;
static SDL_TimerID _timerID;
static ENetHost *_host = NULL;
static ENetPeer *_peer = NULL;
static ENetAddress _address;
static uint8_t _comPortOpen = 0;
static uint8_t _modemCommandMode = 1;
static char _buffer[COM_BUFFER_SIZE];
static uint16_t _bufferHead = 0;
static uint16_t _bufferTail = 0;
static uint8_t _connected = 0;
static void comAddToBuffer(char *data, uint16_t len);
static void comModem(uint8_t c);
static void processEvent(void);
static void processNetworkEvent(void);
long biostime(int cmd, long newtime) {
@ -66,6 +86,188 @@ long biostime(int cmd, long newtime) {
}
static void comAddToBuffer(char *data, uint16_t len) {
uint16_t x;
for (x=0; x<len; x++) {
_buffer[_bufferHead++] = data[x];
if (_bufferHead >= COM_BUFFER_SIZE) _bufferHead = 0;
}
}
int comClose(int com) {
// We only pretend to support one COM port.
if (com != 0) return SER_ERR_UNKNOWN;
if (!_comPortOpen) return SER_ERR_NOT_OPEN;
if (_peer) {
enet_peer_reset(_peer);
_peer = NULL;
}
if (_host) {
enet_host_destroy(_host);
_host = NULL;
}
_comPortOpen = 0;
return SER_SUCCESS;
}
static void comModem(uint8_t c) {
static char command[COM_BUFFER_SIZE] = { 0 };
uint16_t x;
uint8_t result = 0;
uint8_t parsing = 1;
char *p = NULL;
if (c != 13) {
x = strlen(command);
// Room in buffer?
if (x > COM_BUFFER_SIZE - 1) {
// No. Error. Clear buffer.
snprintf(command, COM_BUFFER_SIZE, "%cERROR%c", 13, 13);
comAddToBuffer(command, strlen(command));
command[0] = 0;
} else {
// Add to command buffer.
command[x] = toupper(c);
command[x+1] = 0;
}
} else {
// AT?
if (command[0] != 'A' || command[1] != 'T') result = MODEM_RESULT_ERROR;
// Process command string.
x = 2;
while (parsing && !result && command[x]) {
switch (command[x]) {
// Vendor Commands
case '+':
x++;
// Select Socket Mode
if (strncmp(&command[x], "SOCK", 4) == 0) {
result = MODEM_RESULT_OK;
} else {
result = MODEM_RESULT_ERROR;
}
break;
// Dial
case 'D':
x++;
if (command[x] == 'T' || command[x] == 'P') x++;
// Find port, if any.
_address.port = 23;
if ((p = strstr(&command[x], ":"))) {
p = 0;
p++;
_address.port = atoi(p);
}
enet_address_set_host(&_address, &command[x]);
_peer = enet_host_connect(_host, &_address, 1, 0);
if (!_peer) result = MODEM_RESULT_ERROR;
result = MODEM_RESULT_OK;
_modemCommandMode = 0;
break;
// Dunno.
default:
result = MODEM_RESULT_ERROR;
break;
}
}
// Send result.
switch (result) {
case MODEM_RESULT_OK:
snprintf(command, COM_BUFFER_SIZE, "OK%c", 13);
comAddToBuffer(command, strlen(command));
break;
case MODEM_RESULT_ERROR:
snprintf(command, COM_BUFFER_SIZE, "ERROR%c", 13);
comAddToBuffer(command, strlen(command));
break;
}
// Clear buffer.
command[0] = 0;
}
}
int comOpen(int com, long bps, int dataBits, char parity, int stopBits, int handshaking) {
(void)bps;
(void)dataBits;
(void)parity;
(void)stopBits;
(void)handshaking;
// We only pretend to support one COM port.
if (com != 0) return SER_ERR_UNKNOWN;
if (_comPortOpen) return SER_ERR_ALREADY_OPEN;
_comPortOpen = 1;
_bufferHead = 0;
_bufferTail = 0;
return SER_SUCCESS;
}
int comRead(int com, char *data, int len) {
uint16_t x = 0;
// We only pretend to support one COM port.
if (com != 0) return SER_ERR_UNKNOWN;
if (!_comPortOpen) return SER_ERR_NOT_OPEN;
// Is the buffer empty?
if (_bufferHead == _bufferTail) {
return 0;
}
// Fill buffer.
while (x < len && _bufferHead != _bufferTail) {
data[x++] = _buffer[_bufferTail++];
if (_bufferTail >= COM_BUFFER_SIZE) _bufferTail = 0;
}
return x;
}
int comWrite(int com, const char *data, int len) {
uint16_t x = 0;
ENetPacket *packet = NULL;
// We only pretend to support one COM port.
if (com != 0) return SER_ERR_UNKNOWN;
if (!_comPortOpen) return SER_ERR_NOT_OPEN;
while (_modemCommandMode && x < len) {
comAddToBuffer((char *)&data[x], 1);
comModem(data[x++]);
}
if (!_modemCommandMode && _connected && len - x > 0) {
packet = enet_packet_create(&data[x], len - x, ENET_PACKET_FLAG_RELIABLE);
if (!packet) return SER_ERR_UNKNOWN;
enet_peer_send(_peer, 0, packet);
}
return SER_SUCCESS;
}
uint8_t keyAltGet(void) {
return _alt;
}
@ -218,6 +420,36 @@ static void processEvent(void) {
break;
}
}
processNetworkEvent();
}
static void processNetworkEvent(void) {
ENetEvent *event = NULL;
if (_host) {
while (enet_host_service(_host, event, 1)) {
switch (event->type) {
case ENET_EVENT_TYPE_CONNECT:
_connected = 1;
break;
case ENET_EVENT_TYPE_RECEIVE:
comAddToBuffer((char *)event->packet->data, event->packet->dataLength);
break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
_connected = 0;
_modemCommandMode = 1;
break;
default:
break;
}
}
}
}
@ -264,18 +496,25 @@ ColorT vbeColorMake(uint8_t red, uint8_t green, uint8_t blue) {
void vbePresent(void) {
void *pixels;
int pitch;
SurfaceT *s = surfaceOffScreenGet();
void *pixels;
int temp;
SurfaceT *s = surfaceOffScreenGet();
SDL_LockTexture(_texture, NULL, &pixels, &pitch);
SDL_LockTexture(_texture, NULL, &pixels, &temp);
memcpy(pixels, s->buffer.bits8, s->bytes);
SDL_UnlockTexture(_texture);
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
SDL_RenderPresent(_renderer);
// Throttle this to some sane frame rate.
SDL_Delay(32);
if (_host) {
// Throttle this to some sane frame rate by checking for network events.
for (temp=0; temp<32; temp++) {
processNetworkEvent();
}
} else {
// No network activity. Just sleep.
SDL_Delay(32);
}
}
@ -301,6 +540,9 @@ int16_t vbeShutdown(void) {
_window = NULL;
}
// Stop network.
enet_deinitialize();
// Stop timer.
SDL_RemoveTimer(_timerID);
@ -332,6 +574,9 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
// We do timer startup here, too.
_timerID = SDL_AddTimer(TIMER_INTERVAL, timerCallback, NULL);
// And networking/serial startup.
enet_initialize();
return 0;
}

View file

@ -65,6 +65,7 @@ static void taskGuiEventLoop(void *data) {
ColorT alpha;
#ifdef TESTING
int8_t debugState = 0;
int8_t key = 0;
#endif
(void)data;
@ -87,7 +88,7 @@ static void taskGuiEventLoop(void *data) {
imageRenderWithAlpha(pointer, mouse->x, mouse->y, alpha);
#ifdef TESTING
if (key == '=') guiWidgetTreeDump(guiRootGet(), 0);
if (key == '=') guiDebugWidgetTreeDump(guiRootGet(), 0);
if (key == '+') {
debugState++;
if (debugState > 2) debugState = 0;
@ -150,12 +151,12 @@ int main(int argc, char *argv[]) {
taskStartup();
#ifdef TESTING
taskCreate(taskTestTagList, NULL);
taskCreate(comPortScanTest, NULL);
#else
taskCreate(taskWelcome, NULL);
taskCreate(taskGuiEventLoop, NULL);
#endif
taskCreate(taskGuiEventLoop, NULL);
taskRun();
taskShutdown();

View file

@ -23,16 +23,38 @@
#include "taglist.h"
#include "task.h"
#include "comport.h"
#include "timer.h"
#include "window.h"
#include "button.h"
#include "frame.h"
#include "radio.h"
#include "textbox.h"
#include "updown.h"
#include "label.h"
static WindowT *winSettings;
static FrameT *frmComPorts;
static ButtonT *btnOkay;
#define GROUP_COM 1
#define PORT_NONE 0
#define PORT_BAD 1
#define PORT_GOOD 2
static WindowT *winDetecting;
static LabelT *lblOneMoment;
static WindowT *winSettings;
static FrameT *frmComPorts;
static FrameT *frmServer;
static ButtonT *btnOkay;
static RadioT *rdoCOM1;
static RadioT *rdoCOM2;
static RadioT *rdoCOM3;
static RadioT *rdoCOM4;
static TextboxT *txtServer;
static UpdownT *updPort;
static void btnOkayClick(WidgetT *widget);
@ -47,23 +69,114 @@ static void btnOkayClick(WidgetT *widget) {
void taskSettings(void *data) {
int32_t rc;
uint32_t len;
char buffer[1024];
uint8_t quarterSeconds = 0;
uint8_t ports[4] = { PORT_NONE, PORT_NONE, PORT_NONE, PORT_NONE }; // 0 = No port. 1 = No modem. 2 = Valid.
(void)data;
TagItemT ui[] = {
TagItemT uiDetecting[] = {
T_START,
T_WINDOW, O(winSettings),
T_TITLE, P("Settings"),
T_WIDTH, 200, T_HEIGHT, 200,
T_BUTTON, O(btnOkay),
T_TITLE, P("Okay"),
T_CLICK, P(btnOkayClick),
T_BUTTON, T_DONE,
T_WINDOW, O(winDetecting),
T_TITLE, P("Detecting Modems"),
T_WIDTH, 200, T_HEIGHT, 100,
T_LABEL, O(lblOneMoment),
T_X, 25, T_Y, 25,
T_TITLE, P("One Moment Please!"),
T_LABEL, T_DONE,
T_WINDOW, T_DONE,
T_END
};
tagListRun(ui);
tagListRun(uiDetecting);
taskYield(); // Cause dialog to paint.
for (int x=0; x<4; x++) {
rc = comOpen(x, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
if (rc == SER_SUCCESS) {
snprintf(buffer, 1024, "%s%c", "AT+SOCK1", 13);
comWrite(x, buffer, strlen(buffer));
// Wait a second.
while (quarterSeconds < 5) {
taskYield();
if (timerQuarterSecondTick) quarterSeconds++;
}
len = comRead(x, buffer, 1024);
buffer[len] = 0;
if (strstr(buffer, "OK")) {
ports[x] = PORT_GOOD;
} else {
ports[x] = PORT_BAD;
}
comClose(x);
}
}
guiDelete(D(winDetecting));
TagItemT uiSettings[] = {
T_START,
T_WINDOW, O(winSettings),
T_TITLE, P("Settings"),
T_WIDTH, 300, T_HEIGHT, 295,
T_FRAME, O(frmComPorts),
T_X, 10, T_Y, 5, T_WIDTH, 266, T_HEIGHT, 100,
T_TITLE, P("COM Ports"),
T_RADIOBUTTON, O(rdoCOM1),
T_X, 5,
T_TITLE, P((ports[0] == PORT_NONE ? "COM1 - Not Present" : (ports[0] == PORT_BAD ? "COM1 - Incompatable Modem" : "COM1 - SoftModem Found!"))),
T_GROUP, GROUP_COM,
T_RADIOBUTTON, T_DONE,
T_RADIOBUTTON, O(rdoCOM2),
T_X, 5, T_Y, 20,
T_TITLE, P((ports[1] == PORT_NONE ? "COM2 - Not Present" : (ports[1] == PORT_BAD ? "COM2 - Incompatable Modem" : "COM2 - SoftModem Found!"))),
T_GROUP, GROUP_COM,
T_RADIOBUTTON, T_DONE,
T_RADIOBUTTON, O(rdoCOM3),
T_X, 5, T_Y, 40,
T_TITLE, P((ports[2] == PORT_NONE ? "COM3 - Not Present" : (ports[2] == PORT_BAD ? "COM3 - Incompatable Modem" : "COM3 - SoftModem Found!"))),
T_GROUP, GROUP_COM,
T_RADIOBUTTON, T_DONE,
T_RADIOBUTTON, O(rdoCOM4),
T_X, 5, T_Y, 60,
T_TITLE, P((ports[3] == PORT_NONE ? "COM4 - Not Present" : (ports[3] == PORT_BAD ? "COM4 - Incompatable Modem" : "COM4 - SoftModem Found!"))),
T_GROUP, GROUP_COM,
T_RADIOBUTTON, T_DONE,
T_FRAME, T_DONE,
T_FRAME, O(frmServer),
T_X, 10, T_Y, 110, T_WIDTH, 266, T_HEIGHT, 100,
T_TITLE, P("Server"),
T_TEXTBOX, O(txtServer),
T_X, 5, T_WIDTH, 250,
T_TITLE, P("Address:"),
T_VALUE, P("kangaworld.kangaroopunch.com"),
T_TEXTBOX, T_DONE,
T_UPDOWN, O(updPort),
T_X, 5, T_Y, 30, T_WIDTH, 250,
T_TITLE, P(" Port:"),
T_VALUE, 16550,
T_MINIMUM, 1,
T_MAXIMUM, 65535,
T_UPDOWN, T_DONE,
T_FRAME, T_DONE,
T_BUTTON, O(btnOkay),
T_X, 225, T_Y, 225,
T_TITLE, P("Okay"),
T_CLICK, P(btnOkayClick),
T_BUTTON, T_DONE,
T_WINDOW, T_DONE,
T_END
};
tagListRun(uiSettings);
guiDebugAreaShow(W(winSettings));
guiDebugAreaShow(W(frmComPorts));
guiDebugAreaShow(W(btnOkay));
}

View file

@ -18,12 +18,38 @@
*/
#ifndef STB_H
#define STB_H
#ifndef COMPORT_H
#define COMPORT_H
#include "stb_image.h"
#include "stb_leakcheck.h"
#include "os.h"
#endif // STB_H
#ifdef __linux__
#define SER_SUCCESS 0
#define SER_ERR_UNKNOWN -1
#define SER_ERR_NOT_OPEN -2
#define SER_ERR_ALREADY_OPEN -3
#define SER_HANDSHAKING_RTSCTS 2
int comClose(int com);
int comOpen(int com, long bps, int dataBits, char parity, int stopBits, int handshaking);
int comRead(int com, char *data, int len);
int comWrite(int com, const char *data, int len);
#else
#include "serial/serial.h"
#define comClose serial_close
#define comOpen serial_open
#define comRead serial_read
#define comWrite serial_write
#endif
#endif // COMPORT_H

View file

@ -26,6 +26,10 @@
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
uint8_t timerQuarterSecondTick = 0;
uint8_t timerHalfSecondTick = 0;
uint8_t timerSecondTick = 0;
uint8_t timerQuarterSecondOn = 0;
uint8_t timerHalfSecondOn = 0;
uint8_t timerSecondOn = 0;
@ -52,6 +56,11 @@ void timerUpdate(void) {
now = biostime(0, 0);
// Reset ticks.
timerQuarterSecondTick = 0;
timerHalfSecondTick = 0;
timerSecondTick = 0;
// Ensure we haven't rolled past midnight between calls.
if (now >= _timerLast) {
delta = now - _timerLast;
@ -66,16 +75,19 @@ void timerUpdate(void) {
// Quarter Second timer.
timerQuarterSecondOn = !timerQuarterSecondOn;
timerQuarterSecondTick = 1;
// Half Second timer.
if (--_timerHalfSecond == 0) {
_timerHalfSecond = 2;
timerHalfSecondOn = !timerHalfSecondOn;
timerHalfSecondTick = 1;
// Second timer
if (--_timerSecond == 0) {
_timerSecond = 2;
timerSecondOn = !timerSecondOn;
timerSecondTick = 1;
} // Second.
} // Half Second.

View file

@ -25,6 +25,10 @@
#include "os.h"
extern uint8_t timerQuarterSecondTick;
extern uint8_t timerHalfSecondTick;
extern uint8_t timerSecondTick;
extern uint8_t timerQuarterSecondOn;
extern uint8_t timerHalfSecondOn;
extern uint8_t timerSecondOn;

View file

@ -36,6 +36,9 @@
#include "terminal.h"
#include "taglist.h"
#include "comport.h"
#include <unistd.h>
uint8_t lastKey = 0;
@ -53,6 +56,37 @@ static void buttonClick(WidgetT *widget) {
}
void comPortScanTest(void *data) {
int rc;
int len;
char buffer[1024];
(void)data;
for (int x=0; x<4; x++) {
rc = comOpen(x, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
if (rc == SER_SUCCESS) {
logWrite("COM%d exists!\n", x + 1);
snprintf(buffer, 1024, "%s%c", "AT+SOCK1", 13);
comWrite(x, buffer, strlen(buffer));
sleep(1);
len = comRead(x, buffer, 1024);
buffer[len] = 0;
if (strstr(buffer, "OK")) {
logWrite("ENET SoftModem found!\n");
} else {
logWrite("Result: [%s]\n", buffer);
}
comClose(x);
} else {
logWrite("No COM%d.\n", x + 1);
}
}
guiStop();
}
/*
static void test(void *data) {
DesktopT *desktop = (DesktopT *)guiRootGet();

View file

@ -29,6 +29,7 @@
extern uint8_t lastKey;
void comPortScanTest(void *data);
void taskTestTagList(void *data);
void widgetDebugDraw(WidgetT *widget, uint8_t debugToggle);

View file

@ -65,7 +65,7 @@ void taskWelcome(void *data) {
// 450x128 logo
TagItemT ui[] = {
TagItemT uiWelcome[] = {
T_START,
T_WINDOW, O(winWelcome),
T_TITLE, P("Welcome to KangaWorld!"),
@ -93,5 +93,5 @@ void taskWelcome(void *data) {
T_END
};
tagListRun(ui);
tagListRun(uiWelcome);
}

474
client/test.conf Normal file
View file

@ -0,0 +1,474 @@
# This is the configuration file for dosbox-staging (0.78.0).
# Lines starting with a '#' character are comments.
[sdl]
# fullscreen: Start directly in fullscreen.
# Run INTRO and see Special Keys for window control hotkeys.
# display: Number of display to use; values depend on OS and user settings.
# fullresolution: What resolution to use for fullscreen: 'original', 'desktop'
# or a fixed size (e.g. 1024x768).
# windowresolution: Set window size when running in windowed mode:
# default: Select the best option based on your
# environment and other settings.
# small, medium, or large (or s, m, l):
# Size the window relative to the desktop.
# <custom>: Scale the window to the given dimensions in
# WxH format. For example: 1024x768.
# Scaling is not performed for output=surface.
# window_position: Set initial window position when running in windowed mode:
# auto: Let the window manager decide the position.
# <custom>: Set window position in X,Y format. For example: 250,100
# 0,0 is the top-left corner of the screen.
# window_decorations: Controls whether to display window decorations in windowed mode.
# vsync: Synchronize with display refresh rate if supported. This can
# reduce flickering and tearing, but may also impact performance.
# vsync_skip: Number of microseconds to allow rendering to block before skipping the next frame. 0 disables this and will always render.
# max_resolution: Optionally restricts the viewport resolution within the window/screen:
# auto: The viewport fills the window/screen (default).
# <custom>: Set max viewport resolution in WxH format.
# For example: 960x720
# output: What video system to use for output.
# Possible values: surface, texture, texturenb, texturepp, opengl, openglnb, openglpp.
# texture_renderer: Choose a renderer driver when using a texture output mode.
# Use texture_renderer=auto for an automatic choice.
# Possible values: auto, opengl, opengles2, software.
# capture_mouse: Choose a mouse control method:
# onclick: Capture the mouse when clicking any button in the window.
# onstart: Capture the mouse immediately on start.
# seamless: Let the mouse move seamlessly; captures only with middle-click or hotkey.
# nomouse: Hide the mouse and don't send input to the game.
# Choose how middle-clicks are handled (second parameter):
# middlegame: Middle-clicks are sent to the game.
# middlerelease: Middle-click will release the captured mouse, and also capture when seamless.
# Defaults (if not present or incorrect): seamless middlerelease
# Possible values: seamless, onclick, onstart, nomouse.
# sensitivity: Mouse sensitivity. The optional second parameter specifies vertical sensitivity (e.g. 100,-50).
# raw_mouse_input: Enable this setting to bypass your operating system's mouse
# acceleration and sensitivity settings. This works in
# fullscreen or when the mouse is captured in window mode.
# waitonerror: Wait before closing the console if dosbox has an error.
# priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized.
# pause is only valid for the second entry. auto disables priority levels and uses OS defaults
# Possible values: auto, lowest, lower, normal, higher, highest, pause.
# mapperfile: File used to load/save the key/event mappings from.
# Resetmapper only works with the default value.
# screensaver: Use 'allow' or 'block' to override the SDL_VIDEO_ALLOW_SCREENSAVER
# environment variable (which usually blocks the OS screensaver
# while the emulator is running).
# Possible values: auto, allow, block.
fullscreen = false
display = 0
fullresolution = desktop
windowresolution = default
window_position = auto
window_decorations = true
vsync = false
vsync_skip = 7000
max_resolution = auto
output = opengl
texture_renderer = auto
capture_mouse = seamless middlerelease
sensitivity = 100
raw_mouse_input = false
waitonerror = true
priority = auto,auto
mapperfile = mapper-sdl2-0.78.0.map
screensaver = auto
[dosbox]
# language: Select another language file.
# machine: The type of machine DOSBox tries to emulate.
# Possible values: hercules, cga, cga_mono, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe.
# captures: Directory where things like wave, midi, screenshot get captured.
# memsize: Amount of memory DOSBox has in megabytes.
# This value is best left at its default to avoid problems with some games,
# though few games might require a higher value.
# There is generally no speed advantage when raising this value.
# vmemsize: Video memory in MiB (1-8) or KiB (256 to 8192). 'auto' uses the default per video adapter.
# Possible values: auto, 1, 2, 4, 8, 256, 512, 1024, 2048, 4096, 8192.
# vesa_modes: Controls the selection of VESA 1.2 and 2.0 modes offered:
# compatible A tailored selection that maximizes game compatibility.
# This is recommended along with 4 or 8 MB of video memory.
# all Offers all modes for a given video memory size, however
# some games may not use them properly (flickering) or may need
# more system memory (mem = ) to use them.
# Possible values: compatible, all.
# autoexec_section: How autoexec sections are handled from multiple config files.
# join : combines them into one big section (legacy behavior).
# overwrite : use the last one encountered, like other conf settings.
# Possible values: join, overwrite.
# startup_verbosity: Controls verbosity prior to displaying the program:
# Verbosity | Splash | Welcome | Early stdout
# high | yes | yes | yes
# medium | no | yes | yes
# low | no | no | yes
# quiet | no | no | no
# splash_only | yes | no | no
# auto | 'low' if exec or dir is passed, otherwise 'high'
# Possible values: auto, high, medium, low, splash_only, quiet.
language =
machine = svga_s3
captures = capture
memsize = 16
vmemsize = auto
vesa_modes = compatible
autoexec_section = join
startup_verbosity = auto
[render]
# frameskip: How many frames DOSBox skips before drawing one.
# aspect: Scales the vertical resolution to produce a 4:3 display aspect
# ratio, matching that of the original standard-definition monitors
# for which the majority of DOS games were designed. This setting
# only affects video modes that use non-square pixels, such as
# 320x200 or 640x400; where as square-pixel modes, such as 640x480
# and 800x600, will be displayed as-is.
# monochrome_palette: Select default palette for monochrome display.
# Works only when emulating hercules or cga_mono.
# You can also cycle through available colours using F11.
# Possible values: white, paperwhite, green, amber.
# scaler: Scaler used to enlarge/enhance low resolution modes.
# If 'forced' is appended, then the scaler will be used even if
# the result might not be desired.
# Note that some scalers may use black borders to fit the image
# within your configured display resolution. If this is
# undesirable, try either a different scaler or enabling
# fullresolution output.
# Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x.
# glshader: Either 'none' or a GLSL shader name. Works only with
# OpenGL output. Can be either an absolute path, a file
# in the 'glshaders' subdirectory of the DOSBox
# configuration directory, or one of the built-in shaders:
# advinterp2x, advinterp3x, advmame2x, advmame3x,
# crt-easymode-flat, crt-fakelottes-flat, rgb2x, rgb3x,
# scan2x, scan3x, tv2x, tv3x, sharp (default).
frameskip = 0
aspect = true
monochrome_palette = white
scaler = none
glshader = default
[composite]
# composite: Enable composite mode on start. 'auto' lets the program decide.
# Note: Fine-tune the settings below (ie: hue) using the composite hotkeys.
# Then read the new settings from your console and enter them here.
# Possible values: auto, on, off.
# era: Era of composite technology. When 'auto', PCjr uses new and CGA/Tandy use old.
# Possible values: auto, old, new.
# hue: Appearance of RGB palette. For example, adjust until sky is blue.
# saturation: Intensity of colors, from washed out to vivid.
# contrast: Ratio between the dark and light area.
# brightness: Luminosity of the image, from dark to light.
# convergence: Convergence of subpixel elements, from blurry to sharp (CGA and Tandy-only).
composite = auto
era = auto
hue = 0
saturation = 100
contrast = 100
brightness = 0
convergence = 0
[cpu]
# core: CPU Core used in emulation. auto will switch to dynamic if available and
# appropriate.
# Possible values: auto, dynamic, normal, simple.
# cputype: CPU Type used in emulation. auto is the fastest choice.
# Possible values: auto, 386, 386_slow, 486_slow, pentium_slow, 386_prefetch.
# cycles: Number of instructions DOSBox tries to emulate each millisecond.
# Setting this value too high results in sound dropouts and lags.
# Cycles can be set in 3 ways:
# 'auto' tries to guess what a game needs.
# It usually works, but can fail for certain games.
# 'fixed #number' will set a fixed number of cycles. This is what you usually
# need if 'auto' fails (Example: fixed 4000).
# 'max' will allocate as much cycles as your computer is able to
# handle.
# Possible values: auto, fixed, max.
# cycleup: Number of cycles added or subtracted with speed control hotkeys.
# Run INTRO and see Special Keys for list of hotkeys.
# cycledown: Setting it lower than 100 will be a percentage.
core = auto
cputype = auto
cycles = auto
cycleup = 10
cycledown = 20
[mixer]
# nosound: Enable silent mode, sound is still emulated though.
# rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.
# Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.
# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.
# Possible values: 1024, 2048, 4096, 8192, 512, 256, 128.
# prebuffer: How many milliseconds of data to keep on top of the blocksize.
# negotiate: Allow system audio driver to negotiate optimal rate and blocksize
# as close to the specified values as possible.
nosound = false
rate = 48000
blocksize = 512
prebuffer = 20
negotiate = true
[midi]
# mididevice: Device that will receive the MIDI data (from the emulated MIDI
# interface - MPU-401). Choose one of the following:
# 'fluidsynth', to use the built-in MIDI synthesizer. See the
# [fluidsynth] section for detailed configuration.
# 'mt32', to use the built-in Roland MT-32 synthesizer.
# See the [mt32] section for detailed configuration.
# 'auto', to use the first working external MIDI player. This
# might be a software synthesizer or physical device.
# Possible values: auto, oss, alsa, fluidsynth, mt32, none.
# midiconfig: Configuration options for the selected MIDI interface.
# This is usually the id or name of the MIDI synthesizer you want
# to use (find the id/name with DOS command 'mixer /listmidi').
# - This option has no effect when using the built-in synthesizers
# (mididevice = fluidsynth or mt32).
# - When using ALSA, use Linux command 'aconnect -l' to list open
# MIDI ports, and select one (for example 'midiconfig=14:0'
# for sequencer client 14, port 0).
# - If you're using a physical Roland MT-32 with revision 0 PCB,
# the hardware may require a delay in order to prevent its
# buffer from overflowing. In that case, add 'delaysysex',
# for example: 'midiconfig=2 delaysysex'.
# See the README/Manual for more details.
# mpu401: Type of MPU-401 to emulate.
# Possible values: intelligent, uart, none.
mididevice = auto
midiconfig =
mpu401 = intelligent
[fluidsynth]
# soundfont: Path to a SoundFont file in .sf2 format. You can use an
# absolute or relative path, or the name of an .sf2 inside
# the 'soundfonts' directory within your DOSBox configuration
# directory.
# An optional percentage will scale the SoundFont's volume.
# For example: 'soundfont.sf2 50' will attenuate it by 50 percent.
# The scaling percentage can range from 1 to 500.
# chorus: Chorus effect: 'auto', 'on', 'off', or custom values.
# When using custom values:
# All five must be provided in-order and space-separated.
# They are: voice-count level speed depth modulation-wave, where:
# - voice-count is an integer from 0 to 99.
# - level is a decimal from 0.0 to 10.0
# - speed is a decimal, measured in Hz, from 0.1 to 5.0
# - depth is a decimal from 0.0 to 21.0
# - modulation-wave is either 'sine' or 'triangle'
# For example: chorus = 3 1.2 0.3 8.0 sine
# reverb: Reverb effect: 'auto', 'on', 'off', or custom values.
# When using custom values:
# All four must be provided in-order and space-separated.
# They are: room-size damping width level, where:
# - room-size is a decimal from 0.0 to 1.0
# - damping is a decimal from 0.0 to 1.0
# - width is a decimal from 0.0 to 100.0
# - level is a decimal from 0.0 to 1.0
# For example: reverb = 0.61 0.23 0.76 0.56
soundfont = default.sf2
chorus = auto
reverb = auto
[mt32]
# model: Model of synthesizer to use.
# 'auto' picks the first model with available ROMs, in order as listed.
# 'cm32l' and 'mt32' pick the first model of their type, in the order listed.
# 'mt32_old' and 'mt32_new' are aliases for 1.07 and 2.04, respectively.
# Possible values: auto, cm32l, cm32l_102, cm32l_100, mt32, mt32_old, mt32_107, mt32_106, mt32_105, mt32_104, mt32_bluer, mt32_new, mt32_204.
# romdir: The directory containing ROMs for one or more models.
# The directory can be absolute or relative, or leave it blank to
# use the 'mt32-roms' directory in your DOSBox configuration
# directory. Other common system locations will be checked as well.
# ROM files inside this directory may include any of the following:
# - MT32_CONTROL.ROM and MT32_PCM.ROM, for the 'mt32' model.
# - CM32L_CONTROL.ROM and CM32L_PCM.ROM, for the 'cm32l' model.
# - Unzipped MAME MT-32 and CM-32L ROMs, for the versioned models.
model = auto
romdir =
[sblaster]
# sbtype: Type of Sound Blaster to emulate. 'gb' is Game Blaster.
# Possible values: sb1, sb2, sbpro1, sbpro2, sb16, gb, none.
# sbbase: The IO address of the Sound Blaster.
# Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, 300.
# irq: The IRQ number of the Sound Blaster.
# Possible values: 7, 5, 3, 9, 10, 11, 12.
# dma: The DMA number of the Sound Blaster.
# Possible values: 1, 5, 0, 3, 6, 7.
# hdma: The High DMA number of the Sound Blaster.
# Possible values: 1, 5, 0, 3, 6, 7.
# sbmixer: Allow the Sound Blaster mixer to modify the DOSBox mixer.
# oplmode: Type of OPL emulation. On 'auto' the mode is determined by 'sbtype'.
# All OPL modes are AdLib-compatible, except for 'cms'.
# Possible values: auto, cms, opl2, dualopl2, opl3, opl3gold, none.
# oplemu: Provider for the OPL emulation. 'compat' provides better quality,
# 'nuked' is the default and most accurate (but the most CPU-intensive).
# Possible values: default, compat, fast, mame, nuked.
sbtype = sb16
sbbase = 220
irq = 7
dma = 1
hdma = 5
sbmixer = true
oplmode = auto
oplemu = default
[gus]
# gus: Enable Gravis UltraSound emulation.
# gusbase: The IO base address of the Gravis UltraSound.
# Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.
# gusirq: The IRQ number of the Gravis UltraSound.
# Possible values: 5, 3, 7, 9, 10, 11, 12.
# gusdma: The DMA channel of the Gravis UltraSound.
# Possible values: 3, 0, 1, 5, 6, 7.
# ultradir: Path to UltraSound directory. In this directory
# there should be a MIDI directory that contains
# the patch files for GUS playback. Patch sets used
# with Timidity should work fine.
gus = false
gusbase = 240
gusirq = 5
gusdma = 3
ultradir = C:\ULTRASND
[innovation]
# sidmodel: Model of chip to emulate in the Innovation SSI-2001 card:
# - auto: Selects the 6581 chip.
# - 6581: The original chip, known for its bassy and rich character.
# - 8580: A later revision that more closely matched the SID specification.
# It fixed the 6581's DC bias and is less prone to distortion.
# The 8580 is an option on reproduction cards, like the DuoSID.
# - none: Disables the card.
# Possible values: auto, 6581, 8580, none.
# sidclock: The SID chip's clock frequency, which is jumperable on reproduction cards.
# - default: uses 0.895 MHz, per the original SSI-2001 card.
# - c64ntsc: uses 1.023 MHz, per NTSC Commodore PCs and the DuoSID.
# - c64pal: uses 0.985 MHz, per PAL Commodore PCs and the DuoSID.
# - hardsid: uses 1.000 MHz, available on the DuoSID.
# Possible values: default, c64ntsc, c64pal, hardsid.
# sidport: The IO port address of the Innovation SSI-2001.
# Possible values: 240, 260, 280, 2a0, 2c0.
# 6581filter: The SID's analog filtering meant that each chip was physically unique.
# Adjusts the 6581's filtering strength as a percent from 0 to 100.
# 8580filter: Adjusts the 8580's filtering strength as a percent from 0 to 100.
sidmodel = none
sidclock = default
sidport = 280
6581filter = 50
8580filter = 50
[speaker]
# pcspeaker: Enable PC-Speaker emulation.
# pcrate: Sample rate of the PC-Speaker sound generation.
# zero_offset: Neutralizes and prevents the PC speaker's DC-offset from harming other sources.
# 'auto' enables this for non-Windows systems and disables it on Windows.
# If your OS performs its own DC-offset correction, then set this to 'false'.
# Possible values: auto, true, false.
# tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.
# Possible values: auto, on, off.
# tandyrate: Sample rate of the Tandy 3-Voice generation.
# Possible values: 44100, 48000, 32000, 22050, 16000, 11025, 8000, 49716.
# disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).
# ps1audio: Enable IBM PS/1 Audio emulation.
pcspeaker = true
pcrate = 18939
zero_offset = auto
tandy = auto
tandyrate = 44100
disney = true
ps1audio = false
[joystick]
# joysticktype: Type of joystick to emulate: auto (default),
# auto : Detect and use any joystick(s), if possible.,
# 2axis : Support up to two joysticks.
# 4axis : Support the first joystick only.
# 4axis_2 : Support the second joystick only.
# fcs : Support a Thrustmaster-type joystick.
# ch : Support a CH Flightstick-type joystick.
# hidden : Prevent DOS from seeing the joystick(s), but enable them for mapping.
# disabled : Fully disable joysticks: won't be polled, mapped, or visible in DOS.
# (Remember to reset DOSBox's mapperfile if you saved it earlier)
# Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, hidden, disabled.
# timed: enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).
# autofire: continuously fires as long as you keep the button pressed.
# swap34: swap the 3rd and the 4th axis. Can be useful for certain joysticks.
# buttonwrap: enable button wrapping at the number of emulated buttons.
# circularinput: enable translation of circular input to square output.
# Try enabling this if your left analog stick can only move in a circle.
# deadzone: the percentage of motion to ignore. 100 turns the stick into a digital one.
joysticktype = auto
timed = true
autofire = false
swap34 = false
buttonwrap = false
circularinput = false
deadzone = 10
[serial]
# serial1: set type of device connected to com port.
# Can be disabled, dummy, modem, nullmodem, directserial.
# Additional parameters must be in the same line in the form of
# parameter:value. Parameter for all types is irq (optional).
# for directserial: realport (required), rxdelay (optional).
# (realport:COM1 realport:ttyS0).
# for modem: listenport (optional).
# for nullmodem: server, rxdelay, txdelay, telnet, usedtr,
# transparent, port, inhsocket (all optional).
# Example: serial1=modem listenport:5000
# Possible values: dummy, disabled, modem, nullmodem, directserial.
# serial2: see serial1
# Possible values: dummy, disabled, modem, nullmodem, directserial.
# serial3: see serial1
# Possible values: dummy, disabled, modem, nullmodem, directserial.
# serial4: see serial1
# Possible values: dummy, disabled, modem, nullmodem, directserial.
# phonebookfile: File used to map fake phone numbers to addresses.
serial1 = modem listenport:8192
serial2 = dummy
serial3 = disabled
serial4 = disabled
phonebookfile = phonebook.txt
[dos]
# xms: Enable XMS support.
# ems: Enable EMS support. The default (=true) provides the best
# compatibility but certain applications may run better with
# other choices, or require EMS support to be disabled (=false)
# to work at all.
# Possible values: true, emsboard, emm386, false.
# umb: Enable UMB support.
# ver: Set DOS version (5.0 by default). Specify as major.minor format.
# A single number is treated as the major version.
# Common settings are 3.3, 5.0, 6.22, and 7.1.
# keyboardlayout: Language code of the keyboard layout (or none).
xms = true
ems = true
umb = true
ver = 5.0
keyboardlayout = auto
[ipx]
# ipx: Enable ipx over UDP/IP emulation.
ipx = false
[autoexec]
mount c /home/scott/dos
c:
autoexec.bat

2
client/test.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/bash
${HOME}/code/dosbox-custom/dosbox-staging/build/dosbox -noprimaryconf -nolocalconf -conf test.conf &

View file

@ -20,12 +20,17 @@ TEMPLATE = app
CONFIG -= qt
DESTDIR = $$OUT_PWD/bin
SHARED = $$PWD/../shared
INCLUDEPATH += \
$$SHARED \
$$SHARED/thirdparty
HEADERS = \
src/stb_image.h \
src/stb_leakcheck.h \
src/stb.h
$$SHARED/stddclmr.h \
$$SHARED/thirdparty/memwatch/memwatch.h \
$$SHARED/thirdparty/stb_image.h
SOURCES = \
src/stb.c \
$$SHARED/thirdparty/memwatch/memwatch.c \
src/main.c

View file

@ -20,7 +20,14 @@
#include <stdio.h>
#include "stb.h"
#define MEMWATCH
#include "memwatch/memwatch.h"
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "stb_image.h"
#include "stddclmr.h"
void makeFont(char *source, char *target, int pixelsW, int pixelsH, int charsW, int charCount) {
@ -79,8 +86,5 @@ int main(int argc, char *argv[]) {
makeFont("/home/scott/code/kpmpgsmkii/font/data/vga8x14.png", "/home/scott/code/kpmpgsmkii/client/bin/vga8x14.dat", 8, 14, 16, 255);
makeFont("/home/scott/code/kpmpgsmkii/font/data/vga8x16.png", "/home/scott/code/kpmpgsmkii/client/bin/vga8x16.dat", 8, 16, 16, 255);
// Prove we cleaned up.
stb_leakcheck_dumpmem();
return 0;
}

View file

@ -1,26 +0,0 @@
/*
* Kangaroo Punch MultiPlayer Game Server Mark II
* Copyright (C) 2020-2021 Scott Duensing
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "stb_image.h"
#define STB_LEAKCHECK_IMPLEMENTATION
#include "stb_leakcheck.h"

File diff suppressed because it is too large Load diff

View file

@ -1,194 +0,0 @@
// stb_leakcheck.h - v0.6 - quick & dirty malloc leak-checking - public domain
// LICENSE
//
// See end of file.
#ifdef STB_LEAKCHECK_IMPLEMENTATION
#undef STB_LEAKCHECK_IMPLEMENTATION // don't implement more than once
// if we've already included leakcheck before, undefine the macros
#ifdef malloc
#undef malloc
#undef free
#undef realloc
#endif
#ifndef STB_LEAKCHECK_OUTPUT_PIPE
#define STB_LEAKCHECK_OUTPUT_PIPE stdout
#endif
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
typedef struct malloc_info stb_leakcheck_malloc_info;
struct malloc_info
{
const char *file;
int line;
size_t size;
stb_leakcheck_malloc_info *next,*prev;
};
static stb_leakcheck_malloc_info *mi_head;
void *stb_leakcheck_malloc(size_t sz, const char *file, int line)
{
stb_leakcheck_malloc_info *mi = (stb_leakcheck_malloc_info *) malloc(sz + sizeof(*mi));
if (mi == NULL) return mi;
mi->file = file;
mi->line = line;
mi->next = mi_head;
if (mi_head)
mi->next->prev = mi;
mi->prev = NULL;
mi->size = (int) sz;
mi_head = mi;
return mi+1;
}
void stb_leakcheck_free(void *ptr)
{
if (ptr != NULL) {
stb_leakcheck_malloc_info *mi = (stb_leakcheck_malloc_info *) ptr - 1;
mi->size = ~mi->size;
#ifndef STB_LEAKCHECK_SHOWALL
if (mi->prev == NULL) {
assert(mi_head == mi);
mi_head = mi->next;
} else
mi->prev->next = mi->next;
if (mi->next)
mi->next->prev = mi->prev;
free(mi);
#endif
}
}
void *stb_leakcheck_realloc(void *ptr, size_t sz, const char *file, int line)
{
if (ptr == NULL) {
return stb_leakcheck_malloc(sz, file, line);
} else if (sz == 0) {
stb_leakcheck_free(ptr);
return NULL;
} else {
stb_leakcheck_malloc_info *mi = (stb_leakcheck_malloc_info *) ptr - 1;
if (sz <= mi->size)
return ptr;
else {
#ifdef STB_LEAKCHECK_REALLOC_PRESERVE_MALLOC_FILELINE
void *q = stb_leakcheck_malloc(sz, mi->file, mi->line);
#else
void *q = stb_leakcheck_malloc(sz, file, line);
#endif
if (q) {
memcpy(q, ptr, mi->size);
stb_leakcheck_free(ptr);
}
return q;
}
}
}
static void stblkck_internal_print(const char *reason, stb_leakcheck_malloc_info *mi)
{
#if defined(_MSC_VER) && _MSC_VER < 1900 // 1900=VS 2015
// Compilers that use the old MS C runtime library don't have %zd
// and the older ones don't even have %lld either... however, the old compilers
// without "long long" don't support 64-bit targets either, so here's the
// compromise:
#if _MSC_VER < 1400 // before VS 2005
fprintf(STB_LEAKCHECK_OUTPUT_PIPE, "%s: %s (%4d): %8d bytes at %p\n", reason, mi->file, mi->line, (int)mi->size, (void*)(mi+1));
#else
fprintf(STB_LEAKCHECK_OUTPUT_PIPE, "%s: %s (%4d): %16lld bytes at %p\n", reason, mi->file, mi->line, (long long)mi->size, (void*)(mi+1));
#endif
#else
// Assume we have %zd on other targets.
#ifdef __MINGW32__
__mingw_fprintf(STB_LEAKCHECK_OUTPUT_PIPE, "%s: %s (%4d): %zd bytes at %p\n", reason, mi->file, mi->line, mi->size, (void*)(mi+1));
#else
fprintf(STB_LEAKCHECK_OUTPUT_PIPE, "%s: %s (%4d): %zd bytes at %p\n", reason, mi->file, mi->line, mi->size, (void*)(mi+1));
#endif
#endif
}
void stb_leakcheck_dumpmem(void)
{
stb_leakcheck_malloc_info *mi = mi_head;
while (mi) {
if ((ptrdiff_t) mi->size >= 0)
stblkck_internal_print("LEAKED", mi);
mi = mi->next;
}
#ifdef STB_LEAKCHECK_SHOWALL
mi = mi_head;
while (mi) {
if ((ptrdiff_t) mi->size < 0)
stblkck_internal_print("FREED ", mi);
mi = mi->next;
}
#endif
}
#endif // STB_LEAKCHECK_IMPLEMENTATION
#if !defined(INCLUDE_STB_LEAKCHECK_H) || !defined(malloc)
#define INCLUDE_STB_LEAKCHECK_H
#include <stdlib.h> // we want to define the macros *after* stdlib to avoid a slew of errors
#define malloc(sz) stb_leakcheck_malloc(sz, __FILE__, __LINE__)
#define free(p) stb_leakcheck_free(p)
#define realloc(p,sz) stb_leakcheck_realloc(p,sz, __FILE__, __LINE__)
extern void * stb_leakcheck_malloc(size_t sz, const char *file, int line);
extern void * stb_leakcheck_realloc(void *ptr, size_t sz, const char *file, int line);
extern void stb_leakcheck_free(void *ptr);
extern void stb_leakcheck_dumpmem(void);
#endif // INCLUDE_STB_LEAKCHECK_H
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/

16
shared/thirdparty/enet/.editorconfig vendored Normal file
View file

@ -0,0 +1,16 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Set default charset
charset = utf-8
# 4 space indentation
indent_style = space
indent_size = 4

3
shared/thirdparty/enet/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
build/
node_modules/
.DS_store

25
shared/thirdparty/enet/.travis.yml vendored Normal file
View file

@ -0,0 +1,25 @@
os:
- linux
- osx
language: c
compiler:
- clang
script:
- cmake . -DCMAKE_BUILD_TYPE=Release -DENET_TEST=1 -DENET_SHARED=1
- cmake --build .
- ./enet_test
before_deploy:
- export FILE_TO_UPLOAD=$(ls *.dylib *.so)
deploy:
provider: releases
api_key:
- secure: "VZPCmJqX/MOBJv/k498MIrpKC7SBx+ZYqpOxo1Vp2dO3W8PzChCMePsuCdYL5ZvxLqNv9iClQ778HHQ8X976C7lIBv01p6jf/BBrvp8WguagYRIqQ+6Ehe3l1/I+6Yxx7MnzMZTTCO/EOUbVlfwF4Gql5ybvgH9Vs0CKr00jUaDPCI8pc0rV2WW97qFQ5irfFcvJx7XxuT7V48Ur27y+gkqV+L4YZthjwqN9fC5jULl2ha/WY5tRjv5gjpLpLPvBW94x3L8qET7/izP0g1MrjlPODwh6pr7o6I2SAlURREadgHdovLDm7K7N+DBVT0hZCWXlJ/Sh7Q9gs3CCAxtMyLDSoGjpWHBvRvJw702OtRxyIWriESq80kB8KUQ/piHB4DPMfDpkuWUaSNElX85NyW3fh5aXxlOvQf+CtABNACIuLC/oBshFguFgEu4kuqpFtmUG7EBssrEwnCiw2H3xpMC3G+ALEA03UKYJEZcyrmFo9PwIfaNf9ziJLzqq3haAN1/4pNyvl62MMPtNDyzXzVTWyL/Yi22tDIDgMGwCYpAyNoKHiyPpVGbOkL4561SN947g2TpIfxi6LlxzdLV6fPoPlLBsaha6LXV+YLNWsgpOJYK0zk8dxKNDzGxniSiPAaeEWhbc11UGJYgpk21ySus/lQfsQobEK/EqwOM5mpU="
file_glob: true
file: "${FILE_TO_UPLOAD}"
skip_cleanup: true
on:
tags: true

43
shared/thirdparty/enet/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.0)
project(enet C)
# defaults
set(ENET_STATIC ON)
set(ENET_SHARED OFF)
set(ENET_TEST OFF)
# configure projects
if (ENET_STATIC)
add_library(enet STATIC test/library.c)
if (WIN32)
target_link_libraries(enet PUBLIC winmm ws2_32)
endif()
endif()
if (ENET_SHARED)
target_compile_definitions(enet PUBLIC -DENET_DLL)
add_library(enet SHARED test/library.c)
if (WIN32)
target_link_libraries(enet PUBLIC winmm ws2_32)
endif()
endif()
if (ENET_TEST)
add_executable(enet_test test/build.c)
target_include_directories(enet_test PRIVATE ${PROJECT_SOURCE_DIR}/include)
if (WIN32)
target_link_libraries(enet_test PUBLIC winmm ws2_32)
endif()
endif()
if(MSVC)
target_compile_options(enet PRIVATE -W3)
else()
target_compile_options(enet PRIVATE -Wno-error)
endif()
target_include_directories(enet PUBLIC ${PROJECT_SOURCE_DIR}/include)

22
shared/thirdparty/enet/LICENSE vendored Normal file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2002-2016 Lee Salzman
Copyright (c) 2017-2021 Vladyslav Hrytsenko, Dominik Madarász
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

299
shared/thirdparty/enet/README.md vendored Normal file
View file

@ -0,0 +1,299 @@
<div align="center">
<a href="https://github.com/zpl-c/enet"><img src="https://user-images.githubusercontent.com/2182108/33219675-6150f8a8-d14c-11e7-9081-a9be1945bfb1.png" alt="ENet" /></a>
</div>
<br>
<div align="center">
<a href="https://travis-ci.org/zpl-c/enet"><img src="https://travis-ci.org/zpl-c/enet.svg" alt="Build status" /></a>
<a href="https://ci.appveyor.com/project/inlife/enet"><img src="https://ci.appveyor.com/api/projects/status/0mkwad2yljdlq3c6?svg=true" alt="Build status" /></a>
<a href="https://www.npmjs.com/package/enet.c"><img src="https://img.shields.io/npm/v/enet.c.svg?maxAge=3600" alt="NPM version" /></a>
<a href="https://discord.gg/2fZVEym"><img src="https://discordapp.com/api/guilds/354670964400848898/embed.png" alt="Discord server" /></a>
<a href="LICENSE"><img src="https://img.shields.io/github/license/zpl-c/enet.svg" alt="license" /></a>
</div>
<br style="line-height: 10px" />
<div align="center">
ENet - Simple, lightweight and reliable UDP networking library written on pure C
</div>
<div align="center">
<sub>
Brought to you by
<a href="https://github.com/lsalzman">@lsalzman</a>,
<a href="https://github.com/inlife">@inlife</a>,
<a href="https://github.com/zaklaus">@zaklaus</a>,
<a href="https://github.com/nxrighthere">@nxrighthere</a>
and other contributors!
</sub>
</div>
<hr/>
## Disclaimer
This is a fork of the original library [lsalzman/enet](https://github.com/lsalzman/enet). While original repo offers a stable, time-tested wonderful library,
we are trying to change some things, things, which can't be reflected on the main repo, like:
* integrated ipv6 support
* added monotonic time
* applied project-wide code style change
* cleaned up project
* single-header style code
* NPM package distribution
* removed a lot of older methods
* and many other various changes
## Description
ENet's purpose is to provide a relatively thin, simple and robust network communication
layer on top of UDP (User Datagram Protocol). The primary feature it provides is optional
reliable, in-order delivery of packets, and fragmentation.
ENet omits certain higher level networking features such as authentication, lobbying,
server discovery, encryption, or other similar tasks that are particularly application
specific so that the library remains flexible, portable, and easily embeddable.
## Installation (via npm)
Install library using (omit `--save` if you don't have npm project initilized)
```sh
$ npm install enet.c --save
```
Add include path to the library `node_modules/enet.c/include` to your makefile/
## Installation (manually)
Download file [include/enet.h](https://raw.githubusercontent.com/zpl-c/enet/master/include/enet.h) and just add to your project.
## Usage (Shared library)
Build the shared library:
```sh
$ mkdir build
$ cd build
$ cmake .. -DENET_SHARED=1 -DCMAKE_BUILD_TYPE=Release
$ cmake --build .
```
Use it:
```c
#define ENET_DLL
#include <enet.h>
#include <stdio.h>
int main() {
if (enet_initialize () != 0) {
printf("An error occurred while initializing ENet.\n");
return 1;
}
enet_deinitialize();
return 0;
}
```
## Usage (Static library)
Build the static library:
```sh
$ mkdir build
$ cd build
$ cmake .. -DENET_STATIC=1 -DCMAKE_BUILD_TYPE=Release
$ cmake --build .
```
Use it:
```c
#include <enet.h>
#include <stdio.h>
int main() {
if (enet_initialize () != 0) {
printf("An error occurred while initializing ENet.\n");
return 1;
}
enet_deinitialize();
return 0;
}
```
## Usage (Direct, Preferred)
In this case, library will be embedded to the project itself.
Make sure you add a define for `ENET_IMPLEMENTATION` exactly in one source file before including the `enet.h`.
Here is a simple server and client demo, it will wait 1 second for events, and then exit if none were found:
Server:
```c
#define ENET_IMPLEMENTATION
#include <enet.h>
#include <stdio.h>
int main() {
if (enet_initialize () != 0) {
printf("An error occurred while initializing ENet.\n");
return 1;
}
ENetAddress address = {0};
address.host = ENET_HOST_ANY; /* Bind the server to the default localhost. */
address.port = 7777; /* Bind the server to port 7777. */
#define MAX_CLIENTS 32
/* create a server */
ENetHost * server = enet_host_create(&address, MAX_CLIENTS, 2, 0, 0);
if (server == NULL) {
printf("An error occurred while trying to create an ENet server host.\n");
return 1;
}
printf("Started a server...\n");
ENetEvent event;
/* Wait up to 1000 milliseconds for an event. (WARNING: blocking) */
while (enet_host_service(server, &event, 1000) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT:
printf("A new client connected from %x:%u.\n", event.peer->address.host, event.peer->address.port);
/* Store any relevant client information here. */
event.peer->data = "Client information";
break;
case ENET_EVENT_TYPE_RECEIVE:
printf("A packet of length %lu containing %s was received from %s on channel %u.\n",
event.packet->dataLength,
event.packet->data,
event.peer->data,
event.channelID);
/* Clean up the packet now that we're done using it. */
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
printf("%s disconnected.\n", event.peer->data);
/* Reset the peer's client information. */
event.peer->data = NULL;
break;
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
printf("%s disconnected due to timeout.\n", event.peer->data);
/* Reset the peer's client information. */
event.peer->data = NULL;
break;
case ENET_EVENT_TYPE_NONE:
break;
}
}
enet_host_destroy(server);
enet_deinitialize();
return 0;
}
```
Client:
```c
#include <stdio.h>
#define ENET_IMPLEMENTATION
#include "enet.h"
int main() {
if (enet_initialize() != 0) {
fprintf(stderr, "An error occurred while initializing ENet.\n");
return EXIT_FAILURE;
}
ENetHost* client = { 0 };
client = enet_host_create(NULL /* create a client host */,
1 /* only allow 1 outgoing connection */,
2 /* allow up 2 channels to be used, 0 and 1 */,
0 /* assume any amount of incoming bandwidth */,
0 /* assume any amount of outgoing bandwidth */);
if (client == NULL) {
fprintf(stderr,
"An error occurred while trying to create an ENet client host.\n");
exit(EXIT_FAILURE);
}
ENetAddress address = { 0 };
ENetEvent event = { 0 };
ENetPeer* peer = { 0 };
/* Connect to some.server.net:1234. */
enet_address_set_host(&address, "127.0.0.1");
address.port = 7777;
/* Initiate the connection, allocating the two channels 0 and 1. */
peer = enet_host_connect(client, &address, 2, 0);
if (peer == NULL) {
fprintf(stderr,
"No available peers for initiating an ENet connection.\n");
exit(EXIT_FAILURE);
}
/* Wait up to 5 seconds for the connection attempt to succeed. */
if (enet_host_service(client, &event, 5000) > 0 &&
event.type == ENET_EVENT_TYPE_CONNECT) {
puts("Connection to some.server.net:1234 succeeded.");
} else {
/* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */
enet_peer_reset(peer);
puts("Connection to some.server.net:1234 failed.");
}
// Receive some events
enet_host_service(client, &event, 5000);
// Disconnect
enet_peer_disconnect(peer, 0);
uint8_t disconnected = false;
/* Allow up to 3 seconds for the disconnect to succeed
* and drop any packets received packets.
*/
while (enet_host_service(client, &event, 3000) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_RECEIVE:
enet_packet_destroy(event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
puts("Disconnection succeeded.");
disconnected = true;
break;
}
}
// Drop connection, since disconnection didn't successed
if (!disconnected) {
enet_peer_reset(peer);
}
enet_host_destroy(client);
enet_deinitialize();
}
```
## Tutorials
More information, examples and tutorials can be found at the official site: http://enet.bespin.org/

30
shared/thirdparty/enet/appveyor.yml vendored Normal file
View file

@ -0,0 +1,30 @@
image: Visual Studio 2017
platform:
- x64
configuration:
- Release
before_build:
- cmake . -G "Visual Studio 15 2017 Win64" -DENET_SHARED=1 -DENET_TEST=1
build:
project: $(APPVEYOR_BUILD_FOLDER)\$(APPVEYOR_PROJECT_NAME).sln
test_script:
- '%APPVEYOR_BUILD_FOLDER%\%CONFIGURATION%\enet_test.exe'
artifacts:
- path: 'Release\*.dll'
name: Releases
deploy:
provider: GitHub
auth_token:
secure: "tYm5oXMHHaO3oR5xd93zvnG95eqNZWw065Z9Qo6CAN3+2G7IlWbcmbsYlsl2XDFc"
artifact: /.*\.dll/
draft: false
prerelease: false
on:
appveyor_repo_tag: true

6091
shared/thirdparty/enet/include/enet.h vendored Normal file

File diff suppressed because it is too large Load diff

194
shared/thirdparty/enet/misc/ChangeLog vendored Normal file
View file

@ -0,0 +1,194 @@
ENet 2.0.0 (April 22, 2018):
* changed library format to single header
* applied project-wide code style change
* integrated ipv6 changes from @proller
* changed packet creation to have one less malloc and free per packet. @boardwalk
* removed enet_packet_resize
* added timeout disconnect notification event @airtame
* added total packets sent and lost to enet_peer @airtame
* force a connect packet not to have extra bytes @pisto
* enforce mtu while receiving packets, and don't give up receiving if one too big comes through @pisto
* add metrics for total data send and received @airtame
* replaced exp backoff time for rel packet timeout with linear @airtame
* added monotonic time @airtame
* removed enet_time_set
* removed a lot of wide platform support code, might bring a lot of issues on older/non-standart platforms
* removed range coder compression code
ENet 1.3.13 (April 30, 2015):
* miscellaneous bug fixes
* added premake and cmake support
* miscellaneous documentation cleanups
ENet 1.3.12 (April 24, 2014):
* added maximumPacketSize and maximumWaitingData fields to ENetHost to limit the amount of
data waiting to be delivered on a peer (beware that the default maximumPacketSize is
32MB and should be set higher if desired as should maximumWaitingData)
ENet 1.3.11 (December 26, 2013):
* allow an ENetHost to connect to itself
* fixed possible bug with disconnect notifications during connect attempts
* fixed some preprocessor definition bugs
ENet 1.3.10 (October 23, 2013);
* doubled maximum reliable window size
* fixed RCVTIMEO/SNDTIMEO socket options and also added NODELAY
ENet 1.3.9 (August 19, 2013):
* added duplicatePeers option to ENetHost which can limit the number of peers from duplicate IPs
* added enet_socket_get_option() and ENET_SOCKOPT_ERROR
* added enet_host_random_seed() platform stub
ENet 1.3.8 (June 2, 2013):
* added enet_linked_version() for checking the linked version
* added enet_socket_get_address() for querying the local address of a socket
* silenced some debugging prints unless ENET_DEBUG is defined during compilation
* handle EINTR in enet_socket_wait() so that enet_host_service() doesn't propagate errors from signals
* optimized enet_host_bandwidth_throttle() to be less expensive for large numbers of peers
ENet 1.3.7 (March 6, 2013):
* added ENET_PACKET_FLAG_SENT to indicate that a packet is being freed because it has been sent
* added userData field to ENetPacket
* changed how random seed is generated on Windows to avoid import warnings
* fixed case where disconnects could be generated with no preceding connect event
ENet 1.3.6 (December 11, 2012):
* added support for intercept callback in ENetHost that can be used to process raw packets before ENet
* added enet_socket_shutdown() for issuing shutdown on a socket
* fixed enet_socket_connect() to not error on non-blocking connects
* fixed bug in MTU negotiation during connections
ENet 1.3.5 (July 31, 2012):
* fixed bug in unreliable packet fragment queuing
ENet 1.3.4 (May 29, 2012):
* added enet_peer_ping_interval() for configuring per-peer ping intervals
* added enet_peer_timeout() for configuring per-peer timeouts
* added protocol packet size limits
ENet 1.3.3 (June 28, 2011):
* fixed bug with simultaneous disconnects not dispatching events
ENet 1.3.2 (May 31, 2011):
* added support for unreliable packet fragmenting via the packet flag
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
* fixed regression in unreliable packet queuing
* added check against received port to limit some forms of IP-spoofing
ENet 1.3.1 (February 10, 2011):
* fixed bug in tracking of reliable data in transit
* reliable data window size now scales with the throttle
* fixed bug in fragment length calculation when checksums are used
ENet 1.3.0 (June 5, 2010):
* enet_host_create() now requires the channel limit to be specified as
a parameter
* enet_host_connect() now accepts a data parameter which is supplied
to the receiving receiving host in the event data field for a connect event
* added an adaptive order-2 PPM range coder as a built-in compressor option
which can be set with enet_host_compress_with_range_coder()
* added support for packet compression configurable with a callback
* improved session number handling to not rely on the packet checksum
field, saving 4 bytes per packet unless the checksum option is used
* removed the dependence on the rand callback for session number handling
Caveats: This version is not protocol compatible with the 1.2 series or
earlier. The enet_host_connect and enet_host_create API functions require
supplying additional parameters.
ENet 1.2.5 (June 28, 2011):
* fixed bug with simultaneous disconnects not dispatching events
ENet 1.2.4 (May 31, 2011):
* fixed regression in unreliable packet queuing
* added check against received port to limit some forms of IP-spoofing
ENet 1.2.3 (February 10, 2011):
* fixed bug in tracking reliable data in transit
ENet 1.2.2 (June 5, 2010):
* checksum functionality is now enabled by setting a checksum callback
inside ENetHost instead of being a configure script option
* added totalSentData, totalSentPackets, totalReceivedData, and
totalReceivedPackets counters inside ENetHost for getting usage
statistics
* added enet_host_channel_limit() for limiting the maximum number of
channels allowed by connected peers
* now uses dispatch queues for event dispatch rather than potentially
unscalable array walking
* added no_memory callback that is called when a malloc attempt fails,
such that if no_memory returns rather than aborts (the default behavior),
then the error is propagated to the return value of the API calls
* now uses packed attribute for protocol structures on platforms with
strange alignment rules
* improved autoconf build system contributed by Nathan Brink allowing
for easier building as a shared library
Caveats: If you were using the compile-time option that enabled checksums,
make sure to set the checksum callback inside ENetHost to enet_crc32 to
regain the old behavior. The ENetCallbacks structure has added new fields,
so make sure to clear the structure to zero before use if
using enet_initialize_with_callbacks().
ENet 1.2.1 (November 12, 2009):
* fixed bug that could cause disconnect events to be dropped
* added thin wrapper around select() for portable usage
* added ENET_SOCKOPT_REUSEADDR socket option
* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create()
* added contributed Code::Blocks build file
ENet 1.2 (February 12, 2008):
* fixed bug in VERIFY_CONNECT acknowledgement that could cause connect
attempts to occasionally timeout
* fixed acknowledgements to check both the outgoing and sent queues
when removing acknowledged packets
* fixed accidental bit rot in the MSVC project file
* revised sequence number overflow handling to address some possible
disconnect bugs
* added enet_host_check_events() for getting only local queued events
* factored out socket option setting into enet_socket_set_option() so
that socket options are now set separately from enet_socket_create()
Caveats: While this release is superficially protocol compatible with 1.1,
differences in the sequence number overflow handling can potentially cause
random disconnects.
ENet 1.1 (June 6, 2007):
* optional CRC32 just in case someone needs a stronger checksum than UDP
provides (--enable-crc32 configure option)
* the size of packet headers are half the size they used to be (so less
overhead when sending small packets)
* enet_peer_disconnect_later() that waits till all queued outgoing
packets get sent before issuing an actual disconnect
* freeCallback field in individual packets for notification of when a
packet is about to be freed
* ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a
packet (can be used in concert with freeCallback to support some custom
allocation schemes that the normal memory allocation callbacks would
normally not allow)
* enet_address_get_host_ip() for printing address numbers
* promoted the enet_socket_*() functions to be part of the API now
* a few stability/crash fixes

View file

@ -0,0 +1,24 @@
/**
@page FAQ Frequently Answered Questions
@section Q1 Is ENet thread-safe?
ENet does not use any significant global variables, the vast majority
of state is encapsulated in the ENetHost structure. As such, as long
as the application guards access to this structure, then ENet should
operate fine in a multi-threaded environment.
@section Q2 Isn't ENet just re-inventing TCP?! What's the point?
In a perfect world, that would be true. But as many have found, using
TCP either in lieu of or in conjunction with UDP can lead to all kinds
of nightmares. TCP is a good, solid protocol, however it simply isn't
up to the task of real-time games. Too much of TCP's implementation
dictates a policy that isn't practical for games. If you want to use
TCP, then do so -- this library is for people that either don't want
to use TCP or have tried and ended up being discouraged with the
performance.
*/

View file

@ -0,0 +1,126 @@
/**
@page Features Features and Architecture
ENet evolved specifically as a UDP networking layer for the
multiplayer first person shooter Cube. Cube necessitated low latency
communication with data sent out very frequently, so TCP was an
unsuitable choice due to its high latency and stream orientation. UDP,
however, lacks many sometimes necessary features from TCP such as
reliability, sequencing, unrestricted packet sizes, and connection
management. So UDP by itself was not suitable as a network protocol
either. No suitable freely available networking libraries existed at
the time of ENet's creation to fill this niche.
UDP and TCP could have been used together in Cube to benefit somewhat
from both of their features, however, the resulting combinations of
protocols still leaves much to be desired. TCP lacks multiple streams
of communication without resorting to opening many sockets and
complicates delineation of packets due to its buffering behavior. UDP
lacks sequencing, connection management, management of bandwidth
resources, and imposes limitations on the size of packets. A
significant investment is required to integrate these two protocols,
and the end result is worse off in features and performance than the
uniform protocol presented by ENet.
ENet thus attempts to address these issues and provide a single,
uniform protocol layered over UDP to the developer with the best
features of UDP and TCP as well as some useful features neither
provide, with a much cleaner integration than any resulting from a
mixture of UDP and TCP.
@section CM Connection Management
ENet provides a simple connection interface over which to communicate
with a foreign host. The liveness of the connection is actively
monitored by pinging the foreign host at frequent intervals, and also
monitors the network conditions from the local host to the foreign
host such as the mean round trip time and packet loss in this fashion.
@section Sequencing Sequencing
Rather than a single byte stream that complicates the delineation of
packets, ENet presents connections as multiple, properly sequenced
packet streams that simplify the transfer of various types of data.
ENet provides sequencing for all packets by assigning to each sent
packet a sequence number that is incremented as packets are sent. ENet
guarantees that no packet with a higher sequence number will be
delivered before a packet with a lower sequence number, thus ensuring
packets are delivered exactly in the order they are sent.
For unreliable packets, ENet will simply discard the lower sequence
number packet if a packet with a higher sequence number has already
been delivered. This allows the packets to be dispatched immediately
as they arrive, and reduce latency of unreliable packets to an
absolute minimum. For reliable packets, if a higher sequence number
packet arrives, but the preceding packets in the sequence have not yet
arrived, ENet will stall delivery of the higher sequence number
packets until its predecessors have arrived.
@section Channels Channels
Since ENet will stall delivery of reliable packets to ensure proper
sequencing, and consequently any packets of higher sequence number
whether reliable or unreliable, in the event the reliable packet's
predecessors have not yet arrived, this can introduce latency into the
delivery of other packets which may not need to be as strictly ordered
with respect to the packet that stalled their delivery.
To combat this latency and reduce the ordering restrictions on
packets, ENet provides multiple channels of communication over a given
connection. Each channel is independently sequenced, and so the
delivery status of a packet in one channel will not stall the delivery
of other packets in another channel.
@section Reliability Reliability
ENet provides optional reliability of packet delivery by ensuring the
foreign host acknowledges receipt of all reliable packets. ENet will
attempt to resend the packet up to a reasonable amount of times, if no
acknowledgement of the packet's receipt happens within a specified
timeout. Retry timeouts are progressive and become more lenient with
every failed attempt to allow for temporary turbulence in network
conditions.
@section FaR Fragmentation and Reassembly
ENet will send and deliver packets regardless of size. Large packets
are fragmented into many smaller packets of suitable size, and
reassembled on the foreign host to recover the original packet for
delivery. The process is entirely transparent to the developer.
@section Aggregation Aggregation
ENet aggregates all protocol commands, including acknowledgements and
packet transfer, into larger protocol packets to ensure the proper
utilization of the connection and to limit the opportunities for
packet loss that might otherwise result in further delivery latency.
@section Adaptability Adaptability
ENet provides an in-flight data window for reliable packets to ensure
connections are not overwhelmed by volumes of packets. It also
provides a static bandwidth allocation mechanism to ensure the total
volume of packets sent and received to a host don't exceed the host's
capabilities. Further, ENet also provides a dynamic throttle that
responds to deviations from normal network connections to rectify
various types of network congestion by further limiting the volume of
packets sent.
@section Portability Portability
ENet works on Windows and any other Unix or Unix-like platform
providing a BSD sockets interface. The library has a small and stable
code base that can easily be extended to support other platforms and
integrates easily. ENet makes no assumptions about the underlying
platform's endianess or word size.
@section Freedom Freedom
ENet demands no royalties and doesn't carry a viral license that would
restrict you in how you might use it in your programs. ENet is
licensed under a short-and-sweet MIT-style license, which gives you
the freedom to do anything you want with it (well, almost anything).
*/

View file

@ -0,0 +1,63 @@
/**
@page Installation Installation
ENet should be trivially simple to integrate with most applications.
First, make sure you download the latest source distribution at @ref Downloads.
@section Unix Unix-like Operating Systems
If you are using an ENet release, then you should simply be able to build it
by doing the following:
./configure && make && make install
If you obtained the package from github, you must have automake and autoconf
available to generate the build system first by doing the following command
before using the above mentioned build procedure:
autoreconf -vfi
@subsection SolarisBSD Solaris and BSD
When building ENet under Solaris, you must specify the -lsocket and
-lnsl parameters to your compiler to ensure that the sockets library
is linked in.
@section Windows Microsoft Windows
You may simply use the included "enet.lib" or "enet64.lib" static libraries.
However, if you wish to build the library yourself, then the following
instructions apply:
There is an included MSVC 6 project (enet.dsp) which you may use to
build a suitable library file. Alternatively, you may simply drag all
the ENet source files into your main project.
You will have to link to the Winsock2 libraries, so make sure to add
ws2_32.lib and winmm.lib to your library list (Project Settings | Link |
Object/library modules).
@subsection enet.dsp Building with the included enet.dsp
Load the included enet.dsp. MSVC may ask you to convert it if you
are on a newer version of MSVC - just allow the conversion and save
the resulting project as "enet" or similar. After you build this
project, it will output an "enet.lib" file to either the "Debug/"
or "Release/" directory, depending on which configuration you have
selected to build. By default, it should produce "Debug/enet.lib".
You may then copy the resulting "enet.lib" file and the header files
found in the "include/" directory to your other projects and add it to
their library lists. Make sure to also link against "ws2_32.lib" and
"winmm.lib" as described above.
@subsection DLL DLL
If you wish to build ENet as a DLL you must first define ENET_DLL
within the project (Project Settings | C/C++ | Preprocessor |
Preprocessor definitions) or, more invasively, simply define ENET_DLL
at the top of enet.h.
*/

View file

@ -0,0 +1,26 @@
/**
@page License License
Copyright (c) 2002-2016 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

View file

@ -0,0 +1,59 @@
/** @mainpage ENet
ENet's purpose is to provide a relatively thin, simple and robust
network communication layer on top of UDP (User Datagram Protocol).
The primary feature it provides is optional reliable, in-order
delivery of packets.
ENet omits certain higher level networking features such as authentication,
lobbying, server discovery, encryption, or other similar tasks that are
particularly application specific so that the library remains flexible,
portable, and easily embeddable.
@ref Features
@ref Downloads
@ref Installation
@ref Tutorial
@ref MailingList
@ref IRCChannel
@ref FAQ
@ref License
<a class="el" href="usergroup0.html">Documentation</a>
*/
/**
@page Downloads Downloads
You can retrieve the source to ENet by downloading it in either .tar.gz form
or accessing the github distribution directly.
The most recent stable release (1.3.13) can be downloaded <a class="el" href="download/enet-1.3.13.tar.gz">here</a>.
The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded <a class="el" href="download/enet-1.2.5.tar.gz">here</a>.
You can find the most recent ENet source at <a class="el" href="https://github.com/lsalzman/enet">the github repository</a>.
*/
/**
@page MailingList Mailing List
The <a class="el" href="http://lists.cubik.org/mailman/listinfo/enet-discuss">enet-discuss</a> list is for discussion of ENet, including bug reports or feature requests.
*/
/**
@page IRCChannel IRC Channel
Join the \#enet channel on the <a class="el" href="http://freenode.net">freenode IRC network (irc.freenode.net)</a> for real-time discussion about the ENet library.
*/

View file

@ -0,0 +1,366 @@
/**
@page Tutorial Tutorial
@ref Initialization
@ref CreateServer
@ref CreateClient
@ref ManageHost
@ref SendingPacket
@ref Disconnecting
@ref Connecting
@section Initialization Initialization
You should include the file <enet/enet.h> when using ENet. Do not
include <enet.h> without the directory prefix, as this may cause
file name conflicts on some systems.
Before using ENet, you must call enet_initialize() to initialize the
library. Upon program exit, you should call enet_deinitialize() so
that the library may clean up any used resources.
@code
#include <enet/enet.h>
int
main (int argc, char ** argv)
{
if (enet_initialize () != 0)
{
fprintf (stderr, "An error occurred while initializing ENet.\n");
return EXIT_FAILURE;
}
atexit (enet_deinitialize);
...
...
...
}
@endcode
@section CreateServer Creating an ENet server
Servers in ENet are constructed with enet_host_create(). You must
specify an address on which to receive data and new connections, as
well as the maximum allowable numbers of connected peers. You may
optionally specify the incoming and outgoing bandwidth of the server
in bytes per second so that ENet may try to statically manage
bandwidth resources among connected peers in addition to its dynamic
throttling algorithm; specifying 0 for these two options will cause
ENet to rely entirely upon its dynamic throttling algorithm to manage
bandwidth.
When done with a host, the host may be destroyed with
enet_host_destroy(). All connected peers to the host will be reset,
and the resources used by the host will be freed.
@code
ENetAddress address;
ENetHost * server;
/* Bind the server to the default localhost. */
/* A specific host address can be specified by */
/* enet_address_set_host (& address, "x.x.x.x"); */
address.host = ENET_HOST_ANY;
/* Bind the server to port 1234. */
address.port = 1234;
server = enet_host_create (& address /* the address to bind the server host to */,
32 /* allow up to 32 clients and/or outgoing connections */,
2 /* allow up to 2 channels to be used, 0 and 1 */,
0 /* assume any amount of incoming bandwidth */,
0 /* assume any amount of outgoing bandwidth */);
if (server == NULL)
{
fprintf (stderr,
"An error occurred while trying to create an ENet server host.\n");
exit (EXIT_FAILURE);
}
...
...
...
enet_host_destroy(server);
@endcode
@section CreateClient Creating an ENet client
Clients in ENet are similarly constructed with enet_host_create() when
no address is specified to bind the host to. Bandwidth may be
specified for the client host as in the above example. The peer count
controls the maximum number of connections to other server hosts that
may be simultaneously open.
@code
ENetHost * client;
client = enet_host_create (NULL /* create a client host */,
1 /* only allow 1 outgoing connection */,
2 /* allow up 2 channels to be used, 0 and 1 */,
57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
if (client == NULL)
{
fprintf (stderr,
"An error occurred while trying to create an ENet client host.\n");
exit (EXIT_FAILURE);
}
...
...
...
enet_host_destroy(client);
@endcode
@section ManageHost Managing an ENet host
ENet uses a polled event model to notify the programmer of significant
events. ENet hosts are polled for events with enet_host_service(),
where an optional timeout value in milliseconds may be specified to
control how long ENet will poll; if a timeout of 0 is specified,
enet_host_service() will return immediately if there are no events to
dispatch. enet_host_service() will return 1 if an event was dispatched
within the specified timeout.
Beware that most processing of the network with the ENet stack is done
inside enet_host_service(). Both hosts that make up the sides of a connection
must regularly call this function to ensure packets are actually sent and
received. A common symptom of not actively calling enet_host_service()
on both ends is that one side receives events while the other does not.
The best way to schedule this activity to ensure adequate service is, for
example, to call enet_host_service() with a 0 timeout (meaning non-blocking)
at the beginning of every frame in a game loop.
Currently there are only four types of significant events in ENet:
An event of type ENET_EVENT_TYPE_NONE is returned if no event occurred
within the specified time limit. enet_host_service() will return 0
with this event.
An event of type ENET_EVENT_TYPE_CONNECT is returned when either a new client
host has connected to the server host or when an attempt to establish a
connection with a foreign host has succeeded. Only the "peer" field of the
event structure is valid for this event and contains the newly connected peer.
An event of type ENET_EVENT_TYPE_RECEIVE is returned when a packet is received
from a connected peer. The "peer" field contains the peer the packet was
received from, "channelID" is the channel on which the packet was sent, and
"packet" is the packet that was sent. The packet contained in the "packet"
field must be destroyed with enet_packet_destroy() when you are done
inspecting its contents.
An event of type ENET_EVENT_TYPE_DISCONNECT is returned when a connected peer
has either explicitly disconnected or timed out. Only the "peer" field of the
event structure is valid for this event and contains the peer that
disconnected. Only the "data" field of the peer is still valid on a
disconnect event and must be explicitly reset.
@code
ENetEvent event;
/* Wait up to 1000 milliseconds for an event. */
while (enet_host_service (client, & event, 1000) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
printf ("A new client connected from %x:%u.\n",
event.peer -> address.host,
event.peer -> address.port);
/* Store any relevant client information here. */
event.peer -> data = "Client information";
break;
case ENET_EVENT_TYPE_RECEIVE:
printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
event.packet -> dataLength,
event.packet -> data,
event.peer -> data,
event.channelID);
/* Clean up the packet now that we're done using it. */
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
printf ("%s disconnected.\n", event.peer -> data);
/* Reset the peer's client information. */
event.peer -> data = NULL;
}
}
...
...
...
@endcode
@section SendingPacket Sending a packet to an ENet peer
Packets in ENet are created with enet_packet_create(), where the size
of the packet must be specified. Optionally, initial data may be
specified to copy into the packet.
Certain flags may also be supplied to enet_packet_create() to control
various packet features:
ENET_PACKET_FLAG_RELIABLE specifies that the packet must use reliable
delivery. A reliable packet is guaranteed to be delivered, and a
number of retry attempts will be made until an acknowledgement is
received from the foreign host the packet is sent to. If a certain
number of retry attempts is reached without any acknowledgement, ENet
will assume the peer has disconnected and forcefully reset the
connection. If this flag is not specified, the packet is assumed an
unreliable packet, and no retry attempts will be made nor
acknowledgements generated.
A packet may be resized (extended or truncated) with
enet_packet_resize().
A packet is sent to a foreign host with
enet_peer_send(). enet_peer_send() accepts a channel id over which to
send the packet to a given peer. Once the packet is handed over to
ENet with enet_peer_send(), ENet will handle its deallocation and
enet_packet_destroy() should not be used upon it.
One may also use enet_host_broadcast() to send a packet to all
connected peers on a given host over a specified channel id, as with
enet_peer_send().
Queued packets will be sent on a call to enet_host_service().
Alternatively, enet_host_flush() will send out queued packets without
dispatching any events.
@code
/* Create a reliable packet of size 7 containing "packet\0" */
ENetPacket * packet = enet_packet_create ("packet",
strlen ("packet") + 1,
ENET_PACKET_FLAG_RELIABLE);
/* Extend the packet so and append the string "foo", so it now */
/* contains "packetfoo\0" */
enet_packet_resize (packet, strlen ("packetfoo") + 1);
strcpy (& packet -> data [strlen ("packet")], "foo");
/* Send the packet to the peer over channel id 0. */
/* One could also broadcast the packet by */
/* enet_host_broadcast (host, 0, packet); */
enet_peer_send (peer, 0, packet);
...
...
...
/* One could just use enet_host_service() instead. */
enet_host_flush (host);
@endcode
@section Disconnecting Disconnecting an ENet peer
Peers may be gently disconnected with enet_peer_disconnect(). A
disconnect request will be sent to the foreign host, and ENet will
wait for an acknowledgement from the foreign host before finally
disconnecting. An event of type ENET_EVENT_TYPE_DISCONNECT will be
generated once the disconnection succeeds. Normally timeouts apply to
the disconnect acknowledgement, and so if no acknowledgement is
received after a length of time the peer will be forcefully
disconnected.
enet_peer_reset() will forcefully disconnect a peer. The foreign host
will get no notification of a disconnect and will time out on the
foreign host. No event is generated.
@code
ENetEvent event;
enet_peer_disconnect (peer, 0);
/* Allow up to 3 seconds for the disconnect to succeed
* and drop any packets received packets.
*/
while (enet_host_service (client, & event, 3000) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_RECEIVE:
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
puts ("Disconnection succeeded.");
return;
...
...
...
}
}
/* We've arrived here, so the disconnect attempt didn't */
/* succeed yet. Force the connection down. */
enet_peer_reset (peer);
...
...
...
@endcode
@section Connecting Connecting to an ENet host
A connection to a foreign host is initiated with enet_host_connect().
It accepts the address of a foreign host to connect to, and the number
of channels that should be allocated for communication. If N channels
are allocated for use, their channel ids will be numbered 0 through
N-1. A peer representing the connection attempt is returned, or NULL
if there were no available peers over which to initiate the
connection. When the connection attempt succeeds, an event of type
ENET_EVENT_TYPE_CONNECT will be generated. If the connection attempt
times out or otherwise fails, an event of type
ENET_EVENT_TYPE_DISCONNECT will be generated.
@code
ENetAddress address;
ENetEvent event;
ENetPeer *peer;
/* Connect to some.server.net:1234. */
enet_address_set_host (& address, "some.server.net");
address.port = 1234;
/* Initiate the connection, allocating the two channels 0 and 1. */
peer = enet_host_connect (client, & address, 2, 0);
if (peer == NULL)
{
fprintf (stderr,
"No available peers for initiating an ENet connection.\n");
exit (EXIT_FAILURE);
}
/* Wait up to 5 seconds for the connection attempt to succeed. */
if (enet_host_service (client, & event, 5000) > 0 &&
event.type == ENET_EVENT_TYPE_CONNECT)
{
puts ("Connection to some.server.net:1234 succeeded.");
...
...
...
}
else
{
/* Either the 5 seconds are up or a disconnect event was */
/* received. Reset the peer in the event the 5 seconds */
/* had run out without any significant event. */
enet_peer_reset (peer);
puts ("Connection to some.server.net:1234 failed.");
}
...
...
...
@endcode
*/

34
shared/thirdparty/enet/package.json vendored Normal file
View file

@ -0,0 +1,34 @@
{
"name": "enet.c",
"version": "2.3.0",
"description": "ENet - Simple, lightweight and reliable UDP networking library written on pure C.",
"main": "include/enet.h",
"directories": {
"doc": "misc/docs"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zpl-c/enet-c.git"
},
"keywords": [
"udp",
"networking",
"c",
"cpp",
"c++"
],
"author": "Lee Salzman",
"contributors": [
"Vladyslav Hrytsenko",
"Dominik Madarász"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/zpl-c/enet-c/issues"
},
"homepage": "https://github.com/zpl-c/enet-c#readme",
"dependencies": {}
}

108
shared/thirdparty/enet/test/build.C vendored Normal file
View file

@ -0,0 +1,108 @@
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define ENET_IMPLEMENTATION
#include "enet.h"
#include <stdio.h>
typedef struct {
ENetHost *host;
ENetPeer *peer;
} Client;
void host_server(ENetHost *server) {
ENetEvent event;
while (enet_host_service(server, &event, 2) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT:
printf("A new client connected from ::1:%u.\n", event.peer->address.port);
/* Store any relevant client information here. */
event.peer->data = "Client information";
break;
case ENET_EVENT_TYPE_RECEIVE:
printf("A packet of length %zu containing %s was received from %s on channel %u.\n",
event.packet->dataLength,
event.packet->data,
(char *)event.peer->data,
event.channelID);
/* Clean up the packet now that we're done using it. */
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
printf ("%s disconnected.\n", (char *)event.peer->data);
/* Reset the peer's client information. */
event.peer->data = NULL;
break;
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
printf ("%s timeout.\n", (char *)event.peer->data);
event.peer->data = NULL;
break;
case ENET_EVENT_TYPE_NONE: break;
}
}
}
int main() {
if (enet_initialize() != 0) {
printf("An error occurred while initializing ENet.\n");
return 1;
}
#define MAX_CLIENTS 32
int i = 0;
ENetHost *server;
Client clients[MAX_CLIENTS];
ENetAddress address = {0};
address.host = ENET_HOST_ANY; /* Bind the server to the default localhost. */
address.port = 7777; /* Bind the server to port 7777. */
/* create a server */
printf("starting server...\n");
server = enet_host_create(&address, MAX_CLIENTS, 2, 0, 0);
if (server == NULL) {
printf("An error occurred while trying to create an ENet server host.\n");
return 1;
}
printf("starting clients...\n");
for (i = 0; i < MAX_CLIENTS; ++i) {
enet_address_set_host(&address, "127.0.0.1");
clients[i].host = enet_host_create(NULL, 1, 2, 0, 0);
clients[i].peer = enet_host_connect(clients[i].host, &address, 2, 0);
if (clients[i].peer == NULL) {
printf("coundlnt connect\n");
return 1;
}
}
// program will make N iterations, and then exit
static int counter = 1000;
do {
host_server(server);
ENetEvent event;
for (i = 0; i < MAX_CLIENTS; ++i) {
enet_host_service(clients[i].host, &event, 0);
}
counter--;
} while (counter > 0);
for (i = 0; i < MAX_CLIENTS; ++i) {
enet_peer_disconnect_now(clients[i].peer, 0);
enet_host_destroy(clients[i].host);
}
host_server(server);
enet_host_destroy(server);
enet_deinitialize();
return 0;
}

3
shared/thirdparty/enet/test/library.C vendored Normal file
View file

@ -0,0 +1,3 @@
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define ENET_IMPLEMENTATION
#include "enet.h"

View file

@ -26,19 +26,19 @@
This file is part of MEMWATCH.
MEMWATCH is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
MEMWATCH is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
MEMWATCH is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
MEMWATCH is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MEMWATCH; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License
along with MEMWATCH; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************
**
@ -333,6 +333,9 @@
#include <stdlib.h>
/*lint -restore */
/* strdup() */
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -651,7 +654,7 @@ extern void mwDummyTraceFunction(const char *,...);
#endif /* !__MEMWATCH_C */
#ifdef __cplusplus
}
}
#endif
#if 0 /* 980317: disabled C++ */
@ -686,9 +689,9 @@ extern const char *mwNFile;
extern int mwNLine;
class MemWatch {
public:
MemWatch();
~MemWatch();
};
MemWatch();
~MemWatch();
};
void * operator new(size_t);
void * operator new(size_t,const char *,int);
void * operator new[] (size_t,const char *,int); // hjc 07/16/02

BIN
shared/thirdparty/memwatch/memwatch.o vendored Normal file

Binary file not shown.