Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

dos-like

Engine for making things with a MS-DOS feel, but for modern platforms · By Mattias Gustavsson

How the color and palette system works?

A topic by Vitor Almeida created 34 days ago Views: 61 Replies: 7
Viewing posts 1 to 5

Hey everyone!

I'm having trouble understanding how the color and palette system works in the library.

Currently, I'm drawing a simple Pong game (using white for the elements and other simple drawing functions like line and rectangle).

However, I've created a simple palette with some shades of green that I want to use to simulate a color decay effect using the framebuffer.

My problem is that I can't change (and especially compare) the colors in the drawn framebuffer to know which color I need to "decay".

I don't understand the combined concept of being able to change the framebuffer and the color palette.

Could you please help me?
Thanks.

One question: for example, the code "getpixel(x, y)" returns a color or an index from the palette? If it's a color, this color can be different from the defined/default palette?

I think I understood: the library only works in terms of a palette index: it means that when I use putpixel, getpixel (or setcolor) they will work with an index that will use the color  (rgb) specified in the setpal function.

Developer

Yeah, each pixel in the frame buffer is an index into the palette, a pixel can only have values between 0 and 255. the palette can have 256 entries, and pixels are displayed using the rgb value at that index in the palette. if you change, for example, the palette entry 3, it will affect ALL pixels in the frame buffer that points to that index (all pixels that have value 3)

Thank you very much, Mattias.

Thanks to your explanation about colors, I was able to understand and implement some more effects (scanlines and green phosphor effect) in my pong game.

Developer

Nice, that looks great :)

Thank you Mattias :)

(3 edits)

Hey guys, I also made a quick program to visualize the default doslike palette (it will be useful for future projects):


#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include "dos.h"
#define SCREEN_WIDTH        screenwidth()
#define SCREEN_HEIGHT       screenheight()
#define SQUARE_SIZE         15      // sqrt((SCREEN_WIDTH * SCREEN_HEIGHT) / MAX_PALETTE) == 15.8 (if SCREEN_WIDTH = 320, SCREEN_HEIGHT = 200, MAX_PALETTE = 256)
#define OFFSET              2
#define COLS_PER_ROW        21      // (SCREEN_WIDTH / SQUARE_SIZE) == 21.3333 (if SCREEN_WIDTH = 320, SQUARE_SIZE = 15)
#define MAX_PALETTE         256
#define COLOR_WHITE         15
#define COLOR_RED           41
#define PADDING             1
#define MOUSE_CURSOR_SIZE   3
char textbuffer[17]; // utility buffer for textual stuff
void input(void) {
    if (keystate(KEY_ESCAPE)) exit(0); // exit the game
}    
void update(void) {
}
void draw(void) {
    int palindex = 0;
    int x, y;
    // mouse position & color
    int mx = mousex(), my = mousey();
    int mc = COLOR_RED;
    // draw each color of the palette
    for (int row = 0; palindex < MAX_PALETTE; row++) {
        // row by row, as long as we have colors in the palette to draw
        for (int col = 0; col < COLS_PER_ROW && palindex < MAX_PALETTE; col++) {
            x = OFFSET + (col * SQUARE_SIZE);
            y = OFFSET + (row * SQUARE_SIZE);
            setcolor(palindex);
            bar(x, y, SQUARE_SIZE - PADDING, SQUARE_SIZE - PADDING);
            if (mx > x && mx < (x + SQUARE_SIZE) && my > y && my < (y + SQUARE_SIZE))  {
                setcolor(COLOR_WHITE);
                x = (SCREEN_WIDTH * 0.5) - 50;
                y = SCREEN_HEIGHT - 15;
                sprintf(textbuffer, "getcolor() = %d", palindex); outtextxy(x, y, textbuffer);
                
                // if the mouse (that has a red cursor) is inside a redish color
                // give to it a white color to increase contrast
                if (palindex == 4 || palindex == 12 || (palindex >= 34 && palindex <= 41) || (palindex >= 108 && palindex <= 114))
                    mc = COLOR_WHITE;
            }
            palindex++;
        }
    }
    // mouse cursor
    setcolor(mc);
    bar(mx, my, MOUSE_CURSOR_SIZE, MOUSE_CURSOR_SIZE);
}
int main(int argc, char* argv[]) {
    setvideomode(videomode_320x200);
    setdoublebuffer(1);
    uint8_t* screen = screenbuffer();
    while (!shuttingdown()) {
        waitvbl();
        clearscreen();
        
        input();
        update();
        draw();
        screen = swapbuffers();
    }
    
    return 0;
}