vbe SetPixel problem

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

vbe SetPixel problem

Post by AndrewAPrice »

Can people check to see what's wrong with the following code?

Code: Select all

unsigned int * screenBase; /* beginning of the VBE lfb */
unsigned int width; /* horizontal resolution of the screen */
unsigned int bpp; /* 1 byte for 8-bit, 2 for 16-bit, 3 for 24-bit, 4 for 32-bit */

void setpixel(unsigned int x, unsigned int y, byte_t red, byte_t green, byte_t blue)
{
	byte_t *address = screenBase + (width * y + x) * bpp;
	*address = blue; /* these would only work for 24-bit */
	address++;
	*address = green;
	address++;
	*address = red;
}

If I run it in a for loop, say

Code: Select all

int i;
for(i = 0; i < 800; i++)
{
	setpixel(i, 0, 0xFF, 0xFF, 0x00);
}
only every third pixel is coloured yellow. If I remove the "* bpp" in setpixel so the function reads as:

Code: Select all

byte_t *address = screenBase + (width * y + x) * bpp;
every byte ends up being set to blue value resulting in a white line.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

If fixed my problem by removing "* bpp" and selecting a 32bpp VESA mode. However, how would I adapt the above function to work in 8bpp, 15bpp, 16bpp, and 24bbp VESA modes?
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

I haven't looked thoroughly at the code as I haven't done VESA before, but how are you running this?

I know that VPC2004 has problems with some 24 bit colour modes (I have had problems with some linux distro's before) - in fact some software I have run in the past seemed to stretch the screen and only colour every n'th pixel - sounds very similar to your problems.

Of course, if you are having this problem on a 'real' PC, this doesn't help :?

Hope this helps,
Adam
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Try this:

Code: Select all

void PlotPixel(int x, int y, unsigned char red, unsigned char green, unsigned char blue)
{
  unsigned char *addr = base + (Width*bpp*y) + (x*bpp);
  *addr++ = red;
  *addr++ = green;
  *addr = blue;
}
Also, make sure all your variables have the values in them that you think are there! Now, most video cards actually reverse the red and blue values, so this may screw up, just a heads up! You would need to check the bit masks to see. You can adapt this to 32-bit code easily... depends on where the spare 8-bits is, just increment addr where required. 15/16 bit is a bit harder, but not much... first you must check if you are indeed in 15-bit (R5G5B5) mode, or 16-bit (R5G6B5) mode. Then you would run a function similar to this (again, red and blue may be backwards).

Code: Select all

void PlotPixel16(int x, int y, unsigned char red, unsigned char green, unsigned char blue)
{
  unsigned short *addr = base + (Width*bpp*y) + (x*bpp);
  *addr = (blue>>3); //Shift right 3 to remove bottom 3 bits 8->5 bits!
  *addr<<=6;  //Move right 6 bits to make room for green
  *addr+=(green>>2); //This removes 2 bits, 8->6
  *addr<<=5; //Move this left 5 more bits for red
  *addr+=(red>>3); //Again, remove bottom 3 bits
}
15 bits per pixel is almost the same, just change the <<=6 to <<=5, and the green>>2 into green>>3. Hope this helps.
Last edited by Ready4Dis on Tue Dec 12, 2006 10:39 am, edited 2 times in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Also, the order in which Red Green and Blue appear depends on the implementation.

IIRC you can ask VBE for the exact bitmasks where which color component should go, but you'd still end up with different blocks for each bpp value, due to the byte count of each pixel.

As for why 24 bits dont work - i have no clue. Its especially strange that effectively writing all zeroes result in a white line :roll:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

One more thing, before you enter graphics mode, you should print out all your variables, width, height, bpp, and screen_base just to make sure they all contain the values you are expecting, there is no reason why removing the multiplication by bpp should fix the problem, your code looks pretty correct as far as I can see, so it might be elsewhere.
User avatar
ces_mohab
Member
Member
Posts: 77
Joined: Wed Oct 18, 2006 3:08 am

Post by ces_mohab »

i have recently finished some vbe work here are some snippets:

load bmp of width 160 and height 128 true color at top right screen shifted by 20 from top and right notice 180 and 148.
This works for 24/32 bit color depth.

Code: Select all

load = baseptr + (width*148)*depth ;
	
	for ( i=128 ; i>0 ; i-- )
	{
		int loadtemp = load ;
		for(j=0 ; j<160 ; j++ )
		{
			for(k=0 ; k<3 ; k++)
				load[j*depth + (width-180)*depth + k] = *bmp++ ;
		}
		load = loadtemp - width*depth ;
	}
while this prints a character.
font size 8*16.

Code: Select all

void putcha( int ch , int x , int y )
{
	unsigned char* tov = vptr + (y*16*width + x*8)*depth  ;
	int i , j, index = ch*16 ;
	for( i=0 ; i<16 ; i++ )
	{
		unsigned char* temp = tov ;
		int mask = 0x00000080 ;
		for( j=0 ; j<8 ; j++ )
		{
			if( (font1[index+i]&mask) == mask )
			{
				*tov = attrib ;
				*(tov+1) = attrib>>8 ;
				*(tov+2) = attrib>>16 ;
			}
			tov+=depth ;
			mask >>= 1 ;
		}
		tov = temp + width*depth ;
	}
}
this needs optimization but at least works.


:roll:
To write an OS you need 2 minds one for coding and other for debugging.
Post Reply