![]() |
|
Math wrong and a memory leak? |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
I've posted this similar code a month or so ago, I'm back working on it. This time I am using OpenLayer. I am trying to create a 2D tiling engine. The tiles are not tiling correctly and there must be a memory leak because my processor is using 100% right now >.< (It's making typing hard and I don't want to restart until I finish this)
Tile.cpp
Map.cpp
=-----===-----===-----= |
Simon Parzer
Member #3,330
March 2003
![]() |
firstmap.LoadMap((int *)&map, 21, 16, 1); TileNumber = m_Map[(Row + Xpos) * m_Width + Column + Ypos]; I don't get that. What should (Row + Xpos) be? I think you mean (Row + Ypos). At the end you add Ypos where you probably meant Xpos. int Column = Xpos; int Row = Ypos; So, either make Column = 0; Row = 0; at the beginning and say (Row + Ypos) and Column + Xpos at the "get TileNumber" line or do the opposite in each case. But if you do both you will obviously run out of bounds. |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
firstmap.LoadMap((int *)&map, 21, 16, 1); I've switched it between those before and it had no effect via compile time but I switched it back to how you thought it should be. int Column = Xpos; int Row = Ypos; This sets it so when you call cMap::Draw() You can set the topleft coords to draw. Normally this would be 0,0 But the map can be bigger than the tiles you can display on the screen so we are going to want to change that position a lot. With a map 100x100tiles you are going to want to draw the rest of the map sometimes :-D. In my example program Column and Row are set to 0. Does anyone know of a way to get Two-Dimensional data out of a One-Dimensional array? =-----===-----===-----= |
Steve Terry
Member #1,989
March 2002
![]() |
Quote: Does anyone know of a way to get Two-Dimensional data out of a One-Dimensional array?
Sure bitmaps really are a single dimensional array, to get the x and y on a bitmap you can do some simple math: ___________________________________ |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
Still hasn't solved my problem :-( I've narrowed it down though. Something is going wrong with the inputs to cTile::Draw(). Its inputing some huge number as the TileNumber. So it must be something wrong with my loop inside of cMap::Draw(); =-----===-----===-----= |
Simon Parzer
Member #3,330
March 2003
![]() |
Quote:
int Column = Xpos; int Row = Ypos; This sets it so when you call cMap::Draw() You can set the topleft coords to draw. Normally this would be 0,0 But the map can be bigger than the tiles you can display on the screen so we are going to want to change that position a lot. With a map 100x100tiles you are going to want to draw the rest of the map sometimes :-D. In my example program Column and Row are set to 0.
Yeah, I know. I fully understand your code. But you add Xpos and Ypos twice! int Column = Xpos; int Row = Ypos;
Second time: I know it isn't the error you currently have, because Xpos and Ypos are 0 in your test case. You really should run your map::Draw function through a debugger. And maybe you should use std::vector instead of two-dimensional arrays as soon as you have fixed your problem. |
Indeterminatus
Member #737
November 2000
![]() |
I know this is not related to your problem, I just felt like pointing it out. bool cTile::LoadTileSet(char* filename, int TileWidth, int TileHeight) { m_Filename = filename; if((m_TileWidth = TileWidth) <= 0 || (m_TileHeight = TileHeight) <= 0) return false; ... In these few lines of code, I can spot some issues that might be problematic. Let's have a closer look, shall we? if((m_TileWidth = TileWidth) <= 0: Making use of side-effects never is a good idea. Why? Because it makes the code harder to read, and thus also harder to understand. Let's assume this method is called with 0 for TileWidth and some other value for TileHeight (not important). LoadTileSet will return false as expected, only that the internal state of this cTile instance now is really messed up. m_TileHeight wasn't assigned the value we passed, so it is probably uninitialized. m_TileWidth is 0, even though this is an incorrect value. m_Filename will hold the value of filename, even though the loading failed. m_TileHeight = TileHeight; m_TileWidth = TileWidth; These lines are absolutely unnecessary if you keep the assignments in the previous if clause (which I advise you not to!). My point is, you make it hard for anyone to determine the exact footprint (i.e., postcondition if you prefer that term) for all possible input data. I'm guessing you are not overriding or implementing LoadTileSet, so for starters you could declare both TileHeight and TileWidth as unsigned int. This rules out negative numbers and makes that fact also obvious on first sight. Keeping the state of the object clear might work like this:
Alright, to wrap it up, always expect the worst to happen. Think through the cases with bad input and all combinations of them, and try to catch as many of them as you possibly can. Define what exactly a method should do (like, change any of the object's members only if successful, and on error leave the object entirely untouched). I can almost certainly assure you that this thinking will help the prevention of many bugs. This might not help you right now, but hopefully you can use it in the long run. _______________________________ |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
Ahh thank you very much Simon for pointing that out >.< I'm trying to get a formula to work for me right now. I've tried Column * Row + m_Width but I'm still not getting correct results. To Indeterminatus, =-----===-----===-----= |
Indeterminatus
Member #737
November 2000
![]() |
Quote: What should m_Filename be declared as? I can't get it to be compatible with const char*. Best choice is probably std::string _______________________________ |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
Alright that works :-D Now back to finding my big errrrrrooooooorrrrrr >.< =-----===-----===-----= |
Simon Parzer
Member #3,330
March 2003
![]() |
Quote: Ahh thank you very much Simon for pointing that out >.< I'm trying to get a formula to work for me right now. I've tried Column * Row + m_Width but I'm still not getting correct results.
This is still wrong. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
if the upper-left 0 is at the position (0,0), you want element (3,2). So how do you calculate the one-dimensional index? Each row has 7 numbers (m_Width in your case). So if we want row 2 we say 2 * m_Width, which is 2*7 = 14. Then we simply add the column index, 14 + 3 = 17. Let's count (beginning with 0).. it is RIGHT! And if that doesn't work (another error somewhere else?) you should add debugging output like the following: while(Column < m_Width && Xpixel < screenWIDTH) { TileNumber = m_Map[Row * m_Width + Column]; m_Tiles->DrawTile(TileNumber, (float)Xpixel, (float)Ypixel); Column++; Xpixel += m_Tiles->GetTileWidth(); } With debugging output: while(Column < m_Width && Xpixel < screenWIDTH) { int arrayIndex = Row * m_Width + Column; printf("Row: %d, Column: %d, ArrayIndex: %d, ",Row,Column,arrayIndex); TileNumber = m_Map[arrayIndex]; printf("TileNumber: %d\n",TileNumber); m_Tiles->DrawTile(TileNumber, (float)Xpixel, (float)Ypixel); Column++; Xpixel += m_Tiles->GetTileWidth(); } That will give you a lot of output, so you should redirect it to a file. Then you can check the following: Your map array in the test case is 16*21, so ArrayIndex mustn't be bigger than (16*21) = 336! |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
Alright that formula works perfectly :-D I am speculating that the error is inside the cTIle::Draw() method now. I have been using debugging output like that, but in the form of allegro messages. Because of annoyance of trying to close those pop-up messages and then trying to hit escape to close the program I devised a debugging key. I use: if(key[KEY_D]) { allegro_message("Output: %$", output I want to check); } printf() has no way of displaying to the screen in allegro >.< Edit: Wee I'm almost stuck again, but I'm a bad programmer if I can't find my mistake so I must tear into this some more >.< =-----===-----===-----= |
Simon Parzer
Member #3,330
March 2003
![]() |
Quote: printf() has no way of displaying to the screen in allegro >.<
I know. printf() outputs to the standard output, so if you are smart you compile your program as a console application, start it from terminal in windowed mode and then look at the output in the terminal. You can also start it like |
Matthew Dalrymple
Member #7,922
October 2006
![]() |
Ooooo I'm liking this. I just tested it using that redirection operator mmmm. How I love writing "moo" to a file. Thanks, I love learning new stuff =-----===-----===-----= |
|