1 MILLION+ COLORS WITHOUT PALETTE CHANGE (technically)

this is not fully completed yet, but this is a simple brightness simulator using rgb colors. it never changes the palette during run time, palette is: “#000000”,“#330000”,“#660000”,“#990000”,“#CC0000”,“#FF0000”,“#003300”,“#006600”,“#009900”,“#00CC00”,“#00FF00”,“#000033”,“#000066”,“#000099”,“#0000CC”,“#0000FF

i am using this to create a game with more than 16 colors. If anybody uses this dont make the screen big because it will lag like crazy. also make sure to pre “dither“ your images, or lag will come.

8 Likes

You can use titlemaps as seen here

And by changing the screen size.
You can also use the colors extension to change the brightness of the rgb colors.

2 Likes

I don’t understand most of this
Very impressive I’ll give you that

2 Likes

Here’s a better example

1 Like

Also i get the importedImage variable through anything that turns an image into raw rgb (im using Photopea), and use this c++ code:

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>
#include <algorithm>

struct Color {
    int r, g, b;
};

std::array<Color, 16> PALETTE = { {
    {0x00,0x00,0x00},
    {0x33,0x00,0x00}, {0x66,0x00,0x00}, {0x99,0x00,0x00}, {0xCC,0x00,0x00}, {0xFF,0x00,0x00},
    {0x00,0x33,0x00}, {0x00,0x66,0x00}, {0x00,0x99,0x00}, {0x00,0xCC,0x00}, {0x00,0xFF,0x00},
    {0x00,0x00,0x33}, {0x00,0x00,0x66}, {0x00,0x00,0x99}, {0x00,0x00,0xCC}, {0x00,0x00,0xFF}
} };

// ---------------------
//  Closest palette color
// ---------------------
int closest(int r, int g, int b) {
    int best = 0;
    long bestDist = LONG_MAX;

    for (int i = 0; i < 16; i++) {
        int dr = PALETTE[i].r - r;
        int dg = PALETTE[i].g - g;
        int db = PALETTE[i].b - b;
        long dist = dr * dr + dg * dg + db * db;

        if (dist < bestDist) {
            bestDist = dist;
            best = i;
        }
    }
    return best;
}

// ---------------------
//  rgbToNumberArr (C++ version)
// ---------------------
std::array<int, 9> rgbToNumberArr(int r, int g, int b) {
    double R = r, G = g, B = b;
    std::array<std::string, 9> pattern;

    auto toHexByte = [](int n) {
        const char* hex = "0123456789ABCDEF";
        n = std::max(0, std::min(255, n));
        std::string s;
        s += hex[(n >> 4) & 0xF];
        s += hex[n & 0xF];
        return s;
        };

    auto decode = [](const std::string& code) {
        char c = code[0];
        int v = std::stoi(code.substr(1), nullptr, 16);
        if (c == 'R') return Color{ v,0,0 };
        if (c == 'G') return Color{ 0,v,0 };
        return Color{ 0,0,v };
        };

    // Generate 9-pixel channel pattern
    for (int i = 0; i < 9; i++) {
        char channel = 'R';
        double value = R;

        if (G >= R && G >= B) { channel = 'G'; value = G; }
        else if (B >= R && B >= G) { channel = 'B'; value = B; }

        pattern[i] = std::string(1, channel) + toHexByte((int)value);

        if (channel == 'R') R -= r / 9.0;
        if (channel == 'G') G -= g / 9.0;
        if (channel == 'B') B -= b / 9.0;
    }

    // Convert to palette indices
    std::array<int, 9> out;
    for (int i = 0; i < 9; i++) {
        Color px = decode(pattern[i]);
        out[i] = closest(px.r, px.g, px.b);
    }

    return out;
}

// ---------------------
//  MAIN: RAW -> number[x][y][c]
// ---------------------
int main() {
    const int WIDTH = 144;   // <-- set your width
    const int HEIGHT = 81;  // <-- set your height

    // Load RAW file
    std::ifstream file("image.raw", std::ios::binary);
    std::vector<unsigned char> bytes(
        (std::istreambuf_iterator<char>(file)),
        std::istreambuf_iterator<char>()
    );

    if (bytes.size() != WIDTH * HEIGHT * 3) {
        std::cout << "ERROR: RAW file size does not match WIDTH*HEIGHT*3\n";
        return 1;
    }

    // Convert to pixel array
    std::vector<std::vector<Color>> pixels(HEIGHT, std::vector<Color>(WIDTH));
    int idx = 0;

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            pixels[y][x] = {
                bytes[idx++], // R
                bytes[idx++], // G
                bytes[idx++]  // B
            };
        }
    }

    // Convert to GPU tiles: number[x][y][c]
    std::vector<std::vector<std::array<int, 9>>> number(
        HEIGHT, std::vector<std::array<int, 9>>(WIDTH)
    );

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            Color c = pixels[y][x];
            number[y][x] = rgbToNumberArr(c.r, c.g, c.b);
        }
    }
	



    std::ofstream outFile("output.txt");
    if (!outFile.is_open()) {
        std::cout << "Failed to open output.txt\n";
        return 1;
    }

    outFile << "let importedImage: number[][][] = [\n";

    for (int x = 0; x < WIDTH; x++) {
        outFile << "    [\n";

        for (int y = 0; y < HEIGHT; y++) {
            outFile << "        [";

            for (int c = 0; c < 9; c++) {
                outFile << number[y][x][c];
                if (c != 8) outFile << ", ";
            }

            outFile << "]";
            if (y != HEIGHT - 1) outFile << ",";
            outFile << "\n";
        }

        outFile << "    ]";
        if (x != WIDTH - 1) outFile << ",";
        outFile << "\n";
    }

    outFile << "];\n";
    outFile.close();

    std::cout << "Wrote output.txt successfully.\n";


    return 0;
}

note that you will need to change the PALETTE variable if you have a different palette in your makecode project

3 Likes

yes but if i do tilemaps i cant do the dithering to anything, and im trying to make… Celeste? actually i may do tilemaps theres a chance

2 Likes

northern lights (test):

4 Likes

Yo that’s crazy! I tried to do something like this once, but I never got an actual image.

2 Likes

I have one question:
should I post what I am doing every now and then, or should I work until it is completed?

3 Likes

Every now and then, I love seeing halfway done projects.

1 Like

made Madeline’s walk animation, and the hair (not part of the animation because Celeste does hair physics) though the hair doesnt have the exact physics in this example. if the project lags, open the code and at the top read the comment

1 Like

Hey I’m making a Fnaf 6 Style game and I was curious if its possible to integrate Salvage sections with this extension?

I just saw it and thought “You know that looks like that style could transfer over fairly well” Just because the salvage sections are gonna have a more realistic art style, and there also gonna have pre-rendered assets.

Of course I’m not asking you to do it for me, I’m just curious on if you think something like that could work with this extension.