Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

palette

hi programmer....


I hope you can help me solve this problem:


If i have a 256 color pcx picture (or other format) in the background and some sprites in the forground, and they are using different palettes...The sprite will make the pcx look strange, or the pcx will make the sprite looke strange...

How can i solve this problem???


Thank you....


Comments

  • : If i have a 256 color pcx picture (or other format) in the background and some sprites in the forground, and they are using different palettes...The sprite will make the pcx look strange, or the pcx will make the sprite looke strange...

    : How can i solve this problem???


    This is common problem... Why there isn't enough colors. There is at least three ways to get around this problem. And more can be found every day :)


    1)

    Use different video mode. I suppose that you're currently using 320*200,256 mode. So switch to VESA mode 320*200,16 bit. And then you'll have enough colors (or use 320*200,32 bit). But then screen memory is bigger. And there isn't real palette - so writing something to palette registers doesn't affect the picture.

    (Colors are created writing correct bits to video memory)


    2)

    Reduce backround picture's colors. If you use all 256 colors in there, redude it to use only 128 or 64 colors. And then you'll have rest of the palette for sprite colors.


    3)

    Generate color table where you'll have indexed all possible colors. It could be size of 64*64*64 (all red values * all green...). Here is untested example code (in C), but is should work...


    (ignore those dots (.) in front of the lines, they are only to make code better readable)


    void Initialize()

    {

    unsigned char Red,Green,Blue;

    unsigned char RealColors[64*64*64];


    for (Red=0;Red<64;Red++)<br>
    .for (Green=0;Green<64;Green++)<br>
    ..for (Blue=0;Blue<64;Blue++)<br>
    ...RealColors[Red*64*64 + Green*64 + Blue]=FindNearestColor(Red,Green,Blue);

    }


    In FindNearestColor() you would loop through palette that you're using. And return closest matching color number. Like this:


    unsigned char FindNearestColor(char R, char G, char B)

    {

    int Loop

    int FoundColor; // Nearest found color

    int Distance; // It's distance from original color

    int Temp;

    char r1,r2,r3;


    Distance=10000; // This is initialised to some big value.

    FoundColor=0;

    for (Loop=0;Loop<256;Loop++)<br>
    .{

    .r1=ColorFromPaletteRegs[Loop][0]; // Red

    .g1=ColorFromPaletteRegs[Loop][1]; // Green

    .b1=ColorFromPaletteRegs[Loop][2]; // Blue

    .

    .// Calculate this color's distance from original

    .Temp=abs(R-r1)+abs(G-g1)+abs(B-b1);

    .

    .// Test if closer match were found

    .if (Temp < Distance)

    ..{

    ..// It was closer than previous, store new values

    ..Distance=Temp;

    ..Color=Loop;

    ..}

    .}


    // Return nearest matching color.

    return(Color);

    }


    And after this, when you're drawing something on screen you would convert it colors to the screen colors buy using RealColors table. Again some code:


    unsigned char GetPixelColor(unsigned char Color)

    {

    unsigned char Red,Green,Blue;

    unsigned char RealColor;


    Red=ColorFromPixelsPalette[Color][0];

    Green=ColorFromPixelsPalette[Color][1];

    Blue=ColorFromPixelsPalette[Color][2];


    RealColor=RealColors[Red*64*64 + Green*64 + Blue];


    return(RealColor);

    }


    This value which is returned by GetPixelColor() can be drawed on screen, and it would be cose enough to it's original color. If in palette is some color which is also close of original color. So best result is achieved when you're using some palette which contains almost all colors.




    Please tell me if you get (or didn't get) yours code working.


    -Sepi




  • Thank you very much for the help...But i have still a couple of questions...


    What is the VESA mode number for 640x480 16 bit and 800x600 16 bit???

    How is the memory buffer structured in these two modes...Is it linear or chain 4...


    Thanx...







  • : Thank you very much for the help...But i have still a couple of questions...


    You're welcome!

    Let's see can I say something...


    : What is the VESA mode number for 640x480 16 bit and 800x600 16 bit???


    Hmm...

    I don't remember those numbers... But they can be found in some VESA explanations.

    Try this site:

    ftp://x2ftp.oulu.fi/pub/msdos/programming

    And these files:

    docs/svgaline.zip (vesa 1.2)

    docs/vgovbe20.zip (vesa 2.0)


    Or find some more from 00index.all file


    : How is the memory buffer structured in these two modes...Is it linear or chain 4...


    There are two ways. One is banked memory and second is linear memory buffer. Banked buffer comes with VESA 1.2 and linear with VESA 2.0. I'll explain a bit of these...


    Banked memory:

    Video memory is in segment 0xA000 like normal VGA vid-mem. But you can only adress part of the image through that 64k segment. So there is a vesa function where you can tell where this segment is pointing in real video memory (which lays in your's video card).

    So if you were drawing the whole image you would write the first 64k of it to the video segment, and then call SetBank function where you'll set v-mem pointing to another part of real v-mem and draw more of image and then again set another bank... and so on...


    But this bank switching is slow and no one likes it (at least with old video card it is very slow). So there is better way to adress to video memory, the Linear memory buffer:

    LMB (I recall that it was called like this...) is only a huge memory chunk which points directly(?) to video memory. So it is used like normal VGA memory. No bank switching will be needed. It's adress must be first fetched from VESA 2.0 routines. I don't now really remember how it was done, but try those documents that I listed above there should be all(?) info what you'll need. I don't remember where this LBM will lay, is it in conventional memory or above 1 Meg. If it is above 1 meg then you may have some problems adressing it if you're not using protected mode. I use my VESA routines through protected mode and it works fine. (I use DJGPP)


    And of course those 16bit video modes are stuctured differently like normal 256 colored picture. I'll explain a bit of it (I'am now at work and I should do something where they are paying for me :)


    In 16bit mode 2 bytes contains color information. So if you want to draw to pixel x,y you'll do something like this (LBM):

    VideoMemory[x*2+y*VideoXsize+0]=Byte1;

    VideoMemory[x*2+y*VideoXsize+1]=Byte2;

    Banked version doesn't differ very much from it...

    Those two bytes are constructed like this:

    Bits 14-02 contains Red values, 9-5 is for blue and 4-0 for green. Bit 15 (topmost) is left unused. This is actually 15 bit mode, more info can be found from those documents which I mentioned.


    Ok, I could explain more and more of those modes, but now I HAVE to return my work. Happy coding!


    -Sepi


  • : What is the VESA mode number for 640x480 16 bit and 800x600 16 bit???


    in your univbe directory, there should be a program that displays all available modes and their respective numbers. Output this to a file and print it.


    : How is the memory buffer structured in these two modes...Is it linear or chain 4...


    lets see... its called a LINEAR FRAME BUFFER (lfb) ... so I would say linear :)


Sign In or Register to comment.