Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / display variable with dbPrint

Author
Message
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 19th Apr 2008 05:51
dbPrint seems to be having troubles displaying variables... I think it should work because it is supposed to... anyways...

I declared two variables:

Then assigned values to them:

And of course I did this before the loop...
Then I added:

into the loop...
Then when I tried to compile it I got these errors:


~~Core2uu~~
Lilith
16
Years of Service
User Offline
Joined: 12th Feb 2008
Location: Dallas, TX
Posted: 19th Apr 2008 06:11
One of the applicable parameter types for dbPrint is a LONGLONG, or a 64 bit integer (__int64). You probably need to type cast your 32 bit integers to LONGLONG when you call your dbPrint function.



The alternative would be to actually store them as LONGLONG variables, though I doubt seriously that your characters' health points are going to get quite that large.

Lilith, Night Butterfly
I'm not a programmer but I play one in the office
SunDawg
19
Years of Service
User Offline
Joined: 21st Dec 2004
Location: Massachusetts
Posted: 19th Apr 2008 06:33
Alternatively, you could use sprintf.

Call an extra string that will hold your integer as a number:


Print your integer to the string and then print the string:


This method is preferable, because you can print other text as well, in a similar fashion to normal printf. Look at this example:


This now gives you the ability to add a label, which allows you to debug faster. And finally, the fastest and best solution:


My site, for various stuff that I make.
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 19th Apr 2008 06:33 Edited at: 19th Apr 2008 06:38
dbPrint is able to print integers, and you can certainly cast as Lilith has mentioned, but...

Go ahead and bite the bullet. Use sprintf to format the output. Then you can use the more sensible LPSTR version.

char buffer[80];
.
.
.
sprintf(buffer, "Dwarf Health:%i", DwarfHealth);
dbPrint(buffer);


Later, when you have more information to display, you will be ready.

You win, SunDawg...this time! OOPs, no...your code does not work.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 19th Apr 2008 20:23
I can't get either method to work... I tried Sundawg's first but as Jinzai said it did not work for him and it didn't for me and then I tried Lilith's...

When I try to build with Lilith's method I get these 3 errors...


Any ideas? Maybe I'm doing declarations wrong or something...

~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 19th Apr 2008 20:38
The only thing wrong with SunDawg's code is that he declared a pointer, but it was not pointing to a buffer, it was uninitialized.

Just a guess, but it seems as if you are declaring them within the main function, making them local to that function. Move them outside of main. Put them right below the include files. That makes them global, and PlayerUpdate will be able to see them, then. Otherwise, pass them as variables. Any variables local to main are wasting stack space, as you will not recover the stack space until the program ends. That is a practice that will tend to make your application run more slowly, as Windows must swap and restore the stack whenever it switches applications. (It will do this independent of your switching them.)
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 19th Apr 2008 21:01
OK... I declared the two variables and assigned them values inside the DarkGDK function...



The I put the dbPrint command inside the PlayerUpdate function which is included in the GDK Loop...


That was my setup during my last post... I am not eactly sure what you are wanting me to do because it doesn't help at all if I move the declarations outside of DGDK function...

Here's the 4 errors I get when I move the declarations out of the DGDK and put the under the include files...


~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 19th Apr 2008 21:10 Edited at: 19th Apr 2008 21:11
You can't declare them twice in any event. That error is telling you that.

I am saying to put them here...



Also, somewhere you have declared them as a function, using (). Post the whole file, please. I will fix it for you.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 19th Apr 2008 21:15
Sweet, NOW it works... Actually my code looked the exact the same as your snippet Jinzai but one thing was different... I had declared the two variables in Main.h also and that's where the double declaration errors were coming from... Anyhow thanks a bunch...

~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 19th Apr 2008 21:43
Yes, I was wondering how it was already complaining about redefinition at lines 4 and 7, which is why I asked you to post it up. Its really easy to get the source mucked up when experimenting like that, and fresh eyes help alot.

That's great, now you have a decent method of getting information from your program as it runs, which is what SunDawg was saying, too.

Cheers.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 20th Apr 2008 00:31
Sorry to bother you again Jinzai but while we are on this topic how do you work with dbScreenFPS because I don't get it...

~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 20th Apr 2008 01:59
Its not a bother at all, quite the opposite, really. It returns an integer value. In DBPro, it is simply the FPS, but the documentation states that it is in 1/1000ths of a second. I don't use GDK very much at all, but I imagine that it is like DBPro...frames per second, not milliseconds per frame.

Put a call to it in your game loop, and you can use the same technique to print the value out with sprintf and dbPrint. You can do it like this:

sprintf(buffer, "FPS: %i", dbScreenFPS());
dbPrint(buffer);

sprintf is able to overwrite the buffer, and it also makes sure to null (0) terminate the string it makes, so you can just continue to use the same buffer many times.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 20th Apr 2008 03:22
Great... except... I don't know how to declare buffer...

~~Core2uu~~
SunDawg
19
Years of Service
User Offline
Joined: 21st Dec 2004
Location: Massachusetts
Posted: 20th Apr 2008 03:33
I guess I wasn't clear...the variables really need to be global. I recommend declaring before the includes, as it prevents possible problems later with included source files that reference global variables defined after they are included. Depends on the compiler, but it can be a problem.

My site, for various stuff that I make.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 20th Apr 2008 03:45
OK... so I declared it before the includes as you said and the program compiled fine, no errors, no warnings... and when it ran... it died... At first it spent a couple seconds loading the 3d models and then... here's a screenshot... There was no warning or indication of anything gone wrong...

~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 20th Apr 2008 13:05 Edited at: 20th Apr 2008 13:05
Well, I can't read that, but I know what it is. Not exactly sure, but I'd say that you either didn't really get a buffer, or it may have been overrun. I was not going to show you using the return directly in the sprintf statement like that. Its not the safest, and you now need to bust it apart to see what's going on. Later, after you trust all of the code, you can dod that as a (very small, actually) optimization.

The compiler would complain if you had no variable named buffer for it to work with, but let me explain something important about this buffer, and sprintf, and C. The variable buffer:
char buffer[80];
...is an 80 byte array of type char. In C/C++ the array name minus the [] operator is the address of the beginning of the array. Another way to get the same pointer from array notation is this:
char* c = &buffer[0];

That's just to explain why I pass buffer as the destination for sprintf. Also, this means that you have 79 characters that you can display. Plenty for most debugging purposes.

Now, in C++, you can use something more like what SunDawg has recommended, but let me say here that you are declaring fixed global variables. The same goes for fixed local variables. It is a more consistent practice to simply state the size of the variable, which allows the compiler to make sufficient room, and you can organize your data better. Here is another way to do the same thing dynamically in C++:
char* pbuffer = new char[80];

Now, pbuffer is a pointer to an array, which also can be used with the [] operator in the same manner. The biggest difference is that you must pair new with delete...you have to give the memory back at some point. This method is great for situations where a function must work on variable sized data. To release the buffer, use:
delete [] pbuffer; It is also a great way to read a whole file in, and break it up later using pointers. A really outstanding example is the file loading in Quake II/II, etc. The entire map is loaded in one read, and its processed from memory.

Okay, your program usually hits a break like that when you have a null pointer, or try to read or write memory that isn't in your application's address space, at least programs like what you are working on now. (You also get that in literally thousands of other places, almost exclusively for misbehaving with a pointer, or the dyncamic memory in your app.)

I'd recommend something like this:
int itemp;
.
.
.
itemp = dbScreenFPS();
MesssageBox(NULL, "dbScreenFPS called.", "DEBUGGING", MB_ICONINFORMATION);
sprintf(buffer, "FPS: %i", dbScreenFPS());
dbPrint(buffer);

Declare itemp in the usual spot, and make sure buffer looks like it does above in this post.

MessageBox should already be available to your code, its in Windows user32.lib/dll. That will stop the program to display a message, and you will have to press ok to allow the sprintf to happen. In fact, maybe you should put a message box after it, too to try and bracket the crash off, so you can verify where it actually breaks.

You could also use debug mode and breakpoints, that's always fun...looking under the hood as it runs...very fast for diagnostics, and great during development. The message boxes will be ugly, btw.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 20th Apr 2008 20:15
It's working now.... I hadn't declared buffer properly... For some reason, I was doing this...



... which didn't really make sense to me in the first place and I didn't have perfect expectations for it to work but then I replaced it with char buffer[80]; and voila... problem solved....

Although MessageBox command wasn't working... I got an error which said identifier not found... Do I have to include Windows library too for that too work? If so how do you include it?

~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 21st Apr 2008 08:15
Yes, that is a very common error, which is why I typed a book about it twice this morning. (So you were not my only victim today!)Pointers are as confusing as they are powerful. The reason this does not work:

char* buffer;

is that it is only a pointer...its not a buffer. What is worse is that it is also an uninitialized pointer, meaning its pointing at a random place in your computer's memory. I think that when someone is shown this:

char* pbuffer = new char[80];

That might look similar. Its not at all, because what this is...is an initialized pointer to a valid buffer. It is a dynamic memory allocation as well, however.

I'm pretty sure that the library is already there. (I think, anyway its user32.lib) I think that it is complaining about MB_ICONINFORMATION (0x00000040L), which is defined in winuser.h. I'm pretty sure that all you need to have in the file you are using it in (main.cpp?) is the standard #include <windows.h>. If you don't have that now, and you put that in, you should get winuser.h included by that file. You could also just pass 0, which is MB_OK, or 64, which is MB_ICONINFORMATION.
The library dpenedencies are checked/set using the Project/(ProjectName) Properties menu item. That brings up the property pages for your project. Open the Configuration Properties folder. Open the Linker folder. Select Input. The first item in the list is Additional Dependencies. On the very right side, there is a button that opens a dialog (They have '...' on them.) It might be hidden. Just go to the right of the list item, and click the mouse button. Open the dialog. user32.lib should be in the list on the bottom...Inherited Values. If not, you can add it using the list box above by typing user32.lib, and pressing enter. Be aware that that will only add the library for the active configuration. You can choose to change it for all configurations using the first property page, using either the Configuration droplist on the left, or the Configuration Manager push button on the right.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 22nd Apr 2008 01:38
All I had to do was include windows.h and the intellisense was updated...

Am I ever having fun on this thread, I do have more questions but I'll start another thread and I'll close off by asking this... what is the difference between rebuilding and building a solution?

~~Core2uu~~
jinzai
18
Years of Service
User Offline
Joined: 19th Aug 2006
Location: USA
Posted: 22nd Apr 2008 20:42
Rebuilding will rebuild everything, including things that don't need to be rebuilt. For example, in GDK apps the precompiled header will only get rebuilt when you either change "stdafx.h", or if you select rebuild.

Build only builds those targets that have a later file time than their corresponding .obj files. .obj is the intermediate file you get when you compile a .cpp file, The linker links .obj and .lib files.
Core2uu
16
Years of Service
User Offline
Joined: 15th Mar 2008
Location: Saskatoon, SK, Canada
Posted: 23rd Apr 2008 01:35
THX Jinzai...

~~Core2uu~~

Login to post a reply

Server time is: 2024-09-29 17:22:12
Your offset time is: 2024-09-29 17:22:12