Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Stumped

This thread is locked; no one can reply to it. rss feed Print
Stumped
jason perkins
Member #10,524
January 2009

After Many Many hours of fiddling around the problem appears to be in how I'm saving/loading my files. I don't see what I'm doing wrong here... This was working fine until I updated my project, but now It's broken.

#SelectExpand
1void CLayer::save(std::string a) 2{ 3 if (created== true) 4 { 5 ALLEGRO_FILE* file; 6 7 file = al_fopen(a.c_str(), "w"); 8 9 if(file) 10 std::cout <<" Opened File " << a << endl; 11 12 al_fwrite32le(file, map.getWidth()); 13 std::cout << "saved Map width " << map.getWidth() << endl; 14 al_fwrite32le(file, map.getHeight()); 15 std::cout << "saved Map Height " << map.getHeight() << endl; 16 17 for (int h = 0; h<map.getHeight(); h++) 18 { 19 for (int w = 0; w<map.getWidth(); w++) 20 { 21 std::cout << "iteration " << h*map.getWidth()+w << endl; 22 al_fwrite32le(file, map.map[h*map.getWidth()+w].getId()); 23 std::cout << "saved " << map.map[h*map.getWidth()+w].getId() << endl; 24 } 25 } 26 27 al_fclose(file); 28 std::cout << "Saved " << a << endl; 29 } 30 31} 32 33 34oid CLayer::load(std::string a, std::string b) 35{ 36 ALLEGRO_FILE* file; 37 ALLEGRO_FILE* file2; 38 39 file = al_fopen(a.c_str(), "r"); 40 file2 = al_fopen(b.c_str(), "r"); 41 42 if (file && file2) 43 {al_fclose(file2); 44 { 45 int fwidth = 0; 46 int fheight = 0; 47 48 fwidth = al_fread32le(file); 49 cout << "Loaded file Width - " << fwidth << endl; 50 fheight = al_fread32le(file); 51 cout << "Loaded file Height - " << fheight << endl; 52 create(fwidth, fheight, b); 53 cout << "created map with width " << fwidth << " Height " << fheight << " with pallet " << b << endl; 54 55 for (int h = 0; h<map.getHeight(); h++) 56 { 57 for (int w = 0; w<map.getWidth(); w++) 58 { 59 map.map[h*map.getWidth()+w].setId(al_fread32le(file)); 60 cout << "iteration " << h*map.getWidth()+w << endl; 61 cout << "Map Id " << map.map[h*map.getWidth()+w].getId() << endl; 62 63 map.map[h*map.getWidth()+w].setBmp(pallet.pallet[map.map[h*map.getWidth()+w].getId()].getBmp()); 64 } 65 } 66 67 al_fclose(file); 68 std::cout << "Loaded Map:"<< a << " With Pallet :" << b << endl; 69 loaded = true; 70 } 71 } 72 else 73 std::cout << "Could Not Load " << a << " Using " << b << endl; 74} 75 76void CLayer::create(int a, int b, std::string c) 77{ 78 ALLEGRO_FILE* file; 79 file = al_fopen(c.c_str(), "r"); 80 if(file) 81 { 82 al_fclose(file); 83 84 created = true; 85 pallet.pallet.clear(); 86 pallet = CPallet(c); 87 map = CMap(a, b); 88 89 CResourceGrabber& rg = rg.getInstance(); 90 map.setAllBmps(pallet.getBmp(0)); 91 brush.clear(); 92 brush.push_back(CTile(pallet.getBmp(0))); 93 brush[0].setX(0); 94 brush[0].setY(0); 95 96 brushWidth = 1; 97 brushHeight = 1; 98 brushVisible = false; 99 map.setVisible(false); 100 pallet.setVisible(false); 101 menu.setVisible(true); 102 std::cout << "Created a " << a<< "X"<< b << " Map for your amusement!\n"; 103 } 104 else 105 { 106 std::cout <<"Could Not Open " << c << " Creation Aborted!\n "; 107 } 108 109}

This is what I get from my console. Everything appears to save fine, and then when I load I get seemingly random -1.

{"name":"603620","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/e\/ce65aed8704e8cf820a069ae5b2971f6.jpg","w":690,"h":726,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/e\/ce65aed8704e8cf820a069ae5b2971f6"}603620
Really not sure why this happens.

Edgar Reynaldo
Member #8,592
May 2007
avatar

jason perkins said:

                  map.map[ (h+hh)*map.getWidth()+w+ww ].setId(brush[hh*brushWidth+ww].getId()); //This the problem

My guess is that you are accessing an index of brush that is out of bounds to begin with, and so you are getting a random number from getId().

Use a debugger - set a breakpoint on that line and examine brush.size(), hh, brushWidth, and ww to make sure you are accessing an index of brush that is in bounds.

The other thing, that whole second block of code looks suspicious, especially the part where you access map.map[ (h+hh)*map.getWidth()+w+ww ]. Are you sure you need to offset the index by hh and ww there? Won't that go out of bounds of your map?

Edit for your edit
Not sure what's going on with your saving/loading code. You could add in a check to make sure that the return value of al_fwrite32le is always 4 (bytes written).

From lookin at al_fread32le, -1 is also what it returns when it has reached the end of the file. Add in a check for al_feof to your loading code and make sure it's not hitting the end of the file prematurely.

Something else you can do is check the number of bytes in the file and compare it to (2*4 + 4*(map.Height()*map.Width())) to make sure the file is written correctly and can be read correctly.

Audric
Member #907
January 2001

In load: You read the width and height as fwidth and fheight, but then you loop over map.getWidth() and map.getHeight(), and write into map.map[] Between the two, I assume you should reallocate/reinit the map with these dimensions, so that getWidth() and getHeight() return the right values and the array has correct size.

Disregard that, I missed the create()

jason perkins
Member #10,524
January 2009

Yeah Edgar durring that block of code (that appears to be working, and I removed fromt he post). I'm copying the bitmaps/id's from my brush to the map. So if I click in the bottom right of my map, it will go out of bounds, but I check for it I get no issues from that.

I'm so out of Ideas at this point I'm just going to wipe this file and start from scratch thanks for taking the time to check though.

Edit: This just got a whole lot weirder. I tracked down the problem exactly And it's... strange.

Everything works fine up until I set a map id to equal exactly 26, if I try to load a file with a 26 in it it'll crash, 25 works, 27 works, 254 works... but 26 fails.

I'm just going to post the whole damn thing. There's nothing special about 26. So confused.

edit...

Well aparently it's just when I try to load a 26, The program is acting like the file ends So al_fread16be(...)When this encounters a 26 for some reason is returning as -1, and This is what's setting the rest of my map ids out of bounds

I've tried using al_fwrite/fread32le(), as well as casting the integers I'm saving to int32_t, and int16_t... nothings working.

#SelectExpand
1 2#include "headers.h" 3extern int currentLayer; 4CLayer::CLayer() 5{ 6 7 created = false; 8 loaded = false; 9 selectRectStartX = 0; 10 selectRectStartY = 0; 11 selectRect = false; 12 menu = CMenu(); 13 menu.setVisible(true); 14 brushVisible = false; 15 pallet.setVisible(false); 16 map.setVisible(false); 17 18 19 20} 21 22void CLayer::create(int a, int b, std::string c) 23{ 24 ALLEGRO_FILE* file; 25 file = al_fopen(c.c_str(), "r"); 26 if(file) 27 { 28 al_fclose(file); 29 created = true; 30 pallet.pallet.clear(); 31 pallet = CPallet(c); 32 map = CMap(a, b); 33 34 map.setAllBmps(pallet.getBmp(0)); 35 brush.clear(); 36 brush.push_back(CTile(pallet.getBmp(0))); 37 brush[0].setX(0); 38 brush[0].setY(0); 39 40 brushWidth = 1; 41 brushHeight = 1; 42 brushVisible = false; 43 map.setVisible(false); 44 pallet.setVisible(false); 45 menu.setVisible(true); 46 std::cout << "Created a " << a<< "X"<< b << " Map for your amusement!\n"; 47 } 48 else 49 { 50 std::cout <<"Could Not Open " << c << " Creation Aborted!\n "; 51 } 52 53} 54 55void CLayer::save(std::string a) 56{ 57 if (created== true) 58 { 59 ALLEGRO_FILE* file; 60 61 file = al_fopen(a.c_str(), "w"); 62 63 if(file) 64 al_fwrite16be(file, map.getWidth()); 65 al_fwrite16be(file, map.getHeight()); 66 67 for (int h = 0; h<map.getHeight(); h++) 68 { 69 for (int w = 0; w<map.getWidth(); w++) 70 { 71 al_fwrite16be(file, map.map[h*map.getWidth()+w].getId()); 72 } 73 } 74 75 al_fclose(file); 76 std::cout << "Saved " << a << endl; 77 } 78} 79 80void CLayer::load(std::string a, std::string b) 81{ 82 ALLEGRO_FILE* file; 83 ALLEGRO_FILE* file2; 84 85 file = al_fopen(a.c_str(), "r"); 86 file2 = al_fopen(b.c_str(), "r"); 87 88 if (file && file2) 89 {al_fclose(file2); 90 { 91 int fwidth = 0; 92 int fheight = 0; 93 94 fwidth = al_fread16be(file); 95 fheight = al_fread16be(file); 96 create(fwidth, fheight, b); 97 cout << "created map with width " << fwidth << " Height " << fheight << " with pallet " << b << endl; 98 99 for (int h = 0; h<map.getHeight(); h++) 100 { 101 for (int w = 0; w<map.getWidth(); w++) 102 { 103 map.map[h*map.getWidth()+w].setId(al_fread16be(file)); 104 map.map[h*map.getWidth()+w].setBmp(pallet.pallet[map.map[h*map.getWidth()+w].getId()].getBmp());//HERE if map.map[h*map.getWidth()+w].getId() is 26 the program crashes, 27 works, 244 works. 105 } 106 } 107 108 al_fclose(file); 109 std::cout << "Loaded Map:"<< a << " With Pallet :" << b << endl; 110 loaded = true; 111 } 112 } 113 else 114 std::cout << "Could Not Load " << a << " Using " << b << endl; 115} 116 117 118void CLayer::draw() 119{ 120 CInputManager& im = im.getInstance(); 121 122 if (map.isVisible()) 123 map.draw(); 124 if (menu.isVisible()) 125 menu.draw(); 126 if(pallet.isVisible()) 127 pallet.draw(); 128 if(brushVisible) 129 { 130 for (int i = 0; i< brush.size(); i++) 131 { 132 brush[i].draw(); 133 } 134 } 135 if(selectRect) 136 { 137 al_draw_rectangle(selectRectStartX, selectRectStartY, im.getMouseX(), im.getMouseY(), al_map_rgb(255, 0, 0), 4); 138 } 139} 140 141void CLayer::getInput() 142{ 143 if (created == true) 144 { 145 CInputManager& im = im.getInstance(); 146 147 if (im.esc() && !im.oldEsc()) 148 { 149 loaded = false; 150 if (!menu.isVisible()) 151 { 152 menu.setVisible(true); 153 map.setVisible(false); 154 brushVisible =false; 155 pallet.setVisible(false); 156 } 157 else 158 { 159 menu.setVisible(false); 160 map.setVisible(true); 161 brushVisible = true; 162 } 163 } 164 165 if (im.tab() && im.oldTab() && !menu.isVisible()) 166 { 167 pallet.setVisible(true); 168 map.setVisible(true); 169 brushVisible = false; 170 menu.setVisible(false); 171 } 172 else 173 { 174 pallet.setVisible(false); 175 } 176 177 if (!pallet.isVisible() && !menu.isVisible()) 178 { 179 brushVisible= true; 180 } 181 182 if (pallet.isVisible()) 183 { 184 185 if (im.rClick() && !im.oldRClick()) 186 { 187 //start drawing a rectangle to select multiple tiles 188 selectRect = true; 189 selectRectStartX = im.getMouseX(); 190 selectRectStartY = im.getMouseY(); 191 } 192 193 194 if (!im.rClick() && im.oldRClick()) 195 { 196 //user let go of right click, they've selected the tiles they want to be coppied to brush 197 //setting this rectangle so that rectx1/recty1 is the top left 198 if (im.getMouseX() <= selectRectStartX) 199 { 200 rectX1 = im.getMouseX(); 201 rectX2 = selectRectStartX; 202 } 203 204 else 205 { 206 rectX1 = selectRectStartX; 207 rectX2 = im.getMouseX(); 208 } 209 210 if (im.getMouseY() <= selectRectStartY) 211 { 212 rectY1 = im.getMouseY(); 213 rectY2 = selectRectStartY; 214 } 215 else 216 { 217 rectY1 = selectRectStartY; 218 rectY2 = im.getMouseY(); 219 } 220 221 brush.clear(); 222 //clear brush and add selected tiles to it. 223 for (int i = 0; i < pallet.pallet.size(); i++) 224 { 225 if (pallet.pallet[i].getX() + TILE_SIZE >= rectX1 && pallet.pallet[i].getX() <= rectX2 && 226 pallet.pallet[i].getY() + TILE_SIZE >= rectY1 && pallet.pallet[i].getY() <= rectY2) 227 { 228 brush.push_back(CTile(pallet.pallet[i].getBmp())); 229 230 brush[brush.size()-1].setId(i);//HERE--- If This is 26, and I copy it to my map and save it 231 // The program crashes when I load 232 brush[brush.size()-1].setX(pallet.pallet[i].getX()/TILE_SIZE); 233 brush[brush.size()-1].setY(pallet.pallet[i].getY()/TILE_SIZE); 234 235 } 236 } 237 238 if (brush.size() <1 ) 239 //if for some reason brush size == 0, fill it with something 240 { 241 brush.push_back(CTile(pallet.pallet[0].getBmp())); 242 } 243 244 for (int i = 0; i < brush.size(); i++) 245 { 246 // move the brush to the top left of the screen 247 if (i == 0) 248 { 249 moveThisFarX = brush[i].getX()/TILE_SIZE; 250 moveThisFarY = brush[i].getY()/TILE_SIZE; 251 } 252 brush[i].setX(brush[i].getX()/TILE_SIZE - moveThisFarX); 253 brush[i].setY(brush[i].getY()/TILE_SIZE - moveThisFarY); 254 } 255 256 brushWidth = (brush[brush.size()-1].getX()/TILE_SIZE+1); 257 brushHeight = (brush[brush.size()-1].getY()/TILE_SIZE+1); 258 selectRect = false; 259 } 260 } 261 262 if (map.isVisible()) 263 { 264 if (im.lClick() && ! im.tab()) 265 { 266 //set an area of the map to equal what brush is. 267 268 for (int h = 0; h<map.getHeight(); h++) 269 { 270 for (int w = 0; w<map.getWidth(); w++) 271 272 { 273 274 if (map.map[h*map.getWidth()+w].getX() < im.getMouseX() && map.map[h*map.getWidth()+w].getX() + TILE_SIZE > im.getMouseX() && 275 map.map[h*map.getWidth()+w].getY() < im.getMouseY() && map.map[h*map.getWidth()+w].getY() + TILE_SIZE > im.getMouseY() ) 276 { 277 278 for (int hh = 0; hh<brushHeight; hh++) 279 { 280 for (int ww = 0; ww < brushWidth; ww++) 281 { 282 if ((h+hh)*map.getWidth()+w+ww < map.getWidth()*map.getHeight()) 283 { 284 285 map.map[ (h+hh)*map.getWidth()+w+ww ].setBmp(brush[hh*brushWidth+ww].getBmp()); 286 287 //if (brush[hh*brushWidth+ww].getId() != 26)//##### THIS If the Id is anything 288 //other Than 26, saving/loading works as intended 289 map.map[ (h+hh)*map.getWidth()+w+ww ].setId(brush[hh*brushWidth+ww].getId()); 290 } 291 } 292 293 } 294 295 } 296 } 297 } 298 } 299 300 if (!im.tab()) 301 { 302 map.getInput(); 303 } 304 } 305 306 if (pallet.isVisible()) 307 { 308 if (im.lClick() ) 309 { 310 //if left clicking pallet, set brush's id to equal that pallet Id 311 312 for (int h = 0; h<pallet.getHeight(); h++) 313 { 314 for (int w = 0; w<pallet.getWidth(); w++) 315 { 316 if (pallet.pallet[h*pallet.getWidth()+w].getX() < im.getMouseX() && pallet.pallet[h*pallet.getWidth()+w].getX() + TILE_SIZE >im.getMouseX() && 317 pallet.pallet[h*pallet.getWidth()+w].getY() < im.getMouseY() && pallet.pallet[h*pallet.getWidth()+w].getY() + TILE_SIZE >im.getMouseY() ) 318 { 319 brush.clear(); 320 brush.push_back(CTile(pallet.pallet[h*pallet.getWidth()+w].getBmp())); 321 brush[brush.size()-1].setId(h*pallet.getWidth()+w); 322 brushWidth = 1; 323 brushHeight = 1; 324 } 325 326 } 327 } 328 } 329 pallet.getInput(); 330 } 331 332 } 333 if (menu.isVisible()) 334 { 335 menu.getInput(currentLayer); 336 } 337}

Edit:: problem Solved in another thread, thanks guys!!

Go to: