Olen tekemässä level makeria peliini. Se lukee bmp tiedostosta pikselin kirkkauden ja tekee siitä arvon maaston korkeudeksi. Ohjelmani on kuitenkin buginen ja tarvitsen apua.
Jossain vaiheessa dataa generoidut tiedostot rupeavat kirjoittamaan vain tavua 255. Kohta riippuu kuvan koosta, ei siitä, mitä tiedostossa on sisällä. Esim 50*50 kuvassa ei ole bugia. Mistä tämä johtuu ja miten tämän voi korjata?
Exe tiedostot ja esimerkki levelit: http://zux.sjr.fi/touho/levelmaker.zip
bmp_to_lvl.exe tekee level tiedoston bmp tiedostosta.
bmp_to_txt.exe tekee txt tiedoston, jossa tavut on numeroina.
lvl_to_txt.exe tekee txt tiedoston, jossa tavut on numeroina.
Laitoin zippiin kaksi kuvaa mukaan. Valitsin yksilöt, joista aiheutuu bugi.
Pelini level tiedoston formaatti:
leveys (2 tavua) (leveys = ensimmäinen + 256*toinen)
korkeus (2 tavua)
data (leveys*korkeus tavua) vasemmalta alhaalta lähtien oikealle kerroksittain
Bittikartan formaatti: http://en.wikipedia.org/wiki/Windows_and_OS/2_bitmap
bmp_to_txt.exe (ja lvl_to_txt.exe, vain eri tiedostonnimet)
#include <fstream> using namespace std; int main() { int c; ifstream bmp; ofstream log; bmp.open("level.bmp"); log.open("level.txt"); if(bmp.good() && log.good()) { while(bmp.good()) { c = bmp.get(); log << c << "\n"; } } bmp.close(); log.close(); return 0; }
bmp_to_lvl.exe
#include <fstream> using namespace std; int main() { int c, i; int width=0; int height=0; int x, y; int start; ifstream bmp; ofstream log; bmp.open("level.bmp"); log.open("level"); if(bmp.good() && log.good()) { for(i=0;i<10;i++) bmp.get(); start = bmp.get(); for(i=0;i<7;i++) bmp.get(); width = bmp.get() + bmp.get()*256; for(i=0;i<2;i++) bmp.get(); log.put(width%256); log.put((width/256)%256); height = bmp.get() + bmp.get()*256; for(i=0;i<2;i++) bmp.get(); log.put(height%256); log.put((height/256)%256); for(i=0;i<start-18-8;i++) bmp.get(); for(y=0;y<height;y++) { for(x=0;x<width;x++) { c = (bmp.get() + bmp.get() + bmp.get())/3; log.put(c); } for(i=0;i<(4-(3*width)%4)%4;i++) bmp.get(); } } bmp.close(); log.close(); return 0; }
Ongelma ratkesi niin, että muutin kuvan skaalan tästä: 0-255 tähän: 1-255. Ohjelmani jostain syystä ei pystynyt lukemaan 0-tavuja.
Kokeilepa avata streamit binaarina eli ios::bin-lipulla. Ja kuinka käy \r- ja \n-tavuille, lukeutuvatko oikein? Windowsissa voivat kummatkin muuttua \r\n-pariksi.
\n toimii hyvin. \r tavun yli ohjelma hyppää. Tavuun 26 ohjelma lopettaa kokonaan lukemisen.
EDIT: kääntäjä sanoo, että: `bin' is not a member of `std::ios'.
http://www.cppreference.com/io_flags.html#mode_flags
kertoo, että se on binary, eikä bin.
Laitoin tuon flagin. Nyt se muuttaa tavun 13 tavuksi 14 ja tavun 26 tavuksi 27. Tämä jo kelpaa, mutta onko mahdollista saada myös tavut 13 ja 26 käyttöön?
Ettet vain itse jotenkin muuttele noita tavuja? Sinulla kun taisi aiemminkin olla jokin viritys nollatavujen käsittelyyn...
Ei. Käytin ihan samaa koodia.
ifstream bmp; ofstream log; bmp.open("height.bmp", ios::binary); log.open("out.txt", ios::binary); int c; ... while(bmp.good()) { c = bmp.get(); log << c << "\n"; }
Voisiko olla niin, että luettavassa tiedostossa ei olekaan ihan sitä, mitä kuvittelet siellä olevan? Oletko tutkinut asiaa millään hexdump-ohjelmalla?
Kun tiedosto avataan binary-moodissa ja sitä luetaan get-funktiolla, minkäänlaisia muunnoksia ei kuulu tapahtua, korkeintaan tiedoston lopusta voi tulla ylimääräisiä nollia. Ja standardikirjaston toteutuksissa on yleensä vähemmän bugeja kuin käyttäjien koodissa, joten... Mutta mitä kääntäjää ja kirjastoa muuten käytät?
Tein juuri testin, missä oli korkeutta 26 ja 27 sekä 13 ja 14 vierekkäin. Korkeuseroja näkyi, joten minusta tuntuu, että kaikki on sittenkin ok. Kiitos paljon avusta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.