Bitmap Loader

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
User avatar
npissoawsome
Posts: 114
Joined: June 8th, 2012, 3:01 pm

Bitmap Loader

Post by npissoawsome » June 8th, 2012, 3:08 pm

Alright, well this is the first thing I've done, and I think it's quite impressive... For all of you kids trying to get BMP's to work, but can't you can use this code...

Features
- Can load 24/32 bitmaps
- Can load an array of bmps
- Can play an array of bitmaps
- Can draw single bitmaps

This is the header

Code: Select all

#pragma once
#include "D3DGraphics.h"
#include <d3d9.h>
#include <cstdio>
#include <assert.h>
#include <vector>

using std::vector;
using std::stringstream;
using std::string;

class Bitmap
{
public:
	Bitmap();
	Bitmap( int, int );
	~Bitmap();
	void ArraySet( int, int );
	int timer, maxtimer, index, frames;
	void LoadBMP( const char* );
	void DrawBMP( int, int, D3DGraphics* );
private:
	struct BitmapHeader
	{
		unsigned int filesize;
		unsigned short reserve1;
		unsigned short reserve2;
		unsigned int offset;
	};
	struct BitmapFileHeader
	{
		unsigned int size;
		int width, height;
		unsigned short planes;
		unsigned short bits;
		unsigned int compression;
		unsigned int imageSize;
		int xResolution, yResolution;
		unsigned int nColors;
	};
	struct Pixel24
	{
		unsigned char blue;
		unsigned char green;
		unsigned char red;
	};
	struct Pixel32
	{
		unsigned char alpha;
		unsigned char blue;
		unsigned char green;
		unsigned char red;
	};
	int imageSize;
	BitmapHeader bmpheader;
	BitmapFileHeader bmpfheader;
	FILE* bmpfile;
	D3DCOLOR* surfs;
	char sig[2];
	void Load32( FILE* bmp );
	void Load24( FILE* bmp );
};

void LoadBMP( Bitmap &bmp, const char* );
void DrawBMP( Bitmap &bmp, int, int, D3DGraphics* );
void LoadBMPs( vector<Bitmap> & bmps, const char*, const int, int);
void DrawBMPs( vector<Bitmap> & bmps, int, int, D3DGraphics* );
bool file_exists(const char *);
And this is the cpp file

Code: Select all

#include "Bitmap.h"
#include <string>
#include <sstream>

Bitmap::Bitmap()
{}

Bitmap::~Bitmap()
{}

/* * * * * * * * * * * *
 Initial Function Calls
 * * * * * * * * * * * */

void LoadBMP( Bitmap &bmp, const char* filename )
{
	bmp.LoadBMP( filename );
}

void DrawBMP( Bitmap &bmp, int xoff, int yoff, D3DGraphics* gfx )
{
	bmp.DrawBMP( xoff, yoff, gfx );
}

void LoadBMPs( vector<Bitmap> &bmps, const char* fname, int length, int speed )
{
	stringstream stream;
	string str;

	bmps.resize(length);

	for( int i = 0; i < length; i++ )
	{
		if( i < 10 )
			stream << fname << "0" << i << ".bmp";
		else
			stream << fname << i << ".bmp";
		str = stream.str();
		assert(file_exists(str.c_str()));
		bmps[i].LoadBMP( str.c_str() );
		stream.str( std::string() );
		stream.clear();
	}

	bmps[0].ArraySet( length, speed );
}

void DrawBMPs( vector<Bitmap> &bmps, int x, int y, D3DGraphics* gfx )
{
	bmps[0].timer++;
	if(bmps[0].timer > bmps[0].maxtimer)
	{
		bmps[0].index++;
		if(bmps[0].index >= bmps[0].frames)
			bmps[0].index = 0;
		bmps[0].timer = 0;
	}

	bmps[bmps[0].index].DrawBMP( x, y, gfx );
}

/* * * * * * * * * * * * * * *
 Bitmap Class Loaders/Drawers
 * * * * * * * * * * * * * * */

void Bitmap::LoadBMP( const char* filename )
{
	assert(file_exists(filename));
	bmpfile = fopen( filename, "rb" );
	fread( &sig, sizeof( char ), 2, bmpfile );
	fread( &bmpheader, sizeof( bmpheader ), 1, bmpfile );
	fread( &bmpfheader, sizeof( bmpfheader ), 1, bmpfile );

	imageSize = bmpfheader.height * bmpfheader.width;
	surfs = new D3DCOLOR[imageSize];

	if(bmpfheader.bits == 24)
		Load24( bmpfile );
	else if(bmpfheader.bits == 32)
		Load32( bmpfile );

	fclose( bmpfile );
}

void Bitmap::Load32(FILE* bmp)
{
	Pixel32 pix;
	int padding;

	fseek( bmpfile, bmpheader.offset, SEEK_SET );

	for(int y = 0; y < bmpfheader.height; y++)
	{
		for(int x = 0; x < bmpfheader.width; x++)
		{
			fread( &pix, sizeof(pix), 1, bmpfile );
			surfs[ x + (y * bmpfheader.width) ] = D3DCOLOR_ARGB( pix.alpha, pix.red, pix.green, pix.blue );
		}
	}
}

void Bitmap::Load24(FILE* bmp)
{
	Pixel24 pix;
	int padding;

	fseek( bmpfile, bmpheader.offset, SEEK_SET );

	padding = 4 - (( bmpfheader.width * (bmpfheader.bits / 8)) % 4);

	for(int y = 0; y < bmpfheader.height; y++)
	{
		for(int x = 0; x < bmpfheader.width; x++)
		{
			fread( &pix, sizeof(pix), 1, bmpfile );
			surfs[ x + (y * bmpfheader.width) ] = D3DCOLOR_XRGB( pix.red, pix.green, pix.blue );
		}
		if(!(padding == 4 || padding == 0))
			fseek( bmpfile, padding, SEEK_CUR );
	}
}

void Bitmap::ArraySet( int a, int b )
{
	frames = a;
	maxtimer = b;
	timer = 0;
	index = 0;
}

void Bitmap::DrawBMP( int xoff, int yoff, D3DGraphics* gfx )
{
	for(int y = 0; y < bmpfheader.height; y++)
	{
		for(int x = 0; x < bmpfheader.width; x++)
		{
			gfx->PutPixel( x+xoff, y+yoff, surfs[ x + ((bmpfheader.height - (y + 1)) * bmpfheader.width)]);
		}
	}
}

/* * * * * * * * * *
 Checks for Loading
 * * * * * * * * * */

bool file_exists(const char * filename)
{
    if (FILE * file = fopen(filename, "r"))
    {
        fclose(file);
        return true;
    }
    return false;
}
here's the example game.h

Code: Select all

#pragma once

#include "D3DGraphics.h"
#include <Windows.h>
#include <d3dx9.h>
#include <vector>
#include "Keyboard.h"
#include "Mouse.h"
#include "Sound.h"
#include "Bitmap.h"

class Game
{
public:
	Game( HWND hWnd,const KeyboardServer& kServer,const MouseServer& mServer );
	~Game();
	void Go();
private:
	void ComposeFrame();
private:
	D3DGraphics gfx;
	KeyboardClient kbd;
	MouseClient mouse;
	DSound audio;
	vector<Bitmap> dudes;
	vector<Bitmap> character;
	Bitmap chr;
};
and here's an example game.cpp

Code: Select all

#include "Game.h"
#include "Bitmap.h"

Game::Game( HWND hWnd,const KeyboardServer& kServer,const MouseServer& mServer )
:	gfx( hWnd ),
	audio( hWnd ),
	kbd( kServer ),
	mouse( mServer )
{
	LoadBMPs( dudes, "WalkinDude\\wdude", 14, 3 );
	LoadBMPs( character, "Character\\character", 5, 8 );
	LoadBMP( chr, "Bitmaps\\character32.bmp" );
}

Game::~Game()
{}

void Game::Go()
{
	gfx.BeginFrame();
	ComposeFrame();
	gfx.EndFrame();
}

void Game::ComposeFrame()
{
	DrawBMPs( dudes, 10, 10, &gfx );
	DrawBMPs( character, 100, 10, &gfx );
	DrawBMP( chr, 200, 10, &gfx );
}
self explanatory code really, but if you have any questions, post it in the comment

If anyone finds bugs using this code, please do tell me :)
Attachments
Code.zip
Source Code for this "project"
(204.77 KiB) Downloaded 194 times
Last edited by npissoawsome on June 8th, 2012, 4:13 pm, edited 1 time in total.

User avatar
LuX
Posts: 1492
Joined: April 22nd, 2012, 12:33 pm
Location: Finland

Re: Bitmap Loader

Post by LuX » June 8th, 2012, 3:11 pm

Cool, but bitmap loading was pretty much explained in lesson 20 and 21, in case you haven't watched them yet. I guess the bitmap 32 is a new edition to it however.
ʕ •ᴥ•ʔ

User avatar
npissoawsome
Posts: 114
Joined: June 8th, 2012, 3:01 pm

Re: Bitmap Loader

Post by npissoawsome » June 8th, 2012, 3:13 pm

LuX wrote:Cool, but bitmap loading was pretty much explained in lesson 20 and 21, in case you haven't watched them yet. I guess the bitmap 32 is a new edition to it however.
Oh no, I've seen it, and a fair amount of code is derived from it, but there's a bunch of new stuff, compile & run it, you'll see what I'm talking about

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Bitmap Loader

Post by chili » June 8th, 2012, 3:24 pm

Looks like you've made it more robust and stuff by supporting more formats. A good exercise indeed. :)

Now search the forums, find my fukbmp solution, and figure out how to use GDI+ for loading imagfe files. It is the API that we will be eventually using to load all our image files (although we may use D3DX too in certain cases too, haven't decided yet).

P.S.

It is customary in this forum to post our solution folder after we ahve cleaned and zipped them. chewck out the topic 'READ T}HIS FIRST' for more details. You can also check out Asimov's batch file to hfelp you clean your solution with a minimum of effort. :)
Chili

User avatar
npissoawsome
Posts: 114
Joined: June 8th, 2012, 3:01 pm

Re: Bitmap Loader

Post by npissoawsome » June 8th, 2012, 4:06 pm

chili wrote:Looks like you've made it more robust and stuff by supporting more formats. A good exercise indeed. :)

Now search the forums, find my fukbmp solution, and figure out how to use GDI+ for loading imagfe files. It is the API that we will be eventually using to load all our image files (although we may use D3DX too in certain cases too, haven't decided yet).

P.S.

It is customary in this forum to post our solution folder after we ahve cleaned and zipped them. chewck out the topic 'READ T}HIS FIRST' for more details. You can also check out Asimov's batch file to hfelp you clean your solution with a minimum of effort. :)
Alright, I'll go check out the read this first post

EDIT:
Alright, added the project

Also, I'd highly suggest someone running this, you might be impressed with how easily you can animate BMPs ;)

Post Reply