#define GL_GLEXT_PROTOTYPES
#define _USE_MATH_DEFINES
#include <string.h>
#include <unistd.h>
#if defined(_WIN32)
#include <winsock2.h>
#if defined(__GNUC__)
#include <cpuid.h>
#elif defined(_MSC_VER)
#include <intrin.h>
#endif
//#define APIENTRY __stdcall
#include <windows.h>
#include <errno.h>
#define GLEW_STATIC
#include <GL/glew.h>
//#include "glew/glew.h"
//#include <GL/gl.h>
//#include <GLES2/gl2.h>
//#include <GLES2/gl2ext.h>
//#define GLFW_INCLUDE_ES3
#define GLFW_EXPOSE_NATIVE_WGL
#define GLFW_EXPOSE_NATIVE_WIN32
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <GL/gl.h>
//#include <GL/glext.h>
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#include <sys/time.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "linmathv2.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#define degToRad(angleInDegrees) ((angleInDegrees) * M_PI / 180.0)
#define radToDeg(angleInRadians) ((angleInRadians) * 180.0 / M_PI)
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define CLAMP(x, upper, lower) (MIN(upper, MAX(x, lower)))
#include "custom.h"
#include "player.h"
#include "cjson/cJSON.h"
#include "input.h"
#define PORT 12345
#define MAX_PLAYERS 2
#define UPDATE_INTERVAL 0.050 // 50ms
#define SPEED 100.0 // Pixels per second
#define SMOOTHING_SPEED 10.0 // Smoothing factor for correction
typedef struct {
uint32_t sequence;
double server_time;
uint8_t num_players;
struct {
uint8_t id;
float pos_x, pos_y, pos_z;
float vel_x, vel_y, vel_z;
} players[MAX_PLAYERS];
} Snapshot;
// Get current time in seconds
double get_time() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1e6;
}
// Server code
//--void init_server() {
//-- int sockfd;
//-- struct sockaddr_in server_addr, client_addr;
//-- socklen_t addr_len = sizeof(client_addr);
//-- NetworkPlayer players[MAX_PLAYERS] = {0};
//-- InputMessage input;
//-- Snapshot snapshot = {0};
//-- double last_update_time = get_time();
//-- uint32_t sequence = 0;
//--
//-- // Initialize players
//-- for (int i = 0; i < MAX_PLAYERS; i++) {
//-- players[i].id = i;
//-- players[i].position.x = 100.0 * (i + 1);
//-- players[i].position.y = 100.0;
//-- }
//--
//-- // Create UDP socket
//-- sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//-- if (sockfd < 0) {
//-- perror("Socket creation failed");
//-- exit(1);
//-- }
//--
//-- // Bind socket
//-- memset(&server_addr, 0, sizeof(server_addr));
//-- server_addr.sin_family = AF_INET;
//-- server_addr.sin_addr.s_addr = INADDR_ANY;
//-- server_addr.sin_port = htons(PORT);
//-- if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
//-- perror("Bind failed");
//-- close(sockfd);
//-- exit(1);
//-- }
//--
//-- printf("Server running on port %d\n", PORT);
//--}
//--void update_server() {
//-- //while (1) {
//-- double current_time = get_time();
//--
//-- // Receive inputs non-blocking
//-- while (1) {
//-- ssize_t n = recvfrom(sockfd, &input, sizeof(input), MSG_DONTWAIT,
//-- (struct sockaddr*)&client_addr, &addr_len);
//-- if (n < 0) {
//-- if (errno == EWOULDBLOCK || errno == EAGAIN) break;
//-- perror("Recvfrom failed");
//-- continue;
//-- }
//-- if (player_id < MAX_PLAYERS) {
//-- // Update velocity based on input
//-- players[player_id].velocity.x = input_x * SPEED;
//-- players[player_id].velocity.y = input_y * SPEED;
//-- }
//-- }
//--
//-- // Fixed update
//-- if (current_time - last_update_time >= UPDATE_INTERVAL) {
//-- double dt = UPDATE_INTERVAL;
//--
//-- // Update game state
//-- for (int i = 0; i < MAX_PLAYERS; i++) {
//-- players[i].position.x += players[i].velocity.x * dt;
//-- players[i].position.y += players[i].velocity.y * dt;
//-- }
//--
//-- // Prepare snapshot
//-- snapshot.sequence = sequence++;
//-- snapshot.server_time = current_time;
//-- snapshot.num_players = MAX_PLAYERS;
//-- for (int i = 0; i < MAX_PLAYERS; i++) {
//-- snapshot.players[i].id = players[i].id;
//-- snapshot.players[i].pos_x = players[i].position.x;
//-- snapshot.players[i].pos_y = players[i].position.y;
//-- snapshot.players[i].vel_x = players[i].velocity.x;
//-- snapshot.players[i].vel_y = players[i].velocity.y;
//-- }
//--
//-- // Send snapshot to all clients (broadcast to known clients)
//-- // Here, we assume clients are at known addresses; in practice, maintain a client list
//-- for (int i = 0; i < MAX_PLAYERS; i++) {
//-- sendto(sockfd, &snapshot, sizeof(snapshot), 0,
//-- (struct sockaddr*)&client_addr, addr_len);
//-- }
//--
//-- last_update_time += UPDATE_INTERVAL;
//-- }
//--
//-- //usleep(1000); // Prevent CPU hogging
//-- //}
//--
//-- //close(sockfd);
//--}
//--
//--
//--
//--
//--// client
//--
//--// Client code
//--void init_client(int local_player_id) {
//-- int sockfd;
//-- struct sockaddr_in server_addr;
//-- socklen_t addr_len = sizeof(server_addr);
//-- NetworkPlayer players[MAX_PLAYERS] = {0};
//-- Snapshot snapshot;
//-- InputMessage input = {0};
//-- uint32_t last_sequence = 0;
//-- double last_frame_time = get_time();
//--
//-- // Initialize players
//-- for (int i = 0; i < MAX_PLAYERS; i++) {
//-- players[i].id = i;
//-- }
//-- player_id = local_player_id;
//--
//-- // Create UDP socket
//-- sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//-- if (sockfd < 0) {
//-- perror("Socket creation failed");
//-- exit(1);
//-- }
//--
//-- // Server address
//-- memset(&server_addr, 0, sizeof(server_addr));
//-- server_addr.sin_family = AF_INET;
//-- server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Localhost
//-- server_addr.sin_port = htons(PORT);
//--
//-- printf("Client %d running, connecting to server\n", local_player_id);
//--}
//--
//--void update_client() {
//-- //while (1) {
//-- double current_time = get_time();
//-- double frame_dt = current_time - last_frame_time;
//--
//-- // Simulate input (e.g., arrow keys; in practice, use real input)
//-- input_x = (local_player_id == 0) ? 1.0 : -1.0; // Player 0 moves right, Player 1 left
//-- input_y = 0.0;
//-- sendto(sockfd, &input, sizeof(input), 0,
//-- (struct sockaddr*)&server_addr, sizeof(server_addr));
//--
//-- // Receive snapshots
//-- while (1) {
//-- ssize_t n = recvfrom(sockfd, &snapshot, sizeof(snapshot), MSG_DONTWAIT,
//-- (struct sockaddr*)&server_addr, &addr_len);
//-- if (n < 0) {
//-- if (errno == EWOULDBLOCK || errno == EAGAIN) break;
//-- perror("Recvfrom failed");
//-- continue;
//-- }
//-- if (snapshot.sequence > last_sequence) {
//-- last_sequence = snapshot.sequence;
//-- for (int i = 0; i < snapshot.num_players; i++) {
//-- int id = snapshot.players[i].id;
//-- players[id].position.x = snapshot.players[i].pos_x;
//-- players[id].position.y = snapshot.players[i].pos_y;
//-- players[id].velocity.x = snapshot.players[i].vel_x;
//-- players[id].velocity.y = snapshot.players[i].vel_y;
//-- players[id].snapshot_time = current_time;
//-- // Initialize rendered position if first update
//-- if (players[id].rendered_position.x == 0.0 && players[id].rendered_position.y == 0.0) {
//-- players[id].rendered_position = players[id].position;
//-- }
//-- }
//-- }
//-- }
//--
//-- // Render loop
//-- for (int i = 0; i < MAX_PLAYERS; i++) {
//-- double dt = current_time - players[i].snapshot_time;
//-- // Predict position using last known velocity
//-- Vec3 target_position = {
//-- players[i].position.x + players[i].velocity.x * dt,
//-- players[i].position.y + players[i].velocity.y * dt
//-- players[i].position.z + players[i].velocity.z * dt
//-- };
//--
//-- // Smoothly correct rendered position toward target (rollback)
//-- float correction_x = (target_position.x - players[i].rendered_position.x) * SMOOTHING_SPEED * frame_dt;
//-- float correction_y = (target_position.y - players[i].rendered_position.y) * SMOOTHING_SPEED * frame_dt;
//-- float correction_z = (target_position.z - players[i].rendered_position.z) * SMOOTHING_SPEED * frame_dt;
//-- players[i].rendered_position.x += correction_x;
//-- players[i].rendered_position.y += correction_y;
//-- players[i].rendered_position.z += correction_z;
//--
//-- // Simulate rendering (print position)
//-- printf("Client %d: Player %d at (%f, %f)\n", local_player_id, i,
//-- players[i].rendered_position.x, players[i].rendered_position.y, players[i].rendered_position.z);
//-- }
//--
//-- last_frame_time = current_time;
//-- //usleep(16666); // ~60 FPS
//-- //}
//--
//-- //close(sockfd);
//--}
Top