Implement net component
This commit is contained in:
parent
f42f5f69c8
commit
84c834c000
|
@ -35,6 +35,10 @@ if(SDL1_2_BUILD)
|
|||
target_link_libraries(SDL::SDL_mixer INTERFACE SDL::SDL)
|
||||
endif()
|
||||
|
||||
if(NOT PS1_BUILD)
|
||||
find_package(ENET 1.3 REQUIRED)
|
||||
endif()
|
||||
|
||||
set(cdroot ${CMAKE_BINARY_DIR}/cdimg)
|
||||
file(MAKE_DIRECTORY ${cdroot})
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ cd build
|
|||
SDLDIR=<sdl-prefix> \
|
||||
SDLMIXERDIR=<sdl_mixer-prefix> \
|
||||
SDLGFXDIR=<sdl_gfx-prefix> \
|
||||
ENETDIR=<enet-prefix> \
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/win9x-toolchain.cmake
|
||||
make -j$(nproc --all)
|
||||
```
|
||||
|
@ -106,6 +107,9 @@ building `SDL_mixer`.
|
|||
- `SDLGFXDIR` is the path to the cross-compiled version for `SDL_gfx`,
|
||||
which would correspond to `./configure --prefix=$SDLGFXDIR` used in
|
||||
building `SDL_gfx`.
|
||||
- `ENETDIR` is the path to the cross-compiled version for `enet`,
|
||||
which would correspond to `./configure --prefix=$ENETDIR` used in
|
||||
building `enet`.
|
||||
|
||||
A stripped version of the executable, as well as game assets, will be
|
||||
located in `build/cdimg`.
|
||||
|
|
|
@ -6,6 +6,7 @@ add_custom_command(OUTPUT ${cdroot}/${PROJECT_NAME}
|
|||
add_custom_target(stripped-exe ALL DEPENDS ${cdroot}/${PROJECT_NAME})
|
||||
|
||||
target_link_libraries(SDL::SDL INTERFACE gdi32 user32 winmm dxguid)
|
||||
target_link_libraries(ENET INTERFACE ws2_32)
|
||||
|
||||
add_compile_options(-march=i386)
|
||||
|
||||
|
|
|
@ -132,3 +132,11 @@ WAVE files, support for other audio formats is not required.
|
|||
CFLAGS='-ffunction-sections -fdata-sections' \
|
||||
CC=i386-mingw32-gcc
|
||||
```
|
||||
|
||||
## ENET
|
||||
|
||||
```sh
|
||||
../enet-1.3.17/configure --prefix=$HOME/enet-1.3.17-win32 \
|
||||
--host=i386-mingw32 CFLAGS='-ffunction-sections -fdata-sections' \
|
||||
CC=i386-mingw32-gcc
|
||||
```
|
||||
|
|
|
@ -15,6 +15,7 @@ set(components
|
|||
keyboard
|
||||
menu
|
||||
mouse
|
||||
net
|
||||
pad
|
||||
peripheral
|
||||
player
|
||||
|
|
32
src/net/CMakeLists.txt
Normal file
32
src/net/CMakeLists.txt
Normal file
|
@ -0,0 +1,32 @@
|
|||
set(src "src/common.c")
|
||||
|
||||
if(PS1_BUILD)
|
||||
set(src ${src}
|
||||
"src/ps1/net.c"
|
||||
)
|
||||
else()
|
||||
set(src ${src}
|
||||
"src/net.c"
|
||||
"src/enet/ipv4.c"
|
||||
)
|
||||
|
||||
if(WIN9X_BUILD OR ${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(src ${src} "src/win9x/serial.c")
|
||||
else()
|
||||
# Assume POSIX if the command below executes successfully
|
||||
execute_process(COMMAND uname -m RESULT_VARIABLE result OUTPUT_QUIET)
|
||||
|
||||
if(result)
|
||||
message(FATAL_ERROR "Unknown operating system")
|
||||
else()
|
||||
set(src ${src} "src/posix/serial.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(priv_deps ${priv_deps} util ENET)
|
||||
set(privinc ${privinc} "privinc")
|
||||
endif()
|
||||
|
||||
add_library(net ${src})
|
||||
target_include_directories(net PUBLIC "inc" PRIVATE ${privinc})
|
||||
target_link_libraries(net PRIVATE ${priv_deps})
|
78
src/net/inc/net.h
Normal file
78
src/net/inc/net.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
#ifndef NET_H
|
||||
#define NET_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum net_domain
|
||||
{
|
||||
NET_DOMAIN_IPV4,
|
||||
NET_DOMAIN_SERIAL
|
||||
};
|
||||
|
||||
union net_connect
|
||||
{
|
||||
struct net_connect_common
|
||||
{
|
||||
enum net_domain domain;
|
||||
void (*on_connected)(void *arg);
|
||||
void (*on_disconnected)(void *arg);
|
||||
void *arg;
|
||||
} common;
|
||||
|
||||
struct net_connect_ipv4
|
||||
{
|
||||
struct net_connect_common common;
|
||||
const char *addr;
|
||||
uint16_t port;
|
||||
} ipv4;
|
||||
|
||||
struct net_connect_serial
|
||||
{
|
||||
struct net_connect_common common;
|
||||
const char *dev;
|
||||
unsigned long baud;
|
||||
|
||||
enum
|
||||
{
|
||||
NET_PARITY_NONE,
|
||||
NET_PARITY_ODD,
|
||||
NET_PARITY_EVEN
|
||||
} parity;
|
||||
} serial;
|
||||
};
|
||||
|
||||
union net_server
|
||||
{
|
||||
struct net_server_common
|
||||
{
|
||||
enum net_domain domain;
|
||||
unsigned max_players;
|
||||
} common;
|
||||
|
||||
struct net_server_ipv4
|
||||
{
|
||||
struct net_server_common common;
|
||||
uint16_t port;
|
||||
} ipv4;
|
||||
|
||||
struct net_server_serial
|
||||
{
|
||||
struct net_server_common common;
|
||||
} serial;
|
||||
};
|
||||
|
||||
struct net_socket;
|
||||
|
||||
int net_init(void);
|
||||
void net_deinit(void);
|
||||
int net_update(struct net_socket *s);
|
||||
|
||||
struct net_socket *net_server(const union net_server *srv);
|
||||
struct net_socket *net_connect(const union net_connect *c);
|
||||
int net_read(struct net_socket *s, void *buf, size_t n);
|
||||
int net_write(struct net_socket *s, const void *buf, size_t n);
|
||||
int net_close(struct net_socket *s);
|
||||
const char *net_domain_str(enum net_domain d);
|
||||
|
||||
#endif /* NET_H */
|
30
src/net/privinc/net_private.h
Normal file
30
src/net/privinc/net_private.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef NET_PRIVATE_H
|
||||
#define NET_PRIVATE_H
|
||||
|
||||
#include <net.h>
|
||||
|
||||
struct net_socket
|
||||
{
|
||||
enum net_domain d;
|
||||
struct net_socket_domain *s;
|
||||
};
|
||||
|
||||
int net_init_ipv4(void);
|
||||
void net_deinit_ipv4(void);
|
||||
struct net_socket_domain *net_server_ipv4(const union net_server *srv);
|
||||
struct net_socket_domain *net_connect_ipv4(const union net_connect *c);
|
||||
int net_read_ipv4(struct net_socket_domain *h, void *buf, size_t n);
|
||||
int net_write_ipv4(struct net_socket_domain *h, const void *buf, size_t n);
|
||||
int net_close_ipv4(struct net_socket_domain *h);
|
||||
int net_update_ipv4(struct net_socket_domain *h);
|
||||
|
||||
int net_init_serial(void);
|
||||
void net_deinit_serial(void);
|
||||
struct net_socket_domain *net_server_serial(const union net_server *srv);
|
||||
struct net_socket_domain *net_connect_serial(const union net_connect *c);
|
||||
int net_read_serial(struct net_socket_domain *h, void *buf, size_t n);
|
||||
int net_write_serial(struct net_socket_domain *h, const void *buf, size_t n);
|
||||
int net_close_serial(struct net_socket_domain *h);
|
||||
int net_update_serial(struct net_socket_domain *h);
|
||||
|
||||
#endif /* NET_PRIVATE_H */
|
12
src/net/src/common.c
Normal file
12
src/net/src/common.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <net.h>
|
||||
|
||||
const char *net_domain_str(const enum net_domain d)
|
||||
{
|
||||
static const char *const s[] =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = "UDP/IPv4",
|
||||
[NET_DOMAIN_SERIAL] = "Serial"
|
||||
};
|
||||
|
||||
return s[d];
|
||||
}
|
161
src/net/src/enet/ipv4.c
Normal file
161
src/net/src/enet/ipv4.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <enet/enet.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct net_socket_domain
|
||||
{
|
||||
ENetHost *host;
|
||||
ENetPeer *peers;
|
||||
void (*on_connected)(void *arg);
|
||||
void (*on_disconnected)(void *arg);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CHANNEL,
|
||||
MAX_CHANNELS
|
||||
};
|
||||
|
||||
struct net_socket_domain *net_connect_ipv4(const union net_connect *const c)
|
||||
{
|
||||
struct net_socket_domain *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
s->on_connected = c->common.on_connected;
|
||||
s->on_disconnected = c->common.on_disconnected;
|
||||
s->arg = c->common.arg;
|
||||
s->host = enet_host_create(NULL, 1, MAX_CHANNELS, 0, 0);
|
||||
|
||||
if (!s->host)
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_create failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ENetAddress addr;
|
||||
|
||||
if (enet_address_set_host(&addr, c->ipv4.addr))
|
||||
{
|
||||
fprintf(stderr, "%s: enet_address_set_host failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
addr.port = c->ipv4.port;
|
||||
|
||||
if (!(s->peers = enet_host_connect(s->host, &addr, MAX_CHANNELS, 0)))
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_connect failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
failure:
|
||||
|
||||
if (s && s->host)
|
||||
enet_host_destroy(s->host);
|
||||
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_read_ipv4(struct net_socket_domain *const s, void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write_ipv4(struct net_socket_domain *const s, const void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close_ipv4(struct net_socket_domain *const s)
|
||||
{
|
||||
if (s && s->host)
|
||||
enet_host_destroy(s->host);
|
||||
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int net_update_ipv4(struct net_socket_domain *const s)
|
||||
{
|
||||
int res;
|
||||
ENetEvent ev;
|
||||
|
||||
while ((res = enet_host_service(s->host, &ev, 0)) > 0)
|
||||
{
|
||||
switch (ev.type)
|
||||
{
|
||||
case ENET_EVENT_TYPE_CONNECT:
|
||||
if (s->on_connected)
|
||||
s->on_connected(s->arg);
|
||||
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
if (s->on_disconnected)
|
||||
s->on_disconnected(s->arg);
|
||||
|
||||
case ENET_EVENT_TYPE_RECEIVE:
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_service failed\n", __func__);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_server_ipv4(const union net_server *const srv)
|
||||
{
|
||||
struct net_socket_domain *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
const ENetAddress addr =
|
||||
{
|
||||
.port = srv->ipv4.port
|
||||
};
|
||||
|
||||
s->host = enet_host_create(&addr, srv->common.max_players,
|
||||
MAX_CHANNELS, 0, 0);
|
||||
|
||||
if (!s->host)
|
||||
{
|
||||
fprintf(stderr, "%s: enet_host_create failed\n", __func__);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
failure:
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init_ipv4(void)
|
||||
{
|
||||
return enet_initialize();
|
||||
}
|
||||
|
||||
void net_deinit_ipv4(void)
|
||||
{
|
||||
enet_deinitialize();
|
||||
}
|
111
src/net/src/net.c
Normal file
111
src/net/src/net.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct net_socket *net_connect(const union net_connect *const c)
|
||||
{
|
||||
struct net_socket *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
static struct net_socket_domain *(*const f[])(const union net_connect *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_connect_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_connect_serial
|
||||
};
|
||||
|
||||
if (!(s->s = f[c->common.domain](c)))
|
||||
goto failure;
|
||||
|
||||
return s;
|
||||
|
||||
failure:
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_read(struct net_socket *const s, void *const buf, const size_t n)
|
||||
{
|
||||
static int (*const f[])(struct net_socket_domain *, void *, size_t) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_read_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_read_serial
|
||||
};
|
||||
|
||||
return f[s->d](s->s, buf, n);
|
||||
}
|
||||
|
||||
int net_write(struct net_socket *const s, const void *const buf, const size_t n)
|
||||
{
|
||||
static int (*const f[])(struct net_socket_domain *, const void *, size_t) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_write_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_write_serial
|
||||
};
|
||||
|
||||
return f[s->d](s->s, buf, n);
|
||||
}
|
||||
|
||||
int net_close(struct net_socket *const s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
static int (*const f[])(struct net_socket_domain *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_close_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_close_serial
|
||||
};
|
||||
|
||||
const int res = f[s->d](s->s);
|
||||
|
||||
free(s);
|
||||
return res;
|
||||
}
|
||||
|
||||
int net_update(struct net_socket *const s)
|
||||
{
|
||||
static int (*const f[])(struct net_socket_domain *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_update_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_update_serial
|
||||
};
|
||||
|
||||
return f[s->d](s->s);
|
||||
}
|
||||
|
||||
struct net_socket *net_server(const union net_server *const srv)
|
||||
{
|
||||
struct net_socket *const s = calloc(1, sizeof *s);
|
||||
|
||||
if (!s)
|
||||
goto failure;
|
||||
|
||||
s->d = srv->common.domain;
|
||||
|
||||
static struct net_socket_domain *(*const f[])(const union net_server *) =
|
||||
{
|
||||
[NET_DOMAIN_IPV4] = net_server_ipv4,
|
||||
[NET_DOMAIN_SERIAL] = net_server_serial
|
||||
};
|
||||
|
||||
if (!(s->s = f[s->d](srv)))
|
||||
goto failure;
|
||||
|
||||
failure:
|
||||
net_close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init(void)
|
||||
{
|
||||
return net_init_ipv4() || net_init_serial();
|
||||
}
|
||||
|
||||
void net_deinit(void)
|
||||
{
|
||||
net_deinit_ipv4();
|
||||
net_deinit_serial();
|
||||
}
|
44
src/net/src/posix/serial.c
Normal file
44
src/net/src/posix/serial.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int net_read_serial(struct net_socket_domain *const h, void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write_serial(struct net_socket_domain *const h, const void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_update_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_connect_serial(const union net_connect *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_server_serial(const union net_server *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init_serial(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_deinit_serial(void)
|
||||
{
|
||||
}
|
42
src/net/src/ps1/net.c
Normal file
42
src/net/src/ps1/net.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <net.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int net_read(struct net_socket *const h, void *const buf, const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write(struct net_socket *const h, const void *const buf, const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close(struct net_socket *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_update(struct net_socket *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct net_socket *net_connect(const union net_connect *const c)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct net_socket *net_server(const union net_server *const c)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void net_deinit(void)
|
||||
{
|
||||
}
|
44
src/net/src/win9x/serial.c
Normal file
44
src/net/src/win9x/serial.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <net.h>
|
||||
#include <net_private.h>
|
||||
#include <stddef.h>
|
||||
|
||||
int net_read_serial(struct net_socket_domain *const h, void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_write_serial(struct net_socket_domain *const h, const void *const buf,
|
||||
const size_t n)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_close_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int net_update_serial(struct net_socket_domain *const h)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_connect_serial(const union net_connect *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct net_socket_domain *net_server_serial(const union net_server *const srv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int net_init_serial(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_deinit_serial(void)
|
||||
{
|
||||
}
|
Loading…
Reference in a new issue