Pitäis saada nuo tileInfoTable ja tileDataTable taulukoiksi, yhden alkion kokoisiksi. Miten pitäis menetellä? Tämäs siksi, jotta memcpy toimii... niin ainakin #ohjelmointiputka:lla sanottiin.
#define MPL_SUCCESS 1 #define MPL_FILE_NOT_FOUND 2 #define MPL_SYNTAX_ERROR 3 #define MPL_MISSING_TILE 4 struct Tile{ int X; int Y; int Width; int Height; bool Solid; unsigned int HitTop; unsigned int HitBottom; unsigned int HitLeft; unsigned int HitRight; char Name[256]; char Filename[256]; }; struct TileData{ char Name[256]; SDL_Surface *Data; }; Tile *tileInfoTable; TileData *tileDataTable; int LoadMap(char filename[255]) { FILE *tiedosto; tiedosto = fopen(filename, "r"); if (tiedosto!=NULL) { // TÄSSÄ PITÄIS SAADA NOI tileInfoTable ja tileDataTable yhen alkion kokosiks tauluiks, mite onnistuu? Datan menetyksellä ei ole väliä koska tässä kohtaa kumminkin pitäisi tyhjentää nuo taulut. char rivi[256]; bool tiledef, tiledefStarted, tiledefBracketStarted, mapdef, mapdefStarted, mapdefBracketStarted; tiledef=tiledefStarted=mapdef=mapdefStarted=tiledefBracketStarted=mapdefBracketStarted=false; while(!feof(tiedosto)) { fgets(rivi, 255, tiedosto); if ((strcmp(rivi, "TILEDEF") == 0) && tiledefStarted == false) { tiledefStarted=true; } else if (tiledefStarted == true && (strcmp(rivi, "{") == 0)) { tiledefBracketStarted=true; } else if (tiledefBracketStarted == true && (strcmp(rivi, "}") == 0)) { tiledefBracketStarted=tiledefStarted=false; tiledef=true; } else if (tiledefBracketStarted == true) { int vanhakoko; vanhakoko = sizeof(tileInfoTable) / sizeof(Tile); Tile *uusi = new Tile[vanhakoko+1]; memcpy(uusi, tileInfoTable, vanhakoko * sizeof(Tile)); delete[] tileInfoTable; tileInfoTable = uusi; TileData *uusi2 = new TileData[vanhakoko+1]; memcpy(uusi2, tileDataTable, vanhakoko * sizeof(TileData)); delete[] tileDataTable; tileDataTable = uusi2; sscanf(rivi, "\"%s\" \"%s\"", &tileInfoTable[vanhakoko]->Name); // kesken... } else { return MPL_SYNTAX_ERROR; } } } else { return MPL_FILE_NOT_FOUND; } return MPL_SUCCESS; } /* int CheckHit(Tile lahde, Tile kohde) { int lahdeX2 = lahde.X + lahde.Width; int lahdeY2 = lahde.Y + lahde.Height; int kohdeX2 = kohde.X + kohde.Width; }*/ /* <thefox> square35, uusi=new paska[uusikoko];memcpy(uusi,vanha,vanhakoko);delete[] vanha;vanha=uusi; <thefox> (kun uusikoko>vanhakoko) <thefox> memcpy(uusi,vanha,vanhakoko*sizeof(paska)) tietysti pitäis olla */
Ei, ei ja ei; memcpy haluaa osoittimen. Taulukko on vain silmänlumetta :)
Tile Yksi_Tile; Tile * Tile_Ptr = new Tile; // Muistin kohtaan &Yksi_Tile kopioidaan kohdasta Tile_Ptr sizeof(Tile) tavua. memcpy(&Yksi_Tile, Tile_Ptr, sizeof(Tile));
Siis osoitin siihen kohti muistia, mihin kopioidaan, ja siihen, mistä kopioidaan, ja lopuksi kopioitavien tavujen määrä.
Hmmm... nyt pitää olla varovainen (Jos sovelletaan Metabolixin esimerkkiä suoraan tuohon ohjelmaan), ettei tule käytettyä delete[]-operaattoria vapauttamaan muistia, joka pitäisi vapauttaa deletellä.
Jos nyt käsitin asiaa alkuunkaan, niin mikäs vika tästä puuttuu:
tileInfoTable = new Tile[1];
Tietysti pitää kutsua välillä delete[]:ä, jos tuota ajetaan monta kertaa.
Muuttelin systeemiä eilenillalla aika paljon, ja koodi on nyt tällainen:
#define MPL_SUCCESS 1 #define MPL_FILE_NOT_FOUND 2 #define MPL_SYNTAX_ERROR 3 #define MPL_MISSING_TILE 4 struct TilePlacement{ int X; int Y; int ID; }; struct TileData{ int solid; SDL_Surface *Data; }; TileData *tileDataTaulu = NULL; TilePlacement *tilePlacementTaulu = NULL; int LoadMap(char filename[255]) { if (tileDataTaulu){free(tileDataTaulu);tileDataTaulu=0;} if (tilePlacementTaulu){free(tilePlacementTaulu);tilePlacementTaulu=0;} FILE *tiedosto; tiedosto = fopen(filename, "r"); if (tiedosto!=NULL) { char rivi[256]; bool tiledata=false, mapdata=false, tiledim=false, mapdim=false; unsigned int tileamount, mapSizeX, mapSizeY, menossa=0; while(!feof(tiedosto)) { fgets(rivi, 255, tiedosto); int paikka = 0; while (paikka < 255) { if (rivi[paikka] == '\r') { rivi[paikka] = '\0'; } else if (rivi[paikka] == '\n') { rivi[paikka] = '\0'; } ++paikka; } std::cout << "Rivi luettu!" << std::endl; std::cout << "\"" << rivi << "\"" << std::endl; if (strcmp(rivi, "TILEDATA") == 0) { tiledata=true; std::cout << "Tiledata alkoi!" << std::endl; } else if (tiledata == true) { if (strcmp(rivi, "MAPDATA") == 0) { tiledata = false; mapdata = true; std::cout << "Mapdata alkoi!" << std::endl; } else if (tiledim == false) { sscanf(rivi, "%d", &tileamount); std::cout << "tilemäärä: " << tileamount << std::endl; tileDataTaulu = (TileData *) realloc(tileDataTaulu, tileamount * sizeof(TileData)); tiledim=true; std::cout << "Suurennettiin tiletaulu." << std::endl; } else if (tiledim == true) { char filu[256]; sscanf(rivi, "%s %d", &filu, &tileDataTaulu[menossa].solid); tileDataTaulu[menossa].Data = SDL_LoadBMP(filu); if (tileDataTaulu[menossa].Data == NULL) { return MPL_MISSING_TILE; } std::cout << "Menossa: " << menossa << std::endl; std::cout << "Ladattiin tile: " << filu << std::endl; ++menossa; } } else if (mapdata == true) { } rivi[0] = '\0'; } } else { return MPL_FILE_NOT_FOUND; } return MPL_SUCCESS; } void tyhjennaMuisti(void) { free(tileDataTaulu); free(tilePlacementTaulu); } /* int CheckHit(Tile lahde, Tile kohde) { int lahdeX2 = lahde.X + lahde.Width; int lahdeY2 = lahde.Y + lahde.Height; int kohdeX2 = kohde.X + kohde.Width; }*/ /* <Metabolix> Tyyppi * Taulu = (Tyyppi *) malloc(Taulun_Koko * sizeof(Tyyppi)); <Metabolix> Taulu = (Tyyppi *) realloc(Taulu, Uusi_Koko * sizeof(Tyyppi)); <Metabolix> free(Taulu); */
EDIT: Tuo toimii ainakin mielestäni ihan oikein.
Elikkä olet siirtynyt C-tyyliseen muistinvaraukseen. Käyhän se noinkin, ainakin niin kauan kun TilePlacementillä ja TileDatalla ei tarvitse olla konstruktoria eikä destruktoria, niitä kun ei free ja realloc kutsu.
Sen verran vielä, että jos tuossa C++-tyyliin siirtyisi ja tarvitsisi niitä konstruktoreita, niin jatkuva new-memcpy-delete kutsuisi paljon turhia kutsuja. Jokin STL-container, esimerkiksi vector, voisi olla harkittava ajatus.
Aihe on jo aika vanha, joten et voi enää vastata siihen.