diff --git a/raycaster.c b/raycaster.c index 2b695c0..dc4ef67 100644 --- a/raycaster.c +++ b/raycaster.c @@ -8,7 +8,7 @@ #define DR 0.0174533f // One degree in radians #define gameWidth 320 -#define gameHeight 160 +#define gameHeight 256 #define GAP 20 @@ -23,6 +23,29 @@ // 270° => 3π/2 radians (BOTTOM) // 360° => 2π radians (RIGHT) +// * Define the world +int mapX = 8, mapY = 8, mapSize = 32; + +// clang-format off +int map[] = +{ + 1,1,1,1,1,1,1,1, + 1,0,0,0,0,0,0,1, + 1,0,1,0,0,0,0,1, + 1,0,1,0,0,0,0,1, + 1,0,0,0,0,0,0,1, + 1,0,0,0,0,2,0,1, + 1,0,0,0,0,0,0,1, + 1,1,1,1,1,1,1,1, +}; +// clang-format on + +// Function to check if a number is a power of 2 +int isPowerOfTwo(int n) +{ + return (n > 0) && ((n & (n - 1)) == 0); +} + // * Player position (playerX, playerY), delta (playerDeltaX, playerDeltaY), and angle (pa) float playerX, playerY, playerDeltaX, playerDeltaY, playerAngle; @@ -44,26 +67,10 @@ void drawPlayer() glEnd(); } -// * Define the world -int mapX = 8, mapY = 8, mapSize = 64; - -// clang-format off -int map[] = -{ - 1,1,1,1,1,1,1,1, - 1,0,1,0,0,0,0,1, - 1,0,1,0,0,0,0,1, - 1,0,1,0,0,0,0,1, - 1,0,0,0,0,0,0,1, - 1,0,0,0,0,2,0,1, - 1,0,0,0,0,0,0,1, - 1,1,1,1,1,1,1,1, -}; -// clang-format on - // * Draws the top-down map with white alls and black floors void drawMap2D() { + int gridMapSize = mapSize; int x, y, xo, yo; for (y = 0; y < mapY; y++) { @@ -81,15 +88,15 @@ void drawMap2D() glColor3f(0, 0, 0); } - xo = x * mapSize; - yo = y * mapSize; + xo = x * gridMapSize; + yo = y * gridMapSize; glBegin(GL_QUADS); // Draw each block; the +-1 creates the outline glVertex2i(xo + 1, yo + 1); - glVertex2i(xo + 1, yo + mapSize - 1); - glVertex2i(xo + mapSize - 1, yo + mapSize - 1); - glVertex2i(xo + mapSize - 1, yo + 1); + glVertex2i(xo + 1, yo + gridMapSize - 1); + glVertex2i(xo + gridMapSize - 1, yo + gridMapSize - 1); + glVertex2i(xo + gridMapSize - 1, yo + 1); glEnd(); } } @@ -107,6 +114,16 @@ float dist(float ax, float ay, float bx, float by, float ang) void drawRays3D() { int r, mx, my, mapPoint, dof; + int gridMapSize = mapSize; + + // Ensure mapSize is a power of 2, otherwise default or handle error + if (!isPowerOfTwo(mapSize)) + { + fprintf(stderr, "Error: mapSize must be a power of 2 (e.g., 16, 32, 64, 128).\n"); + exit(1); + } + + int shiftSize = (int)(log2f((float)mapSize)); // Ray x, y, angle float rayX, rayY, rayAngle; @@ -151,9 +168,9 @@ void drawRays3D() if (rayAngle > PI) { // Round the ray's Y position to the nearest 64th value. - // We can do this by bit-shifting down by 6, then bit-shifting back up by - // 6. Then, we subtract a small amount for accuracy. - rayY = (((int)playerY >> 6) << 6) - 0.0001f; + // We can do this by bit-shifting down by `shiftSize`, then bit-shifting back up by + // `shiftSize`. Then, we subtract a small amount for accuracy. + rayY = (((int)playerY >> shiftSize) << shiftSize) - 0.0001f; // The ray's X value is the distance between the player and the ray's Y // position, times the inverse of tangent, plus the player's X position. @@ -161,7 +178,7 @@ void drawRays3D() // Now that we have the ray's first grid intersection position, we need // the next X and Y offset for the second grid intersection point. - yo = -64; + yo = -gridMapSize; xo = -yo * aTan; } @@ -170,13 +187,13 @@ void drawRays3D() { // This is almost exactly the same as looking up, but we add one grid // unit, instead of subtracting a tiny amount. - rayY = (((int)playerY >> 6) << 6) + 64; + rayY = (((int)playerY >> shiftSize) << shiftSize) + gridMapSize; rayX = (playerY - rayY) * aTan + playerX; // This is almost exactly the same as looking up, but we add instead of // subtract. - yo = 64; + yo = gridMapSize; xo = -yo * aTan; } @@ -198,8 +215,8 @@ void drawRays3D() // to know where that is in the map array. // Let's take the ray hit position (rx,ry) and divide it by 64 (bit-shift // 6 places), and use that to find the position in the map's array. - mx = (int)(rayX) >> 6; - my = (int)(rayY) >> 6; + mx = (int)(rayX) >> shiftSize; + my = (int)(rayY) >> shiftSize; mapPoint = my * mapX + mx; // If the map position is less than the array's size, then we can check it @@ -238,18 +255,18 @@ void drawRays3D() // ? Looking left if (rayAngle > PI2 && rayAngle < PI3) { - rayX = (((int)playerX >> 6) << 6) - 0.0001f; + rayX = (((int)playerX >> shiftSize) << shiftSize) - 0.0001f; rayY = (playerX - rayX) * nTan + playerY; - xo = -64; + xo = -gridMapSize; yo = -xo * nTan; } // ? Looking right if (rayAngle < PI2 || rayAngle > PI3) { - rayX = (((int)playerX >> 6) << 6) + 64; + rayX = (((int)playerX >> shiftSize) << shiftSize) + gridMapSize; rayY = (playerX - rayX) * nTan + playerY; - xo = 64; + xo = gridMapSize; yo = -xo * nTan; } @@ -266,8 +283,8 @@ void drawRays3D() // to know where that is in the map array. // Let's take the ray hit position (rx,ry) and divide it by 64 (bit-shift // 6 places), and use that to find the position in the map's array. - mx = (int)(rayX) >> 6; - my = (int)(rayY) >> 6; + mx = (int)(rayX) >> shiftSize; + my = (int)(rayY) >> shiftSize; mapPoint = my * mapX + mx; // If the map position is less than the array's size, then we can check it @@ -512,6 +529,7 @@ void buttons(unsigned char key, int x, int y) void init() { + // Sets the screen to the given color (grey) glClearColor(0.3, 0.3, 0.3, 0);