From ed403627ea1934fb41b187027ae852265b5a410e Mon Sep 17 00:00:00 2001 From: cwj3rcb Date: Sun, 31 Aug 2025 15:22:25 -0500 Subject: [PATCH] Resolving mismatch --- main.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 23 deletions(-) diff --git a/main.c b/main.c index 662b84a..5f9d4dd 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,11 @@ #include "raylib.h" #include "rcamera.h" #include "raymath.h" -#include -#include +#include "stdbool.h" +#include "stddef.h" +#include "stdlib.h" +#include "stdint.h" +#include "time.h" //---------------------------------------------------------------------------------- // Defines and Macros @@ -30,11 +33,40 @@ #define NORMALIZE_INPUT 0 #define ARRLEN(a) (sizeof(a) / sizeof((a)[0])) +#define FLOOR_EXTENT 25 +#define TILE_SIZE 5.0f + enum game_state { STATE_MENU, // 0 by default STATE_GAME, // 1 }; +//---------------------------------------------------------------------------------- +// RNG +//---------------------------------------------------------------------------------- +// One-time world seed (set in main) +static uint32_t gWorldSeed = 123456789u; + +// Fast 2D int hash → stable pseudo-random per cell +static inline uint32_t hash2i(int x, int z, uint32_t seed) +{ + uint32_t h = (uint32_t)x * 374761393u ^ (uint32_t)z * 668265263u ^ seed * 2654435761u; + h ^= h >> 13; h *= 1274126177u; h ^= h >> 16; + return h; +} + +// 1-in-N chance using a hashed value +static inline bool one_in_n(uint32_t h, int n) +{ + return (h % (uint32_t)n) == 0u; +} + +// Map a few hash bits to [-0.5, +0.5] for jitter +static inline float hash01_to_m05p05(uint32_t h_bits) +{ + return ((h_bits & 0xFFu) / 255.0f) - 0.5f; +} + //---------------------------------------------------------------------------------- //Defining program structure //---------------------------------------------------------------------------------- @@ -91,6 +123,8 @@ void UpdateBody(Master* g, float rot, char side, char forward, bool jumpPressed, static void UpdateCameraAngle(Master* g); static void DrawLevel(Model mdlTile); static void CenterMouseAndFlush(void); +int Random(int x); +static void RenderTrees(Master* g, Texture2D tree, Vector3 treepos, float treeSize); //------------------------------------------------------------------------------------ // Program main entry point @@ -160,7 +194,7 @@ int main(void) Texture2D tree = LoadTexture("resources/sprites/tree.png"); GenTextureMipmaps(&tree); SetTextureFilter(tree, TEXTURE_FILTER_BILINEAR); // optional but looks nicer - Vector3 treepos = (Vector3){ 0.0f, 7.0f, 0.0f }; // where in 3D world to place it + Vector3 treepos = (Vector3){ 0.0f, 0.0f, 0.0f }; // where in 3D world to place it float treeSize = 15.0f; // billboard height in world units // --- Grass tile setup --- @@ -179,7 +213,7 @@ int main(void) Shader shAlphaClip = LoadShaderFromMemory(NULL, ALPHA_CLIP_FS); int locCutoff = GetShaderLocation(shAlphaClip, "u_alphaCutoff"); float cutoff = 0.3f; // tweak to taste; 0.3 - 0.5 works well for tree PNGs - SetShaderValue(shAlphaClip, locCutoff, &cutoff, SHADER_UNIFORM_FLOAT); + SetShaderValue(shAlphaClip, locCutoff, &cutoff, SHADER_UNIFORM_FLOAT); //-------------------------------------------------------------------------------------- // Main game loop @@ -268,15 +302,13 @@ int main(void) - + /* int bbdifx = g.player.position.x - bbPos.x; int bbdifz = g.player.position.z - bbPos.z; bbPos.x += 0.01 * bbdifx; bbPos.z += 0.01 * bbdifz; - - treepos = (Vector3){ 0.0f, 7.0f, 0.0f }; - + */ break; }; } @@ -305,21 +337,11 @@ int main(void) BeginShaderMode(shAlphaClip); { - // Draw your trees here with DrawBillboard / DrawBillboardPro - // Example using your positions: - DrawBillboard(g.player.camera, tree, treepos, treeSize, WHITE); - - Vector3 p = treepos; - p.x += 3*5; p.z += 3*5; DrawBillboard(g.player.camera, tree, p, treeSize, WHITE); - p.x += 5*5; p.z += -2*5; DrawBillboard(g.player.camera, tree, p, treeSize, WHITE); - p.x += -4*5; p.z += 3*5; DrawBillboard(g.player.camera, tree, p, treeSize, WHITE); - p.x += 9*5; p.z += 10*5; DrawBillboard(g.player.camera, tree, p, treeSize, WHITE); - - // Your sign as a cutout too (if it has a clean alpha) + RenderTrees(&g, tree, treepos, treeSize); } EndShaderMode(); - DrawBillboard(g.player.camera, sign, bbPos, bbSize, WHITE); + //DrawBillboard(g.player.camera, sign, bbPos, bbSize, WHITE); //This was the texture chasing you. EndMode3D(); // Draw info box @@ -522,8 +544,8 @@ static void UpdateCameraAngle(Master* g) // Draw game level static void DrawLevel(Model mdlTile) { - const int floorExtent = 25; - const float tileSize = 5.0f; + const int floorExtent = FLOOR_EXTENT; + const float tileSize = TILE_SIZE; const Color tileColor1 = (Color){ 150, 200, 200, 255 }; // Floor tiles @@ -574,7 +596,70 @@ static void DrawLevel(Model mdlTile) } //fix mouse -static void CenterMouseAndFlush() { +static void CenterMouseAndFlush() +{ SetMousePosition(GetRenderWidth()/2, GetRenderHeight()/2); (void)GetMouseDelta(); +} + +//Random number gen +int Random(int x) +{ + int r = (rand() % x) + 1; // 1–40 + return r; +} + +static inline void DrawTreeBillboardStable(Camera cam, Texture2D tex, Vector3 groundPos, float heightWorld, Color tint) +{ + // Keep sprite aspect ratio + float aspect = (float)tex.width / (float)tex.height; + Vector2 size = (Vector2){ heightWorld * aspect, heightWorld }; + + // Bottom-center pivot so base sits on groundPos.y + Vector2 origin = (Vector2){ 0.5f, 0.75f }; + + // Fixed world up (ignore camera.up roll) + Vector3 up = (Vector3){ 0, 1, 0 }; + + Rectangle src = (Rectangle){ 0, 0, (float)tex.width, (float)tex.height }; + DrawBillboardPro(cam, tex, src, groundPos, up, size, origin, 0.0f, tint); +} + +static void RenderTrees(Master* g, Texture2D tree, Vector3 baseTreePos, float treeSize) +{ + const int floorExtent = FLOOR_EXTENT; + const float tileSize = TILE_SIZE; + + // Placement knobs + const int densityA = 10; // 1-in-10 on (odd,odd) + const int densityB = 20; // 1-in-14 on (even,even) + const float jitter = tileSize * 0.35f; // random in-tile offset + + const float groundY = baseTreePos.y; // <-- use this as terrain height + + for (int z = -floorExtent; z < floorExtent; ++z) + for (int x = -floorExtent; x < floorExtent; ++x) + { + uint32_t h = hash2i(x, z, gWorldSeed); + uint32_t hA = h; + uint32_t hB = h * 0x9E3779B1u + 0x85EBCA6Bu; + + // (odd,odd) + if ((z & 1) && (x & 1) && one_in_n(hA, densityA)) { + float ox = hash01_to_m05p05(hA) * jitter; + float oz = hash01_to_m05p05(hA >> 8) * jitter; + + Vector3 pos = { x*tileSize + ox, groundY, z*tileSize + oz }; + DrawTreeBillboardStable(g->player.camera, tree, pos, /*height*/ treeSize, WHITE); + } + + // (even,even) + if (!(z & 1) && !(x & 1) && one_in_n(hB, densityB)) { + float ox = hash01_to_m05p05(hB) * jitter; + float oz = hash01_to_m05p05(hB >> 8) * jitter; + + Vector3 pos = { x*tileSize + ox, groundY, z*tileSize + oz }; + DrawTreeBillboardStable(g->player.camera, tree, pos, /*height*/ treeSize, WHITE); + } + } } \ No newline at end of file