From 0151eb65ef177b918b1570d0c66797a10adf6e04 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 21:16:16 +0530 Subject: [PATCH] REAL GAM --- game/client | Bin 38744 -> 0 bytes game/client.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++--- game/server | Bin 36424 -> 0 bytes 3 files changed, 149 insertions(+), 7 deletions(-) delete mode 100755 game/client delete mode 100755 game/server diff --git a/game/client b/game/client deleted file mode 100755 index dd120e67ad8cfe63762cc04683146e234cf7c4f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38744 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 D{ynK0 diff --git a/game/client.c b/game/client.c index c9ac211..c7eb9e5 100644 --- a/game/client.c +++ b/game/client.c @@ -1,4 +1,4 @@ -// game/client.c - SMOOTH TERRAIN VERSION +// game/client.c - SMOOTH TERRAIN VERSION WITH DIRECTIONAL LIGHT & SHADOWS #include "raylib.h" #include #include @@ -43,6 +43,16 @@ typedef int socklen_t; #define BTN_USE_MEDKIT (1u << 4) #define BTN_JUMP (1u << 5) +// ============== DIRECTIONAL LIGHT ============== +typedef struct { + Vector3 direction; // Normalized light direction + Vector3 color; // RGB color (0-1 range) + float intensity; // Light intensity multiplier + float ambientIntensity; // Ambient light strength + float shadowBias; // Shadow bias to prevent z-fighting + float shadowIntensity; // How dark shadows are (0-1) +} DirectionalLight; + // ============== SIMPLEX NOISE ============== static const uint8_t perm[512] = { 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, @@ -257,6 +267,110 @@ static Mesh generate_terrain_mesh(void) { } // ============== END SIMPLEX NOISE ============== +// ============== LIGHTING HELPERS ============== +// apply_directional_lighting: Basic Lambertian diffuse lighting +// Applies directional light with diffuse component based on surface normal +static Color apply_directional_lighting(Color baseColor, Vector3 normal, + DirectionalLight light) { + // Normalize light direction (it's already normalized, but for safety) + Vector3 lightDir = light.direction; + + // Calculate diffuse component: dot product of negative light direction and + // surface normal We use negative because light travels opposite to its + // direction vector + float diff = fmaxf(0.0f, -(lightDir.x * normal.x + lightDir.y * normal.y + + lightDir.z * normal.z)); + + // Combine diffuse with ambient light + // Ambient provides minimum brightness even in shadow + float brightness = light.ambientIntensity + + (diff * light.intensity * (1.0f - light.ambientIntensity)); + + // Apply brightness multiplier to base color + int r = (int)(baseColor.r * brightness); + int g = (int)(baseColor.g * brightness); + int b = (int)(baseColor.b * brightness); + + // Clamp RGB to valid range [0, 255] + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (b > 255) + b = 255; + + return (Color){r, g, b, baseColor.a}; +} + +// calculate_shadow_factor: Distance-based shadow softening +// Objects at higher elevations or farther from ground get softer, less +// pronounced shadows This simulates how shadows fade with distance and +// atmospheric scattering +static float calculate_shadow_factor(Vector3 worldPos, Vector3 lightDir, + float maxShadowDistance) { + // Calculate height above ground (approximate) + float distFromLight = fmaxf(0.0f, worldPos.y - 2.0f); + + // Fade out shadow strength with distance (max 15% darkening) + float shadowIntensity = + fmaxf(0.0f, 1.0f - (distFromLight / maxShadowDistance)); + return 1.0f - (shadowIntensity * 0.15f); +} + +// calculate_temporal_shadow: Time-based shadow variance for anti-aliasing +// Simulates subtle shadow movement to avoid banding artifacts +static float calculate_temporal_shadow(Vector3 worldPos, float timePhase) { + // Add subtle time-based variation to shadow boundaries + float noiseVal = + sinf(worldPos.x * 0.5f + timePhase) * cosf(worldPos.z * 0.5f + timePhase); + return 1.0f + (noiseVal * 0.02f); // Very subtle variation +} + +// apply_lighting_with_shadows: Full lighting calculation with shadows +// Combines directional light, ambient light, shadows, and temporal variation +static Color apply_lighting_with_shadows(Color baseColor, Vector3 normal, + Vector3 worldPos, + DirectionalLight light) { + // Calculate base shadow factor (distance-based) + float shadowFactor = + calculate_shadow_factor(worldPos, light.direction, 10.0f); + + // Apply shadow to intensity + float adjustedIntensity = light.intensity * shadowFactor; + + // Calculate diffuse component with adjusted intensity + Vector3 lightDir = light.direction; + float diff = fmaxf(0.0f, -(lightDir.x * normal.x + lightDir.y * normal.y + + lightDir.z * normal.z)); + + // Combine with ambient using adjusted intensity + float brightness = light.ambientIntensity + (diff * adjustedIntensity * + (1.0f - light.ambientIntensity)); + + // Apply brightness to base color + int r = (int)(baseColor.r * brightness); + int g = (int)(baseColor.g * brightness); + int b = (int)(baseColor.b * brightness); + + // Clamp values to valid RGB range + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (b > 255) + b = 255; + + return (Color){r, g, b, baseColor.a}; +} + +static Vector3 v3_normalize(Vector3 v) { + float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + if (len < 0.0001f) + return (Vector3){0, 1, 0}; + return (Vector3){v.x / len, v.y / len, v.z / len}; +} +// ============== END LIGHTING HELPERS ============== + static void set_nonblocking(int sock) { #ifdef _WIN32 u_long mode = 1; @@ -427,7 +541,7 @@ int main(void) { #endif const int sw = 1280, sh = 720; - InitWindow(sw, sh, "Voxel Shooter - Client (SMOOTH TERRAIN)"); + InitWindow(sw, sh, "Voxel Shooter - Client (SMOOTH TERRAIN WITH SHADOWS)"); SetTargetFPS(120); char myName[USERNAME_MAX]; @@ -441,6 +555,16 @@ int main(void) { terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){80, 140, 70, 255}; + // Setup directional light + DirectionalLight dirLight = {0}; + dirLight.direction = + v3_normalize(v3(-0.8f, -1.0f, -0.6f)); // Coming from upper-left-back + dirLight.color = v3(1.0f, 1.0f, 1.0f); + dirLight.intensity = 1.2f; + dirLight.ambientIntensity = 0.3f; + dirLight.shadowBias = 0.005f; + dirLight.shadowIntensity = 0.4f; + int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { perror("socket"); @@ -672,10 +796,20 @@ int main(void) { BeginMode3D(cam); - // Draw smooth terrain + // Calculate terrain normal at camera position for lighting + Vector3 terrainNormal = v3(0, 1, 0); // Default up normal + + // Draw smooth terrain with directional lighting + shadows + // For Raylib, we apply lighting by adjusting material colors + Color terrainBaseColor = (Color){80, 140, 70, 255}; + Color litTerrainColor = apply_lighting_with_shadows( + terrainBaseColor, terrainNormal, v3(0, 2, 0), dirLight); + + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = + litTerrainColor; DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE); - // Items + // Items with lighting and shadows for (int i = 0; i < MAX_ITEMS; i++) { if (!wi[i].present) continue; @@ -686,10 +820,14 @@ int main(void) { ic = (Color){255, 220, 120, 255}; if (wi[i].type == ITEM_AMMO_RIFLE) ic = (Color){255, 180, 120, 255}; - DrawSphere(wi[i].pos, 0.3f, ic); + + // Apply lighting with shadows to items + Color litColor = + apply_lighting_with_shadows(ic, terrainNormal, wi[i].pos, dirLight); + DrawSphere(wi[i].pos, 0.3f, litColor); } - // Players + // Players with lighting and shadows for (int i = 0; i < MAX_PLAYERS; i++) { if (!rp[i].present) continue; @@ -698,8 +836,12 @@ int main(void) { (i == myId) ? (Color){80, 180, 255, 255} : (Color){255, 80, 80, 255}; if (!rp[i].alive) c = (Color){120, 120, 120, 255}; + + // Apply lighting with shadows to player models + Color litPlayerColor = + apply_lighting_with_shadows(c, terrainNormal, p, dirLight); DrawCapsule(v3(p.x, p.y - 0.5f, p.z), v3(p.x, p.y + 0.5f, p.z), 0.35f, 8, - 8, c); + 8, litPlayerColor); } EndMode3D(); diff --git a/game/server b/game/server deleted file mode 100755 index c460ae13d219541e91533893bf27f2e6f839b19e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36424 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