Hello once again, I've continued my engine somewhat and the rendering functions are now working fine thanks to Stinomus (feel free to applaud). However to enable it to load data I must use files containing strings describing objects in the game world. That in turn works perfectly and passes the relevant string to a function that stores it.
However I realised my engine would be quite a proportion harder to code if I was unable to display 'debug' messages on the screen with values etc, in this regard I decided to create a function that would accept strings from anywhere in my program (in this case the file loading application) store them in a vector of structs and then parse them to the rendering routine before flipping the backbuffer.
In case your not familiar as to why i don't just output them immediately hardware graphics coding requires that anything output to the screen be placed between a startscene() and endscene() function, thus any debug messages I want to display must be stalled until rendering takes place.

The function to store the string works fine, however when I attempt to load the string from the structure using the vector the string data comes out as a garbled lines of gibberish. My only explination is either the string isn't being stored correctly and I'm reading the next set of memory blocks after it's location, or for some reason it's being converted between formats in some fashion. I have only gleaned a use of vectors recently so though perhaps it would be wise to see if anyone has an explanation or can find fault in my code I am unaware of (more likely by far).

the structure that stores my 'message' data and other declared variables

struct PrintBuffer
{
	int onscreen;
	int ypos;
	LPCWSTR PrintString;
};

vector<PrintBuffer>	StringBuffer;
int DebugYPos=0;

The function that stores a message

void DrawDebugText(LPCWSTR oString)
{
	PrintBuffer PushString;
	PushString.onscreen=0;
	PushString.PrintString = oString;
	PushString.ypos=DebugYPos;
	StringBuffer.push_back(PushString);
	DebugYPos+=20;
	
	for(int i=0;i<int(StringBuffer.size()-1);i++)
	{
		if (StringBuffer.at(i).ypos==DebugYPos) 
		{
			DebugYPos+=20;
		}
	}
	if (DebugYPos >= SCREENHEIGHT) DebugYPos=0;
}

the code to send the string to the rendering function (rendering function DrawTextScreen() works perfectly thus is ommited

void RenderDebugText()
{
	if (StringBuffer.empty())
	{DebugYPos=0;return;}
	for(int i=0;i<int(StringBuffer.size());i++)
	{
		if (StringBuffer.at(i).onscreen >=255)
		{
			StringBuffer.erase(StringBuffer.begin()+i);
		}else
		{
			StringBuffer.at(i).onscreen++;
			DrawTextScreen((StringBuffer.at(i).PrintString),0.0f,StringBuffer.at(i).ypos+0.0f,20.0f,200.0f,D3DCOLOR_ARGB(255-StringBuffer.at(i).onscreen,255,255,255));
		}
	}
}

Having checked the values during run time with break points the string stored in the vector is definitely "data/level1/level.info", however the output is seemingly random characters (mostly Traditional Japanese or Mandarin) while that may fit well with my anime style game, it certainly does not help me check the data as i load it, thus any solution will be gratefully appreciated.

Recommended Answers

All 8 Replies

Update:
I tried storing a point to a new string in the struct, then assigning the string to that memory location, then giving that to the string display function.

I.E.
Store Function

void DrawDebugText(LPCWSTR oString)
{
	LPCWSTR* oStringPnt;
	int Lenth = wcslen(oString);
	oStringPnt = new LPCWSTR[Lenth];
		*oStringPnt = oString;

	PrintBuffer AStringBuf;
	AStringBuf.onscreen=0;
	AStringBuf.PrintString=oStringPnt;
	StringBuffer.push_back(AStringBuf);
	DebugYPos+=20;
	
	for(int i=0;i<int(StringBuffer.size()-1);i++)
	{
		if (StringBuffer.at(i).ypos==DebugYPos) 
		{
			DebugYPos+=20;
		}
	}
	if (DebugYPos >= SCREENHEIGHT) DebugYPos=0;
}

rendering function

void RenderDebugText()
{
	if (StringBuffer.empty())
	{DebugYPos=0;return;}
	for(int i=0;i<int(StringBuffer.size());i++)
	{
		if (StringBuffer.at(i).onscreen >=255)
		{
			delete StringBuffer.at(i).PrintString;
			StringBuffer.erase(StringBuffer.begin()+i);
		}else
		{
			StringBuffer.at(i).onscreen++;
			DrawTextScreen((*(StringBuffer.at(i).PrintString)),0.0f,StringBuffer.at(i).ypos+0.0f,20.0f,200.0f,D3DCOLOR_ARGB(255-StringBuffer.at(i).onscreen,255,255,255));
		}
	}
}

the result was almost identical, except this time while that adress contains garbled characters they no longer actually display (wow :-|)
I will take any ideas, comments, or suggestions right now, including any way to re-write the entire thing that will work.

So with breakpoints, the value of the string in vector just before you extract it is valid?
If so perhaps the replace the call to StringBuffer.at(i).PrintString with something like "Hello World". And see what happens.

That way you get a picture of what the value is in the data structure and then the output if you pass a valid string to the print function.

So with breakpoints, the value of the string in vector just before you extract it is valid?
If so perhaps the replace the call to StringBuffer.at(i).PrintString with something like "Hello World". And see what happens.

That way you get a picture of what the value is in the data structure and then the output if you pass a valid string to the print function.

I did just that, and guess what, it works perfectly, my only possible solution therefore is that somehow when passing an LPCWSTR (a typedef of wchar_t *) It passes over the memory value rather than the information inside said value, or something to that effect.
I thus will attempt a character by character copy or a memory copy and report back.

Thank you sir, I have no idea why I didn't think of that myself.

Create a vector of type wchar_t and store the values in it :)
Remember that you'll have to use wcin and wcout if you want to do I/O

Create a vector of type wchar_t and store the values in it :)
Remember that you'll have to use wcin and wcout if you want to do I/O

I/O is being handled by custom functions so I'm fine by that, however making a wchar_t vector is worth a try, I'll tell you the results when I have some :p

After trying all kinds of things passing an array of wchar_t between functions and adding it to a vector worked. however after playing around with both codes it seems the problem might lie with the null terminator to the string?
In short if I remove the null terminator I get the same garbled output, Is there something about null terminators and LPCWSTRs I should know? the MSDN didn't mention anything. Either way it works now thus I'll mark the post solved. Thanks guys!

>In short if I remove the null terminator I get the same garbled output, Is there something about null terminators and LPCWSTRs I should know?

Yes, when writing a character string to the screen, everything is written to the screen until the NULL-terminator has been encountered, however if there isn't one, then the memory after the character string will be displayed as well, which in most cases gives you that garbled output :)

>In short if I remove the null terminator I get the same garbled output, Is there something about null terminators and LPCWSTRs I should know?

Yes, when writing a character string to the screen, everything is written to the screen until the NULL-terminator has been encountered, however if there isn't one, then the memory after the character string will be displayed as well, which in most cases gives you that garbled output :)

That's what's odd, with the LPCWSTR system I had originally it worked *without* the null terminator, but not with?!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.