PHP Code:
ofstream fout;
fout.open("res.epe", ios::binary);
bin_res_start(&fout, 1);
bin_write_sprite(&fout, "spr_blank.gif", 0, IT_GIF, 1, 1);
fout.close();
Then I read the sprite like this:
PHP Code:
// turns a 0-65535 integer into 2 bytes
char *pack(unsigned int value, char buffer[2])
{
buffer[0] = (value >> 8);
buffer[1] = (value & 255);
return (buffer);
}
// turns 2 bytes into a 0-65535 integer
unsigned int unpack(char byteA, char byteB)
{
return ((static_cast<unsigned int>(byteA) << 8) | byteB);
}
// heads the file
// rs is the number of sprites that are going to be put into the file
void bin_res_start(ofstream *fout, unsigned int rs)
{
char p[2];
*fout << pack(rs, p);
unsigned int i = 0;
while (i < (rs*9))
{
*fout << '\0';
i++;
}
}
// write a sprite into the file as well as its type and width and height
// rn is the index of the sprite in the file (if its the 4th sprite to be put in the file its index is 3)
void bin_write_sprite(ofstream *fout, string fname, int rn, unsigned int type, unsigned int w, unsigned int h)
{
char p[2]; // used to pack integers into bytes
ifstream fin; // open the sprite
fin.open(fname.c_str(), ios::in|ios::binary);
fout->seekp(0, ios::end); // find the file size of the current file
unsigned int fsizeFout = fout->tellp();
fin.seekg(0, ios::end); // find the file size of the sprite
unsigned int fsizeFin = fin.tellg();
fin.seekg(0); // seek to the position where the information about the sprite will be written
fout->seekp((rn*9) + 2);
*fout << static_cast<unsigned char>(type); // write the type of sprite (GIF, PNG, etc..)
*fout << pack(w, p); // write the width of the sprite
*fout << pack(h, p); // write the height of the sprite
*fout << pack(fsizeFout, p); // write the current file size (thats where the actual sprite will be written at, this way I can seek there to read it)
*fout << pack(fsizeFin, p); // write the file size of the sprite (so that I can loop through to read it into memory)
string buffer; // to store the contents of the sprite
unsigned int i = 0;
while (i < fsizeFin) // loop through the sprite and add it to buffer
{
buffer += fin.get();
i++;
}
fout->seekp(0, ios::end); // seek to the end of the file to append the sprite
*fout << buffer; // write the sprite
fin.close();
}
// reads a sprite from a res file
// rn is the index of the file to be read
int bin_read_sprite(ifstream *fin, int rn)
{
fin->seekg((rn*9) + 2); // seek to the position where all the information about the sprite is stored
unsigned char type = fin->get(); // get the type
unsigned int w = unpack(fin->get(), fin->get()); // get the width
unsigned int h = unpack(fin->get(), fin->get()); // get the height
unsigned int b = unpack(fin->get(), fin->get()); // get the starting location of the sprite
unsigned int e = unpack(fin->get(), fin->get()); // get the file size of the sprite
SDL_RWops *rw;
string buffer;
fin->seekg(b); // seek to the position of the sprite
int i = 0;
while (i < e) // read the sprite into a string
{
buffer += fin->get();
i++;
}
rw = SDL_RWFromConstMem(buffer.c_str(), e); // set the RWops to the buffer
return load_sprite(rw, type, w, h); // load the sprite
}
// load the sprite from a RWops
// type is the type of image (GIF, PNG, etc..)
// w is the width of the sprite
// h is the height of the sprite
int load_sprite(SDL_RWops *rw, int type, int width, int height)
{
sprite *s = new sprite;
s->set_sprite(rw, type, width, height);
engine::sprVector.push_back(s);
return engine::sprVector.size();
}
class sprite
{
public:
sprite()
{
si++; // index
_si = si;
}
~sprite()
{
int
cap = _frameVector.size(),
i = 0;
while (i < cap) // delete allocated memory
{
delete _frameVector[i];
i++;
}
}
void set_sprite_from_sprite(SDL_Surface *_sprite, int width, int height) // create new SDL_rects for the frames of the sprite
{
int i = 1, j = 1;
while (width*i <= _sprite->w)
{
while (height*j <= _sprite->h)
{
SDL_Rect *r = new SDL_Rect;
r->x = width*(i - 1);
r->y = height*(j - 1);
r->w = width;
r->h = height;
_frameVector.push_back(r);
j++;
}
j = 1;
i++;
}
}
void set_sprite(SDL_RWops *rw, int type, int width = 0, int height = 0) // set the _sprite to an image
{
_sprite = load_image(rw, type);
set_sprite_from_sprite(_sprite, width, height);
}
void set_sprite(string filename, int width = 0, int height = 0)
{
_sprite = load_image(filename.c_str());
set_sprite_from_sprite(_sprite, width, height);
}
SDL_Surface * get_sprite() const
{
return _sprite;
}
SDL_Rect * get_frame(int index) const
{
if (index < _frameVector.size())
{
return _frameVector[index];
}
else
{
return NULL;
}
}
private:
SDL_Surface *_sprite;
int _width;
int _height;
int _si;
vector<SDL_Rect*>_frameVector;
static int si;
};
SDL_Surface *load_image(SDL_RWops *rw, int type)
{
SDL_Surface *loadedImage = NULL; // temp storage for the image being loaded
SDL_Surface *optimizedImage = NULL; // the optimized image; image that will be used
switch (type)
{
case IT_PNG:
loadedImage = IMG_LoadPNG_RW(rw);
break;
case IT_GIF:
loadedImage = IMG_LoadGIF_RW(rw);
break;
}
if (loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat(loadedImage); // optimize the image; change its bpp to the screen's
SDL_FreeSurface(loadedImage); // free the non-optimized image
if (optimizedImage != NULL)
{
Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF);
SDL_SetColorKey(optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey);
}
}
return optimizedImage;
}
I know this is a lot to look through, but I've been trying to find the bug for a few days and I'm getting no where so I would really appreciate it if someone who knows what they are doing could lend a hand. Thank you for your time.