summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile40
-rw-r--r--client/net/net.c8
-rw-r--r--server/main.c15
-rw-r--r--shared/net_compat.h61
4 files changed, 109 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index 65ffe9d..e3d8520 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,25 @@
-CC = gcc-15
-CFLAGS = -MMD -MP -Wall -Wextra -pthread
-LDFLAGS = -pthread
+# Detect OS
+UNAME_S := $(shell uname -s)
+CFLAGS_COMMON = -MMD -MP -Wall -Wextra -I./shared
+
+# Compiler
+ifeq ($(UNAME_S),Darwin)
+ CC = gcc-15
+ CFLAGS = $(CFLAGS_COMMON) -pthread
+ LDFLAGS = -pthread
+else ifeq ($(UNAME_S),Linux)
+ CC = gcc
+ CFLAGS = $(CFLAGS_COMMON) -pthread
+ LDFLAGS = -pthread
+else
+ # Windows (MSYS2 MinGW)
+ CC = gcc
+ CFLAGS = $(CFLAGS_COMMON)
+ LDFLAGS = -lws2_32
+endif
+
+# Directories
SERVER_BUILD = build/server
SERVER_TARGET = bin/server
SERVER_SRC = $(shell find server -name "*.c")
@@ -11,9 +29,17 @@ CLIENT_BUILD = build/client
CLIENT_TARGET = bin/client
CLIENT_SRC = $(shell find client -name "*.c")
CLIENT_OBJ = $(CLIENT_SRC:client/%.c=$(CLIENT_BUILD)/%.o)
+
+# Raylib via pkg-config (works on macOS, Linux, MSYS2)
CLIENT_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags raylib)
CLIENT_LDFLAGS = $(LDFLAGS) $(shell pkg-config --libs raylib)
+# Windows needs extra libs sometimes
+ifeq ($(OS),Windows_NT)
+ CLIENT_LDFLAGS += -lopengl32 -lgdi32 -lwinmm
+endif
+
+# Dependency files
-include $(SERVER_OBJ:.o=.d)
-include $(CLIENT_OBJ:.o=.d)
@@ -24,15 +50,18 @@ all: $(SERVER_TARGET) $(CLIENT_TARGET)
server: $(SERVER_TARGET)
client: $(CLIENT_TARGET)
+# Create bin directory
bin:
mkdir -p bin
+# Link targets
$(SERVER_TARGET): $(SERVER_OBJ) | bin
- $(CC) $(LDFLAGS) $(SERVER_OBJ) -o $(SERVER_TARGET)
+ $(CC) $(SERVER_OBJ) -o $(SERVER_TARGET) $(LDFLAGS)
$(CLIENT_TARGET): $(CLIENT_OBJ) | bin
- $(CC) $(CLIENT_LDFLAGS) $(CLIENT_OBJ) -o $(CLIENT_TARGET)
+ $(CC) $(CLIENT_OBJ) -o $(CLIENT_TARGET) $(CLIENT_LDFLAGS)
+# Compile rules
$(SERVER_BUILD)/%.o: server/%.c
mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@
@@ -41,5 +70,6 @@ $(CLIENT_BUILD)/%.o: client/%.c
mkdir -p $(dir $@)
$(CC) $(CLIENT_CFLAGS) -c $< -o $@
+# Clean
clean:
rm -rf build bin
diff --git a/client/net/net.c b/client/net/net.c
index be61104..7f6332e 100644
--- a/client/net/net.c
+++ b/client/net/net.c
@@ -1,13 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
-#include <err.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <netinet/in.h>
#include <time.h>
#include "net.h"
+#include "net_compat.h"
void ServerConnect() {
+ net_init();
+
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
@@ -23,4 +22,5 @@ void ServerConnect() {
sendto(fd, buff, sizeof(buff), 0, (struct sockaddr *)&server, sizeof(server));
close(fd);
+ net_cleanup();
}
diff --git a/server/main.c b/server/main.c
index 789d392..6a5e5ba 100644
--- a/server/main.c
+++ b/server/main.c
@@ -1,12 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
-#include <err.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <netinet/in.h>
#include <time.h>
+#include "net_compat.h"
int main() {
+ net_init();
+
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
@@ -22,6 +21,8 @@ int main() {
err(EXIT_FAILURE, "bind failed");
}
+ set_nonblocking(fd);
+
time_t startTime = time(NULL);
while (time(NULL) < startTime + 60) {
@@ -29,13 +30,15 @@ int main() {
socklen_t connectionLen = sizeof(connection);
char buff[64];
- int size = recvfrom(fd, buff, sizeof(buff), MSG_DONTWAIT,
+ int size = recvfrom(fd, buff, sizeof(buff), 0,
(struct sockaddr *)&connection, &connectionLen);
if (size != -1)
- printf("got a message\n");
+ printf("message recievd\n");
}
close(fd);
+ net_cleanup();
+
return 0;
}
diff --git a/shared/net_compat.h b/shared/net_compat.h
new file mode 100644
index 0000000..5e63e04
--- /dev/null
+++ b/shared/net_compat.h
@@ -0,0 +1,61 @@
+// net_compat.h
+#pragma once
+
+#ifdef _WIN32
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #pragma comment(lib, "ws2_32.lib")
+
+ // Map POSIX names to Winsock equivalents
+ #define close(s) closesocket(s)
+ #define MSG_DONTWAIT 0 // no direct equivalent, use non-blocking mode instead
+
+ static inline int net_errno(void) { return WSAGetLastError(); }
+ #define NET_EAGAIN WSAEWOULDBLOCK
+ #define NET_EINTR WSAEINTR
+
+ typedef int socklen_t;
+
+ // err.h doesn't exist on Windows — provide a minimal shim
+ #include <stdio.h>
+ #include <stdlib.h>
+ static inline void err(int code, const char *msg) {
+ fprintf(stderr, "%s: WSA error %d\n", msg, WSAGetLastError());
+ exit(code);
+ }
+
+ // Winsock requires explicit init/cleanup
+ static inline void net_init(void) {
+ WSADATA wsa;
+ if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) {
+ fprintf(stderr, "WSAStartup failed\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ static inline void net_cleanup(void) { WSACleanup(); }
+
+ // Non-blocking: Winsock uses ioctlsocket instead of MSG_DONTWAIT
+ #include <winsock2.h>
+ static inline void set_nonblocking(SOCKET s) {
+ u_long mode = 1;
+ ioctlsocket(s, FIONBIO, &mode);
+ }
+
+#else
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <unistd.h>
+ #include <err.h>
+ #include <errno.h>
+ #include <fcntl.h>
+
+ static inline void net_init(void) {} // no-op on POSIX
+ static inline void net_cleanup(void) {} // no-op on POSIX
+ static inline void set_nonblocking(int s) {
+ fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
+ }
+
+ static inline int net_errno(void) { return errno; }
+ #define NET_EAGAIN EAGAIN
+ #define NET_EINTR EINTR
+#endif