Hello all! As you may or may not have seen in discord and cemetech SAX, I am working with AI to create a 3D Minecraft game for the TI-84 Plus CE.
The program is written in C, and it could probably be ported later to asm for faster speeds.

Current features:
- 16x16x4 world.
- Only 1 block: grass.
- Camera movement
- Player movement
- Flying up and down

Here are images of the progress from the beginning:




Link to imgur album:
https://imgur.com/a/YGgTZjU
Finally time for an update!




Features:
- Generation using noise. 0 returns superflat, the input is broken though. That will be fixed later.
- Semi-working backface culling. Still trying to work out the kinks.
- FPS counter in place.
- FOV can be altered from source code. I haven't added any options screen for this though.
- Blinking cursor partially works (still testing with dot projection values to fix that).
- World Size increased to a single chunk, 16x16x16 blocks.
- Each face is textured with 2 colors per face per cube, modifiable in the color sheet.

The program currently is 14985 bytes. Quite small for such a world size, thanks to the compression lol

Future implementations/experiments:

- Realtime generation of a level appvar, it will generate more chunks and store in there and dynamically load from the appvar into the current world array.
- Placing and destroying blocks when the cursor is stable.

I wrote this with ChatGPT, going back and forth trying optimization after optimization to the rendering. I kind of understand 3D Projection now.

Here's the github:
https://github.com/TimmyTurner51/Minecraft-3D-CE
I have done something similar with ai but it was... janky to say the least

Code:

#include <graphx.h>
#include <math.h>
#include <stdint.h>
#include <keypadc.h>

// Define palette-safe colors
#define BLUE    16  // Blue (background)
#define GREEN   3   // Green (blocks)
#define GRAY    7   // Gray (bedrock)

#define WIDTH 5
#define HEIGHT 5
#define DEPTH 5

#define CUBE_SIZE 10
#define SCREEN_CENTER_X 160
#define SCREEN_CENTER_Y 120

uint8_t world[WIDTH][HEIGHT][DEPTH];

// Camera position and rotation
float cameraX = 2.5f, cameraY = 2.5f, cameraZ = -5.0f; // Start behind the world
float cameraYaw = 0.0f, cameraPitch = 0.0f;            // Camera rotation angles

// Initialize the 3D world with some blocks
void initializeWorld() {
    for (int z = 0; z < DEPTH; z++) {
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                if (y == HEIGHT - 1) {
                    world[x][y][z] = 1; // Bedrock
                } else {
                    world[x][y][z] = 0; // Empty space
                }
            }
        }
    }

    // Example: Adding some green blocks
    world[2][3][2] = 2; // Green block
}

// Perspective projection of a 3D point
void projectPoint(float x, float y, float z, int *px, int *py) {
    // Transform point based on camera position and rotation
    float dx = x - cameraX;
    float dy = y - cameraY;
    float dz = z - cameraZ;

    float cosYaw = cos(cameraYaw), sinYaw = sin(cameraYaw);
    float cosPitch = cos(cameraPitch), sinPitch = sin(cameraPitch);

    // Rotate around the Y-axis (yaw)
    float tempX = cosYaw * dx - sinYaw * dz;
    float tempZ = sinYaw * dx + cosYaw * dz;

    // Rotate around the X-axis (pitch)
    float tempY = cosPitch * dy - sinPitch * tempZ;
    tempZ = sinPitch * dy + cosPitch * tempZ;

    // Simple perspective projection
    float fov = 90.0f;          // Field of view
    float viewerDistance = 5.0; // Distance from the camera to the screen

    float factor = fov / (viewerDistance + tempZ);
    *px = SCREEN_CENTER_X + (int)(tempX * factor);
    *py = SCREEN_CENTER_Y - (int)(tempY * factor);
}

// Check for collisions
int isCollision(float x, float y, float z) {
    int blockX = (int)x;
    int blockY = (int)y;
    int blockZ = (int)z;

    if (blockX >= 0 && blockX < WIDTH &&
        blockY >= 0 && blockY < HEIGHT &&
        blockZ >= 0 && blockZ < DEPTH) {
        return world[blockX][blockY][blockZ] != 0; // Return true if block is not empty
    }
    return 1; // Collide with the boundary
}

// Handle keyboard input for movement
void handleMovement() {
    kb_Scan();

    float moveSpeed = 0.1f;
    float dx = 0, dy = 0, dz = 0;

    if (kb_IsDown(kb_KeyMode)) dz -= moveSpeed;    // Forward
    if (kb_IsDown(kb_KeyApps)) dz += moveSpeed;    // Backward
    if (kb_IsDown(kb_KeyStat)) dx += moveSpeed;    // Right
    if (kb_IsDown(kb_KeyAlpha)) dx -= moveSpeed;   // Left
    if (kb_IsDown(kb_KeyAdd)) dy += moveSpeed;     // Up
    if (kb_IsDown(kb_KeySub)) dy -= moveSpeed;     // Down

    // Check for collisions before moving
    if (!isCollision(cameraX + dx, cameraY, cameraZ)) cameraX += dx;
    if (!isCollision(cameraX, cameraY + dy, cameraZ)) cameraY += dy;
    if (!isCollision(cameraX, cameraY, cameraZ + dz)) cameraZ += dz;
}

// Handle keyboard input for looking
void handleLooking() {
    kb_Scan();

    float lookSpeed = 0.05f;

    if (kb_IsDown(kb_KeyUp)) {
        cameraPitch -= lookSpeed;   // Look up
        if (cameraPitch < -1.57f) cameraPitch = -1.57f; // Clamp to -90 degrees
    }
    if (kb_IsDown(kb_KeyDown)) {
        cameraPitch += lookSpeed;   // Look down
        if (cameraPitch > 1.57f) cameraPitch = 1.57f; // Clamp to +90 degrees
    }
    if (kb_IsDown(kb_KeyLeft)) {
        cameraYaw -= lookSpeed;   // Look left
        if (cameraYaw < -6.28f) cameraYaw += 6.28f; // Wrap yaw to avoid overflow
    }
    if (kb_IsDown(kb_KeyRight)) {
        cameraYaw += lookSpeed;   // Look right
        if (cameraYaw > 6.28f) cameraYaw -= 6.28f; // Wrap yaw to avoid overflow
    }
}

// Draw a 3D-like cube using projected 2D points
void drawCube(float x, float y, float z, uint8_t color) {
    int p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
    int p5x, p5y, p6x, p6y, p7x, p7y, p8x, p8y;

    // Project the 8 vertices of the cube
    projectPoint(x, y, z, &p1x, &p1y);
    projectPoint(x + CUBE_SIZE, y, z, &p2x, &p2y);
    projectPoint(x + CUBE_SIZE, y + CUBE_SIZE, z, &p3x, &p3y);
    projectPoint(x, y + CUBE_SIZE, z, &p4x, &p4y);

    projectPoint(x, y, z + CUBE_SIZE, &p5x, &p5y);
    projectPoint(x + CUBE_SIZE, y, z + CUBE_SIZE, &p6x, &p6y);
    projectPoint(x + CUBE_SIZE, y + CUBE_SIZE, z + CUBE_SIZE, &p7x, &p7y);
    projectPoint(x, y + CUBE_SIZE, z + CUBE_SIZE, &p8x, &p8y);

    // Draw faces of the cube (back to front for correct depth)
    gfx_SetColor(color - 3); // Darker for the back face
    gfx_FillTriangle(p5x, p5y, p6x, p6y, p7x, p7y); // Back face top triangle
    gfx_FillTriangle(p5x, p5y, p7x, p7y, p8x, p8y); // Back face bottom triangle

    gfx_SetColor(color - 2); // Side shading
    gfx_FillTriangle(p1x, p1y, p2x, p2y, p6x, p6y); // Side face
    gfx_FillTriangle(p1x, p1y, p6x, p6y, p5x, p5y);

    gfx_SetColor(color); // Front face
    gfx_FillTriangle(p1x, p1y, p2x, p2y, p3x, p3y);
    gfx_FillTriangle(p1x, p1y, p3x, p3y, p4x, p4y);
}

// Render the entire 3D world
void renderWorld() {
    gfx_FillScreen(BLUE); // Set the background to blue

    for (int z = DEPTH - 1; z >= 0; z--) { // Render back to front
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                if (world[x][y][z] == 1) {
                    drawCube(x * CUBE_SIZE, y * CUBE_SIZE, z * CUBE_SIZE, GRAY); // Bedrock
                } else if (world[x][y][z] == 2) {
                    drawCube(x * CUBE_SIZE, y * CUBE_SIZE, z * CUBE_SIZE, GREEN); // Green block
                }
            }
        }
    }
}

int main() {
    gfx_Begin(); // Initialize graphics mode
    gfx_SetDrawBuffer(); // Enable double buffering
    initializeWorld(); // Set up the 3D world

    while (1) {
        kb_Scan(); // Scan for key presses

        handleMovement(); // Handle movement
        handleLooking();  // Handle looking (camera rotation)

        // Exit when [CLEAR] is pressed
        if (kb_IsDown(kb_KeyClear)) {
            break;
        }

        renderWorld(); // Call the renderWorld function to draw the frame
        gfx_SwapDraw(); // Swap buffers to display the frame
    }

    gfx_End(); // Close graphics mode
    return 0; // Indicate successful execution
}
the CE guy wrote:
I have done something similar with ai but it was... janky to say the least

Code:

#include <graphx.h>
#include <math.h>
#include <stdint.h>
#include <keypadc.h>

// Define palette-safe colors
#define BLUE    16  // Blue (background)
#define GREEN   3   // Green (blocks)
#define GRAY    7   // Gray (bedrock)

#define WIDTH 5
#define HEIGHT 5
#define DEPTH 5

#define CUBE_SIZE 10
#define SCREEN_CENTER_X 160
#define SCREEN_CENTER_Y 120

uint8_t world[WIDTH][HEIGHT][DEPTH];

// Camera position and rotation
float cameraX = 2.5f, cameraY = 2.5f, cameraZ = -5.0f; // Start behind the world
float cameraYaw = 0.0f, cameraPitch = 0.0f;            // Camera rotation angles

// Initialize the 3D world with some blocks
void initializeWorld() {
    for (int z = 0; z < DEPTH; z++) {
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                if (y == HEIGHT - 1) {
                    world[x][y][z] = 1; // Bedrock
                } else {
                    world[x][y][z] = 0; // Empty space
                }
            }
        }
    }

    // Example: Adding some green blocks
    world[2][3][2] = 2; // Green block
}

// Perspective projection of a 3D point
void projectPoint(float x, float y, float z, int *px, int *py) {
    // Transform point based on camera position and rotation
    float dx = x - cameraX;
    float dy = y - cameraY;
    float dz = z - cameraZ;

    float cosYaw = cos(cameraYaw), sinYaw = sin(cameraYaw);
    float cosPitch = cos(cameraPitch), sinPitch = sin(cameraPitch);

    // Rotate around the Y-axis (yaw)
    float tempX = cosYaw * dx - sinYaw * dz;
    float tempZ = sinYaw * dx + cosYaw * dz;

    // Rotate around the X-axis (pitch)
    float tempY = cosPitch * dy - sinPitch * tempZ;
    tempZ = sinPitch * dy + cosPitch * tempZ;

    // Simple perspective projection
    float fov = 90.0f;          // Field of view
    float viewerDistance = 5.0; // Distance from the camera to the screen

    float factor = fov / (viewerDistance + tempZ);
    *px = SCREEN_CENTER_X + (int)(tempX * factor);
    *py = SCREEN_CENTER_Y - (int)(tempY * factor);
}

// Check for collisions
int isCollision(float x, float y, float z) {
    int blockX = (int)x;
    int blockY = (int)y;
    int blockZ = (int)z;

    if (blockX >= 0 && blockX < WIDTH &&
        blockY >= 0 && blockY < HEIGHT &&
        blockZ >= 0 && blockZ < DEPTH) {
        return world[blockX][blockY][blockZ] != 0; // Return true if block is not empty
    }
    return 1; // Collide with the boundary
}

// Handle keyboard input for movement
void handleMovement() {
    kb_Scan();

    float moveSpeed = 0.1f;
    float dx = 0, dy = 0, dz = 0;

    if (kb_IsDown(kb_KeyMode)) dz -= moveSpeed;    // Forward
    if (kb_IsDown(kb_KeyApps)) dz += moveSpeed;    // Backward
    if (kb_IsDown(kb_KeyStat)) dx += moveSpeed;    // Right
    if (kb_IsDown(kb_KeyAlpha)) dx -= moveSpeed;   // Left
    if (kb_IsDown(kb_KeyAdd)) dy += moveSpeed;     // Up
    if (kb_IsDown(kb_KeySub)) dy -= moveSpeed;     // Down

    // Check for collisions before moving
    if (!isCollision(cameraX + dx, cameraY, cameraZ)) cameraX += dx;
    if (!isCollision(cameraX, cameraY + dy, cameraZ)) cameraY += dy;
    if (!isCollision(cameraX, cameraY, cameraZ + dz)) cameraZ += dz;
}

// Handle keyboard input for looking
void handleLooking() {
    kb_Scan();

    float lookSpeed = 0.05f;

    if (kb_IsDown(kb_KeyUp)) {
        cameraPitch -= lookSpeed;   // Look up
        if (cameraPitch < -1.57f) cameraPitch = -1.57f; // Clamp to -90 degrees
    }
    if (kb_IsDown(kb_KeyDown)) {
        cameraPitch += lookSpeed;   // Look down
        if (cameraPitch > 1.57f) cameraPitch = 1.57f; // Clamp to +90 degrees
    }
    if (kb_IsDown(kb_KeyLeft)) {
        cameraYaw -= lookSpeed;   // Look left
        if (cameraYaw < -6.28f) cameraYaw += 6.28f; // Wrap yaw to avoid overflow
    }
    if (kb_IsDown(kb_KeyRight)) {
        cameraYaw += lookSpeed;   // Look right
        if (cameraYaw > 6.28f) cameraYaw -= 6.28f; // Wrap yaw to avoid overflow
    }
}

// Draw a 3D-like cube using projected 2D points
void drawCube(float x, float y, float z, uint8_t color) {
    int p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
    int p5x, p5y, p6x, p6y, p7x, p7y, p8x, p8y;

    // Project the 8 vertices of the cube
    projectPoint(x, y, z, &p1x, &p1y);
    projectPoint(x + CUBE_SIZE, y, z, &p2x, &p2y);
    projectPoint(x + CUBE_SIZE, y + CUBE_SIZE, z, &p3x, &p3y);
    projectPoint(x, y + CUBE_SIZE, z, &p4x, &p4y);

    projectPoint(x, y, z + CUBE_SIZE, &p5x, &p5y);
    projectPoint(x + CUBE_SIZE, y, z + CUBE_SIZE, &p6x, &p6y);
    projectPoint(x + CUBE_SIZE, y + CUBE_SIZE, z + CUBE_SIZE, &p7x, &p7y);
    projectPoint(x, y + CUBE_SIZE, z + CUBE_SIZE, &p8x, &p8y);

    // Draw faces of the cube (back to front for correct depth)
    gfx_SetColor(color - 3); // Darker for the back face
    gfx_FillTriangle(p5x, p5y, p6x, p6y, p7x, p7y); // Back face top triangle
    gfx_FillTriangle(p5x, p5y, p7x, p7y, p8x, p8y); // Back face bottom triangle

    gfx_SetColor(color - 2); // Side shading
    gfx_FillTriangle(p1x, p1y, p2x, p2y, p6x, p6y); // Side face
    gfx_FillTriangle(p1x, p1y, p6x, p6y, p5x, p5y);

    gfx_SetColor(color); // Front face
    gfx_FillTriangle(p1x, p1y, p2x, p2y, p3x, p3y);
    gfx_FillTriangle(p1x, p1y, p3x, p3y, p4x, p4y);
}

// Render the entire 3D world
void renderWorld() {
    gfx_FillScreen(BLUE); // Set the background to blue

    for (int z = DEPTH - 1; z >= 0; z--) { // Render back to front
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                if (world[x][y][z] == 1) {
                    drawCube(x * CUBE_SIZE, y * CUBE_SIZE, z * CUBE_SIZE, GRAY); // Bedrock
                } else if (world[x][y][z] == 2) {
                    drawCube(x * CUBE_SIZE, y * CUBE_SIZE, z * CUBE_SIZE, GREEN); // Green block
                }
            }
        }
    }
}

int main() {
    gfx_Begin(); // Initialize graphics mode
    gfx_SetDrawBuffer(); // Enable double buffering
    initializeWorld(); // Set up the 3D world

    while (1) {
        kb_Scan(); // Scan for key presses

        handleMovement(); // Handle movement
        handleLooking();  // Handle looking (camera rotation)

        // Exit when [CLEAR] is pressed
        if (kb_IsDown(kb_KeyClear)) {
            break;
        }

        renderWorld(); // Call the renderWorld function to draw the frame
        gfx_SwapDraw(); // Swap buffers to display the frame
    }

    gfx_End(); // Close graphics mode
    return 0; // Indicate successful execution
}


Do know, I keep going back and forth, this was started like 2 weeks ago and we've only made it this far today. It mistakenly messed up convimg.yaml multiple times and tried gfx_FillPolygon and that doesn't exist. You have to be very descriptive of what's wrong and try providing images to the AI to further show it what's wrong. I'm paying literal money for this lol. It's just trial and error until something decent pops up.
TimmyTurner62 wrote:
the CE guy wrote:
I have done something similar with ai but it was... janky to say the least

Code:

#include <graphx.h>
#include <math.h>
#include <stdint.h>
#include <keypadc.h>

// Define palette-safe colors
#define BLUE    16  // Blue (background)
#define GREEN   3   // Green (blocks)
#define GRAY    7   // Gray (bedrock)

#define WIDTH 5
#define HEIGHT 5
#define DEPTH 5

#define CUBE_SIZE 10
#define SCREEN_CENTER_X 160
#define SCREEN_CENTER_Y 120

uint8_t world[WIDTH][HEIGHT][DEPTH];

// Camera position and rotation
float cameraX = 2.5f, cameraY = 2.5f, cameraZ = -5.0f; // Start behind the world
float cameraYaw = 0.0f, cameraPitch = 0.0f;            // Camera rotation angles

// Initialize the 3D world with some blocks
void initializeWorld() {
    for (int z = 0; z < DEPTH; z++) {
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                if (y == HEIGHT - 1) {
                    world[x][y][z] = 1; // Bedrock
                } else {
                    world[x][y][z] = 0; // Empty space
                }
            }
        }
    }

    // Example: Adding some green blocks
    world[2][3][2] = 2; // Green block
}

// Perspective projection of a 3D point
void projectPoint(float x, float y, float z, int *px, int *py) {
    // Transform point based on camera position and rotation
    float dx = x - cameraX;
    float dy = y - cameraY;
    float dz = z - cameraZ;

    float cosYaw = cos(cameraYaw), sinYaw = sin(cameraYaw);
    float cosPitch = cos(cameraPitch), sinPitch = sin(cameraPitch);

    // Rotate around the Y-axis (yaw)
    float tempX = cosYaw * dx - sinYaw * dz;
    float tempZ = sinYaw * dx + cosYaw * dz;

    // Rotate around the X-axis (pitch)
    float tempY = cosPitch * dy - sinPitch * tempZ;
    tempZ = sinPitch * dy + cosPitch * tempZ;

    // Simple perspective projection
    float fov = 90.0f;          // Field of view
    float viewerDistance = 5.0; // Distance from the camera to the screen

    float factor = fov / (viewerDistance + tempZ);
    *px = SCREEN_CENTER_X + (int)(tempX * factor);
    *py = SCREEN_CENTER_Y - (int)(tempY * factor);
}

// Check for collisions
int isCollision(float x, float y, float z) {
    int blockX = (int)x;
    int blockY = (int)y;
    int blockZ = (int)z;

    if (blockX >= 0 && blockX < WIDTH &&
        blockY >= 0 && blockY < HEIGHT &&
        blockZ >= 0 && blockZ < DEPTH) {
        return world[blockX][blockY][blockZ] != 0; // Return true if block is not empty
    }
    return 1; // Collide with the boundary
}

// Handle keyboard input for movement
void handleMovement() {
    kb_Scan();

    float moveSpeed = 0.1f;
    float dx = 0, dy = 0, dz = 0;

    if (kb_IsDown(kb_KeyMode)) dz -= moveSpeed;    // Forward
    if (kb_IsDown(kb_KeyApps)) dz += moveSpeed;    // Backward
    if (kb_IsDown(kb_KeyStat)) dx += moveSpeed;    // Right
    if (kb_IsDown(kb_KeyAlpha)) dx -= moveSpeed;   // Left
    if (kb_IsDown(kb_KeyAdd)) dy += moveSpeed;     // Up
    if (kb_IsDown(kb_KeySub)) dy -= moveSpeed;     // Down

    // Check for collisions before moving
    if (!isCollision(cameraX + dx, cameraY, cameraZ)) cameraX += dx;
    if (!isCollision(cameraX, cameraY + dy, cameraZ)) cameraY += dy;
    if (!isCollision(cameraX, cameraY, cameraZ + dz)) cameraZ += dz;
}

// Handle keyboard input for looking
void handleLooking() {
    kb_Scan();

    float lookSpeed = 0.05f;

    if (kb_IsDown(kb_KeyUp)) {
        cameraPitch -= lookSpeed;   // Look up
        if (cameraPitch < -1.57f) cameraPitch = -1.57f; // Clamp to -90 degrees
    }
    if (kb_IsDown(kb_KeyDown)) {
        cameraPitch += lookSpeed;   // Look down
        if (cameraPitch > 1.57f) cameraPitch = 1.57f; // Clamp to +90 degrees
    }
    if (kb_IsDown(kb_KeyLeft)) {
        cameraYaw -= lookSpeed;   // Look left
        if (cameraYaw < -6.28f) cameraYaw += 6.28f; // Wrap yaw to avoid overflow
    }
    if (kb_IsDown(kb_KeyRight)) {
        cameraYaw += lookSpeed;   // Look right
        if (cameraYaw > 6.28f) cameraYaw -= 6.28f; // Wrap yaw to avoid overflow
    }
}

// Draw a 3D-like cube using projected 2D points
void drawCube(float x, float y, float z, uint8_t color) {
    int p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
    int p5x, p5y, p6x, p6y, p7x, p7y, p8x, p8y;

    // Project the 8 vertices of the cube
    projectPoint(x, y, z, &p1x, &p1y);
    projectPoint(x + CUBE_SIZE, y, z, &p2x, &p2y);
    projectPoint(x + CUBE_SIZE, y + CUBE_SIZE, z, &p3x, &p3y);
    projectPoint(x, y + CUBE_SIZE, z, &p4x, &p4y);

    projectPoint(x, y, z + CUBE_SIZE, &p5x, &p5y);
    projectPoint(x + CUBE_SIZE, y, z + CUBE_SIZE, &p6x, &p6y);
    projectPoint(x + CUBE_SIZE, y + CUBE_SIZE, z + CUBE_SIZE, &p7x, &p7y);
    projectPoint(x, y + CUBE_SIZE, z + CUBE_SIZE, &p8x, &p8y);

    // Draw faces of the cube (back to front for correct depth)
    gfx_SetColor(color - 3); // Darker for the back face
    gfx_FillTriangle(p5x, p5y, p6x, p6y, p7x, p7y); // Back face top triangle
    gfx_FillTriangle(p5x, p5y, p7x, p7y, p8x, p8y); // Back face bottom triangle

    gfx_SetColor(color - 2); // Side shading
    gfx_FillTriangle(p1x, p1y, p2x, p2y, p6x, p6y); // Side face
    gfx_FillTriangle(p1x, p1y, p6x, p6y, p5x, p5y);

    gfx_SetColor(color); // Front face
    gfx_FillTriangle(p1x, p1y, p2x, p2y, p3x, p3y);
    gfx_FillTriangle(p1x, p1y, p3x, p3y, p4x, p4y);
}

// Render the entire 3D world
void renderWorld() {
    gfx_FillScreen(BLUE); // Set the background to blue

    for (int z = DEPTH - 1; z >= 0; z--) { // Render back to front
        for (int y = 0; y < HEIGHT; y++) {
            for (int x = 0; x < WIDTH; x++) {
                if (world[x][y][z] == 1) {
                    drawCube(x * CUBE_SIZE, y * CUBE_SIZE, z * CUBE_SIZE, GRAY); // Bedrock
                } else if (world[x][y][z] == 2) {
                    drawCube(x * CUBE_SIZE, y * CUBE_SIZE, z * CUBE_SIZE, GREEN); // Green block
                }
            }
        }
    }
}

int main() {
    gfx_Begin(); // Initialize graphics mode
    gfx_SetDrawBuffer(); // Enable double buffering
    initializeWorld(); // Set up the 3D world

    while (1) {
        kb_Scan(); // Scan for key presses

        handleMovement(); // Handle movement
        handleLooking();  // Handle looking (camera rotation)

        // Exit when [CLEAR] is pressed
        if (kb_IsDown(kb_KeyClear)) {
            break;
        }

        renderWorld(); // Call the renderWorld function to draw the frame
        gfx_SwapDraw(); // Swap buffers to display the frame
    }

    gfx_End(); // Close graphics mode
    return 0; // Indicate successful execution
}


Do know, I keep going back and forth, this was started like 2 weeks ago and we've only made it this far today. It mistakenly messed up convimg.yaml multiple times and tried gfx_FillPolygon and that doesn't exist. You have to be very descriptive of what's wrong and try providing images to the AI to further show it what's wrong. I'm paying literal money for this 0x5. It's just trial and error until something decent pops up.

It wasn't going to be a long term project but it worked better than i thought there is also basic camera movement which surprisingly didn't take more than 10 prompts to get right.
Edit: it also tried nonexistent functions multiple times for me also but every time it did I fed it the error message and it fixed it.
NOTE: Do not run this on your calc without backing it up first! This version is a bit unstable and can cause crashes and hangs where you must reset to continue using the calculator, or it can reset it itself upon exiting the program. It's a bug I'll work out. AGAIN! BACK UP YOUR CALC!

Update time!




After long hours of testing (while being sick) and back and forth refactoring, we now have an update!
- Seed input (my theory is 0 returns superflat, why real Minecraft randomizes a blank seed, 0 makes Perlin Noise generation break as seen here)
- Block highlighting (cursor)
- FPS Counter
- Texture mapping
- If not already posted before, full 16x16x16 chunk is generated
- Render distance (not featured yet)
- FOV (not featured yet, default 90).

Source code: https://github.com/TimmyTurner51/Minecraft-3D-CE

Backface culling is still kinda broken in second image...
Next is hotbar, inventory, and placing and destroying blocks. Also need more things like trees added and it's basically good to go from there.
More updates to come!
This is very cool! Speed is pretty good considering what it's trying to do.

Once you get BFC and clipping sorted it will look even better, but it's a fantastic start! Smile
Looks cool! Shock
Really cool!
Laughing
Update time!




I need help though, I have a C function that needs to be rewritten to ASM in hopes of a speedup. It's currently unthrottled in CEmu but completely unplayable like this on a real CE (unless by chance there's some hidden insane speedup hack haha)
Do note, floats are there still because swapping everything to ints just broke everything.

Code:

Code:

void drawTexturedTriangle(int x0, int y0, int x1, int y1, int x2, int y2,
                          float u0, float v0, float u1, float v1, float u2, float v2,
                          uint8_t *texture, int tileWidth, int tileHeight) {
    int iu0 = (int)(u0 * tileWidth * FIXED_ONE);
    int iv0 = (int)(v0 * tileHeight * FIXED_ONE);
    int iu1 = (int)(u1 * tileWidth * FIXED_ONE);
    int iv1 = (int)(v1 * tileHeight * FIXED_ONE);
    int iu2 = (int)(u2 * tileWidth * FIXED_ONE);
    int iv2 = (int)(v2 * tileHeight * FIXED_ONE);

    int minX = fminf(fminf(x0, x1), x2) / renderResolution * renderResolution;
    int maxX = fmaxf(fmaxf(x0, x1), x2) / renderResolution * renderResolution;
    int minY = fminf(fminf(y0, y1), y2) / renderResolution * renderResolution;
    int maxY = fmaxf(fmaxf(y0, y1), y2) / renderResolution * renderResolution;

    int denom = (y1 - y2)*(x0 - x2) + (x2 - x1)*(y0 - y2);
    if (denom == 0) return;

    for (int y = minY; y <= maxY; y += renderResolution) {
        for (int x = minX; x <= maxX; x += renderResolution) {
            int w1_fp = (((y1 - y2)*(x - x2) + (x2 - x1)*(y - y2)) << FIXED_SHIFT) / denom;
            int w2_fp = (((y2 - y0)*(x - x2) + (x0 - x2)*(y - y2)) << FIXED_SHIFT) / denom;
            int w3_fp = FIXED_ONE - w1_fp - w2_fp;

            if (w1_fp >= 0 && w2_fp >= 0 && w3_fp >= 0) {
                int iu = (MUL_FIXED(iu0, w1_fp) + MUL_FIXED(iu1, w2_fp) + MUL_FIXED(iu2, w3_fp)) >> FIXED_SHIFT;
                int iv = (MUL_FIXED(iv0, w1_fp) + MUL_FIXED(iv1, w2_fp) + MUL_FIXED(iv2, w3_fp)) >> FIXED_SHIFT;
                // Wrap UVs safely before indexing
                iu %= tileWidth;
                iv %= tileHeight;
                if (iu < 0) iu += tileWidth;
                if (iv < 0) iv += tileHeight;

                // Clamp as fallback to prevent overflows (optional)
                if (iu >= tileWidth) iu = tileWidth - 1;
                if (iv >= tileHeight) iv = tileHeight - 1;

                uint8_t color = texture[iv * tileWidth + iu];
                gfx_SetColor(color);
                gfx_FillRectangle(x, y, renderResolution, renderResolution);
            }
        }
    }
}
TimmyTurner62 wrote:
I need help though, I have a C function that needs to be rewritten to ASM in hopes of a speedup. It's currently unthrottled in CEmu but completely unplayable like this on a real CE (unless by chance there's some hidden insane speedup hack haha)
Do note, floats are there still because swapping everything to ints just broke everything.


It could speed up if you define the variables once instead of every time you call the function. Another solution is using bitwise operators instead of built in math functions, but I wouldn't know how, that's something you'd have to look into. Same goes with assembly, it would help a bit but I know nothing of it.
I think switching to fixed-point with integers is going to be your best option to speed this up, assuming you're already using the display in half-resolution mode for an additional speedup.
Pre-Alpha v6.14.25a2 is here. Completely remade. Here is the int reiteration.
Repo: https://github.com/TimmyTurner51/Minecraft-CE/tree/main
Preview:
Features (full set in github):
Working hotbar
Place blocks
Destroy blocks
You are given an empty slot, grass, dirt, tree log, tree leaves by default.
Rendering still needs fix up and speed up and the player cursors dot projection is a bit loose. I'll fix that tmr or something. Imagine mobs.

This thing needs a nice name at this point. CraftCE? Something new. I mean MC3D is meh L :/
I hope this works out, the screenshots are great. I just hope that the ez80 cpu can handle that much without exploding. Smile
As for the name... Start a poll instead?
If this doesn't already exist, I suggest CEcraft for the name.
MinCEraft would be a good name. Also this looks super cool
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement