C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-07-2007, 01:56 PM   #1
Wheres the lesbians?
 
mike_g's Avatar
 
Join Date: Oct 2006
Location: UK
Posts: 1,219
Bitmasking Problem

I'm making a set of functions to produce console-like output for SDL. The font is made from a binary mask but I am having problems getting it to display properly. Heres an example of it printing the string"0123456789ABCDE" :
http://i92.photobucket.com/albums/l1...l/deleteme.png

Its partly readable but somethings definitely wrong. The constructor for the class takes a character map, and the data. This is run here in my prog:
Code:
BitText txt(	"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 
				"mprtxpmckccccmmp`acg~mp`e`pmaeiq~aa~oom`pmego}ppm~``acgomppmppmmppn`ak"
				"cipp~pp}pp}pp}mpooopm}ppppp}~oo}oo~~oo}ooompoorpnppp~pppmcccccm~aaaqqk"
				"pqswsqpoooooo~pztppppppxtrppmpppppm}pp}ooomppptrn}pp}sqpmpom`pm~cccccc"
				"ppppppmpppppicppppttippicipppppiccc~`acgo~" );
Heres what the constructor does with it:
Code:
BitText::BitText(const char* char_map, const char* char_data)
{
	int len = (int)strlen(char_map);
	map = new char[len];
	strcpy(map, char_map);
	len = (int)strlen(char_data);
	data = new char[len];
	strcpy(data, char_data); 
	col = 0xFFFFFFFF;
}
And heres the function to print text to the screen:
Code:
void BitText::Print(Uint16 x_pos, Uint16 y_pos, const char* text)
{
	int x, y, bit, pos;
	char* ptr;

	for(int i=0; i<(int)strlen(text); i++)
	{
		//Get the coresponding character in the character map
		for(ptr=map, pos=0; *ptr; ptr++, pos++)
			if(*ptr == text[i]) break;

		//Get the characters data start point
		ptr = data +(pos*7);
		
		//Draw character
		for(y=0; y<7; y++)
		{		
			bit=16;
			for(x=0; x<5; x++, bit >>= 1)
				if(*ptr & bit) 
					WritePixel(x_pos+x, y_pos+y, this->col);	 
			ptr++; //Move to data byte holding next scanline of the character	
		}

		x_pos+=6;
	}
}
I'm pretty sure the mistake is in this last function. Can someone see whats going wrong here? I can't Hopefully thats all the relevant code here.

Last edited by mike_g; 11-07-2007 at 01:58 PM.
mike_g is offline   Reply With Quote
Old 11-07-2007, 02:03 PM   #2
Registered User
 
Join Date: Jan 2007
Location: Euless, TX
Posts: 135
First question --- where does "map" come from in your print function??
kcpilot is offline   Reply With Quote
Old 11-07-2007, 02:03 PM   #3
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
[edit]
Quote:
First question --- where does "map" come from in your print function??
It's likely a char*, a member of the class BitText. At least that's what I should think.
Code:
BitText::BitText(const char* char_map, const char* char_data)
{
	int len = (int)strlen(char_map);
	map = new char[len];  /* +1, right? . . . */
	strcpy(map, char_map);
[/edit]

In BitText::BitText() . . .
Code:
map = new char[len];
len+1 perhaps?
Code:
col = 0xFFFFFFFF;
I like
Code:
col = (unsigned long)-1;
just because.

Code:
for(int i=0; i<(int)strlen(text); i++)
Calculating strlen() is expensive, consider moving the calculation outside of the for loop and storing it in a variable.

Code:
		//Get the coresponding character in the character map
		for(ptr=map, pos=0; *ptr; ptr++, pos++)
			if(*ptr == text[i]) break;

		//Get the characters data start point
		ptr = data +(pos*7);
It seems to me that this is simpler:
Code:
for(pos = 0; map[pos]; pos ++)
    if(map[pos] == text[i]) break;

ptr = data + pos * 7;
Or you could just use pos all the way through. pos and ptr basically hold the same information, so you don't need both of them.
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 11-07-2007, 02:05 PM   #4
Registered User
 
Join Date: Oct 2001
Posts: 2,936
Code:
	map = new char[len];
.
.
	data = new char[len];
You have to allocate len+1 to make room for the string terminator which is appended by strcpy().
Code:
	map = new char[len+1];
.
.
	data = new char[len+1];
__________________
http://www.freechess.org
swoopy is offline   Reply With Quote
Old 11-07-2007, 02:15 PM   #5
Wheres the lesbians?
 
mike_g's Avatar
 
Join Date: Oct 2006
Location: UK
Posts: 1,219
Quote:
First question --- where does "map" come from in your print function??
Sorry heres my class definition:
Code:
class BitText
{
	private:
		char* data;
		char* map;
		Uint32 col;
	public:
		BitText(const char*, const char*); 
		void Print(Uint16, Uint16, const char*);
};
map holds all the characters displayable in order. EG: 0123456789ABCDEF....etc.
data holds the mask data. EG: "mprtxpm" is the data to display the number 0.

Quote:
In BitText::BitText() . . .
Code:

map = new char[len];

len+1 perhaps?
Yeah forgot about that.

Quote:
I like
Code:

col = (unsigned long)-1;
Now youre just showing off

Quote:
Calculating strlen() is expensive, consider moving the calculation outside of the for loop and storing it in a variable.
Oh. I dident think it recalculated it each loop. Best move it out I guess.

Quote:
It seems to me that this is simpler:
Code:

for(pos = 0; map[pos]; pos ++)
if(map[pos] == text[i]) break;

ptr = data + pos * 7;
But wheres 'i' gone then?

Cheers.
mike_g is offline   Reply With Quote
Old 11-07-2007, 02:20 PM   #6
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
What do you mean? i still exists. I'm just saying that you could use my for loop instead of your for loop. Mine makes use of only one counting variable, pos, whilst yours uses pos as well as ptr. You don't need both counters -- one will suffice.
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 11-07-2007, 02:25 PM   #7
Wheres the lesbians?
 
mike_g's Avatar
 
Join Date: Oct 2006
Location: UK
Posts: 1,219
>_< oh yeah. dident realize that. I guess I should take more time to think while i type

Still looking for an answer to the original problem tho if anyone can spot it.

Cheers.
mike_g is offline   Reply With Quote
Old 11-07-2007, 03:05 PM   #8
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
That buffer overrun could be the source of your problem. Buffer overruns can result in strange things. Fix it and see what happens.

You are of course aware that there are plenty of text handling libraries available for the SDL? You can get truetype fonts with SDL_ttf; SDL_gfx has simple bitmap font handling capabilities (with embedded data); and I've heard of sfont as well. Search the SDL libraries page if you're interested.

Code:
		//Get the coresponding character in the character map
		for(ptr=map, pos=0; *ptr; ptr++, pos++)
			if(*ptr == text[i]) break;
What if the character doesn't exist in the map, for example a space? You'll have another buffer overrun.

How is your data laid out? Because you seem to be using only the lower-order 4 bits of every byte:
Code:
		//Draw character
		for(y=0; y<7; y++)
		{		
			bit=16;
			for(x=0; x<5; x++, bit >>= 1)
				if(*ptr & bit) 
					WritePixel(x_pos+x, y_pos+y, this->col);	 
			ptr++; //Move to data byte holding next scanline of the character	
		}
If data is stored in the upper 4 bits as well, you're not using it.
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 11-07-2007, 04:58 PM   #9
Registered User
 
Join Date: Oct 2001
Posts: 2,936
I think there's a problem with your font map. It appears you have a 7x5 grid for every character, is this correct? I printed out the grid for some of the characters, and it almost looks like in some cases part of the character is missing. The number one looks ok, but most look similar to your deleteme.png file. Maybe the grid is supposed to be wider?

And Dwks, it's 5 bits, not 4 bits being used.
__________________
http://www.freechess.org
swoopy is offline   Reply With Quote
Old 11-07-2007, 05:04 PM   #10
Registered User
 
Join Date: Oct 2001
Posts: 2,936
Speaking of which do you have a file that you can post that shows what the font looks like for each character?
__________________
http://www.freechess.org
swoopy is offline   Reply With Quote
Old 11-07-2007, 09:42 PM   #11
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
Quote:
And Dwks, it's 5 bits, not 4 bits being used.
Oops, you're right. Sigh.

Actually, a better way to write the loop would perhaps be
Code:
for(x=0; bit; x++, bit >>= 1)
Of course, bit could also be computed inside the loop with
Code:
2 << (4 - x)
but that would likely be slightly less efficient. Maybe.
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 11-07-2007, 11:24 PM   #12
Wheres the lesbians?
 
mike_g's Avatar
 
Join Date: Oct 2006
Location: UK
Posts: 1,219
Quote:
Originally Posted by dwks
That buffer overrun could be the source of your problem. Buffer overruns can result in strange things. Fix it and see what happens.
Well I had made most of the changes you suggested, as they were good. However I couldent see any of them changing the output of my prog. Fair enough the string delimeter was missing, but with the test data I was using the end of either strings would never be reached anyway since non-featured characters were never used. Still those parts are all fixed, and my for loops are a bit better now too

Quote:
Originally Posted by swoopy
Speaking of which do you have a file that you can post that shows what the font looks like for each character?
No sorry dude. I got the font data from some Basic code for drawing fake led displays. Having seen that prog work I know the original data was correct. Just incase you would like it with the characters seperated this was the original Basic source:
Code:
Data "mprtxpm"    ; 0
Data "ckccccm"    ; 1
Data "mp`acg~"    ; 2
Data "mp`e`pm"    ; 3
Data "aeiq~aa"    ; 4 
Data "~oom`pm"    ; 5
Data "ego}ppm"    ; 6
Data "~``acgo"    ; 7
Data "mppmppm"    ; 8
Data "mppn`ak"    ; 9

Data "cipp~pp"    ; A
Data "}pp}pp}"    ; B
Data "mpooopm"    ; C
Data "}ppppp}"    ; D
Data "~oo}oo~"    ; E
Data "~oo}ooo"    ; F
Data "mpoorpn"    ; G
Data "ppp~ppp"    ; H
Data "mcccccm"    ; I
Data "~aaaqqk"    ; J
Data "pqswsqp"    ; K
Data "oooooo~"    ; L
Data "pztpppp"    ; M
Data "ppxtrpp"    ; N
Data "mpppppm"    ; O
Data "}pp}ooo"    ; P
Data "mppptrn"    ; Q
Data "}pp}sqp"    ; R
Data "mpom`pm"    ; S
Data "~cccccc"    ; T
Data "ppppppm"    ; U
Data "pppppic"    ; V
Data "pppptti"    ; W
Data "ppicipp"    ; X
Data "pppiccc"    ; Y
Data "~`acgo~"    ; Z
mike_g is offline   Reply With Quote
Old 11-07-2007, 11:48 PM   #13
Wheres the lesbians?
 
mike_g's Avatar
 
Join Date: Oct 2006
Location: UK
Posts: 1,219
Ok I just drew the binary pattern out for the first character and I found it dosent match to what I want. Apparently the prog I got this from used some other method to read the data. >_< That was kind of dumb of me not checking it. Guess I need to come up with some new data.
mike_g is offline   Reply With Quote
Old 11-08-2007, 12:24 AM   #14
Registered User
 
Join Date: Oct 2001
Posts: 2,936
I noticed the map had more than the 5 least significant bits set in some of the chars too, which seemed odd, so maybe somehow it makes use of all 8 bits (or perhaps 7 bits), but as you say, the patterns don't seem to properly map.
__________________
http://www.freechess.org
swoopy is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Need help understanding a problem dnguyen1022 C++ Programming 2 04-29-2009 04:21 PM
Memory problem with Borland C 3.1 AZ1699 C Programming 16 11-16-2007 11:22 AM
Someone having same problem with Code Block? ofayto C++ Programming 1 07-12-2007 08:38 AM
A question related to strcmp meili100 C++ Programming 6 07-07-2007 02:51 PM
WS_POPUP, continuation of old problem blurrymadness Windows Programming 1 04-20-2007 06:54 PM


All times are GMT -6. The time now is 04:14 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22