Grayscale and mode 13h
I've been trying to display 24-bit graphics in the mode 13h 256-colour graphics mode by converting the pixel values to their average and setting the palette so it is 256 shades of grey.
The only thing is, I kept getting some weird sharp transitions from white to black and vice-versa in certain areas of each image, which I attributed to an overflow occuring somewhere in my calculations. After playing around with them for about 15 mins, I finally remembered that only six bits of each eight bit colour value in the palette is actually used, subsequently I'd only get 64 shades of grey. :(
Is there a way around this, or a different graphics mode that will give me a full grayscale palette?
are you keeping in mind that 13h graphics uses 24-bit colors, it just has an 8-bit palette?
13 graphics does NOT use 24-bit colour. If you had read what I had said, only 6 of the eight bits of each colour value are used. This means that you can only pick your palette from 2^18 colours (262,144 colours), not 16,777,216 like in 24-bit modes. Gotta love these old standards...
e.g. if you set a register to RGB 215, 34, 167:-
Only the the bits with pipes underneath them are actually used, the bits with Xs underneath them aren't used. This results in the actual value being RGB 212, 32, 164.
11010101 00100010 10100111
||||||XX ||||||XX ||||||XX
um...yes 13h DOES use 24-bit color, thats why you HAVE 64 choices of RGB values.
Think about it, the format for 16 bit is this:
RRRRR GGGGGG BBBBB
Now, think in binary for a bit. If that is the format for 16-bit, that must mean that the maximum amount of choices for colors in 16-bit is 32 (except for green which has the extra bit, unless we are in 15-bit, which gives an even 5 bits for every color).
However, in 13h, you have a choice of 64 shades of RGB, so the format is this:
RRRRRR GGGGGG BBBBBB AAAAAA
the A is the alpha mask. Look at the colors there. There are 24-bits. Each color gives you 64 choices because you have 6 bits per color. Therefore it is 24-bit color, only 13h uses an 8-bit PALETTE, which means you have the ability to use 256 colors at a time.
I guess you could take off the A mask and say 13h uses 18-bit...but i dont think 18-bit is even heard of anywhere....thats weird to talk about 18-bit...
There is a function via int 10h that will grayscale the palette in one call. Look in RBIL for the function.
No no no, you dont know what your talking about (or maybey I dont :) ). mode 13H is capable of displaying up to 256 colors on the screen at one time, thus 8 bit color. You can change the palette for any of those 256 colors to an 18 bit value (6 bits red, 6 green, 6 blue) giving you a quite a few different colors to choose from. Its still 8 bit color, being able to change the pallete does not make it 18 bit (or 24 ?). David, I see what you are trying to say but thats not how different color modes are actually refered to.
To convert RGB colors to grey scale, you need
18% * R
81% * G
1% * B
of the color components.
That way you get 256(!!!) grey shades from 256 colors.
I really don't understand how can you speak of 24 bit colors on mode 13h, which is a standard VGA mode -> 320 x 200 x 256 colors.
Beesides, playing around with the VGA is great fun.
Have a nice code!
C'mon guys. Just load your 16/24/32 bit image into the palette correctly (use the right bit shifts for your color depth). Then call the BIOS INT 10h to greyscale the entire palette. That's all there is to it. No need to go calculating all the grey intensities in 256 color mode.
Bubba, you're right, of course, using function of BIOS int 10h to convert the palette is quick and confortable, but...
BIOS functions and ints are slooooow, there are lot of checkings and workarounds (btw, it uses the same algorythm which I described previously).
So, if you want to speed up things and make a real breath-cutting demo, use low-level VGA programming and Assembly ;°)
That's what I meant.
Why assembly, all you need to do pallete setting is in and out which you can do in C or assembly. Doesnt make much sense in assembly.
Why assembly? Well, stupid_mutt, don't use it, just...
... if you want to speed up things and make a real breath-cutting demo ;°)
I was generally speaking of cool effects and demos. If you don't care how C, Pascal etc. libs "unoptimize" ;) your code, don't use assembly. If you don't care about the size of your executable, don't use assembly.
How can you e.g. set the instruction pointer in C or Pascal, not using assembly, which does it through 2 simple instructions:
Which compiler will optimize (just some very primitive examples!)
mov ax, 0 to xor ax, ax
or cmp ax, 0 to or ax, 0 ?!
Can you be already sure the higher level language does the right thing? Because I'm not! I love assembly, sorry.
But if you don't care, don't use ASM.
That's my point of view.
hehehe, getting technical are we? jmp changes the instruction pointer also, no need to push anything. Also, what are the chances the person who wants to do this knows assembly?
For the simplest way to do this, check my posts in this thread.
Assembly? This does not have to be done in asm and has no inherent advantage that I can see. And don't get me wrong, I love assembly, but C can handle this task very efficiently.
Bubba, I don't think your method would work for me as I'm doing this for an animation player, and I've tried updating the palette completely 25 times a second before, it ain't pretty :o
In this situation I think using a universal grayscale palette would be the best option so that it would look OK whatever is being displayed.
Unless you can suggest a good dithering algo? :)
Then by all means move to protected mode and use the 16/32 bit modes to do this. You will also be able to use the LFB.
You might be able to pull this off in real mode by getting the far address of the bank switch function and then call it via a far pointer instead of an interrupt.