Вот простенький загрузчик BMP файла который я написал основываясь на
уроках Андре Ламота:
Код:
#define WIN32_LEAN_AND_MEAN
#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"ddraw.lib")
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>
#define WIDTH 640
#define HEIGHT 480
#define BPP 32
//////////////////////////////////////////////////////////////////////////
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))
//////////////////////////////////////////////////////////////////////////
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader;
BITMAPINFOHEADER bitmapinfoheader;
PALETTEENTRY palette[256];
UCHAR *buffer;
} BITMAP_FILE, *BITMAP_FILE_PTR;
//////////////////////////////////////////////////////////////////////////
int Load_Image(BITMAP_FILE_PTR bitmap,char *name);
int Init_Game();
int Game_Render();
int Shutdown_Game();
//////////////////////////////////////////////////////////////////////////
LPDIRECTDRAW7 d3d7=NULL;
LPDIRECTDRAWSURFACE7 pBuffer=NULL;
LPDIRECTDRAWSURFACE7 sBuffer=NULL;
DDSURFACEDESC2 ddsd;
BITMAP_FILE bitmap;
HWND hwnd;
MSG msg;
//////////////////////////////////////////////////////////////////////////
int Load_Image(BITMAP_FILE_PTR bitmap,char *name)
{
FILE *fImage;
fImage=fopen(name,"rb");
fread(&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER),1,fImage);
fread(&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER),1,fImage);
bitmap->buffer=(UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage);
fread(bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage,1,fImage);
fclose(fImage);
return 0;
}
////////////////////////////////////////////////////////////
int Draw_Image(int width,int height)
{
pBuffer->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
DWORD *primary_buffer = (DWORD *)ddsd.lpSurface;
for (int index_y = 0; index_y < height; index_y++)
{
for (int index_x = 0; index_x < width; index_x++)
{
UCHAR blue = (bitmap.buffer[index_y*width*3 + index_x*3 + 0]),
green = (bitmap.buffer[index_y*width*3 + index_x*3 + 1]),
red = (bitmap.buffer[index_y*width*3 + index_x*3 + 2]);
DWORD pixel = _RGB32BIT(0,red,green,blue);
primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;
}
}
pBuffer->Unlock(NULL);
return 0;
}
////////////////////////////////////////////////////////////
LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
case WM_CREATE:
{
return 0;
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}break;
default:break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX win;
win.cbSize = sizeof(WNDCLASSEX);
win.style = CS_HREDRAW | CS_VREDRAW;
win.lpfnWndProc = WinProc;
win.cbClsExtra = 0;
win.cbWndExtra = 0;
win.hInstance = hinstance;
win.hIcon = LoadIcon(NULL, IDI_APPLICATION);
win.hCursor = LoadCursor(NULL, IDC_ARROW);
win.hbrBackground = NULL;
win.lpszMenuName = NULL;
win.lpszClassName ="WINX";
win.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&win);
hwnd=CreateWindowEx(NULL,"WINX","Warcraft 3000",WS_POPUP | WS_VISIBLE,0,0,
WIDTH,HEIGHT,NULL,NULL,hinstance,NULL);
Init_Game();
ShowWindow(hwnd,SW_SHOWDEFAULT);
UpdateWindow(hwnd);
ZeroMemory(&msg,sizeof(msg));
while(msg.message!=WM_QUIT)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Game_Render();
}
Shutdown_Game();
UnregisterClass("WINX",win.hInstance);
return 0;
}
////////////////////////////////////////////////////////////
int Init_Game()
{
DirectDrawCreateEx(NULL,(void **)&d3d7,IID_IDirectDraw7,NULL);
d3d7->SetCooperativeLevel(hwnd,DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
d3d7->SetDisplayMode(WIDTH,HEIGHT,BPP,0,0);
DDRAW_INIT_STRUCT(ddsd);
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
d3d7->CreateSurface(&ddsd,&pBuffer,NULL);
Load_Image(&bitmap,"bitmap24.bmp");
return 0;
}
////////////////////////////////////////////////////////////
int Game_Render()
{
Draw_Image(WIDTH,HEIGHT);
if(KEY_DOWN(VK_ESCAPE))
{
PostMessage(hwnd,WM_DESTROY,0,0);
}
return 0;
}
////////////////////////////////////////////////////////////
int Shutdown_Game()
{
if(sBuffer!=NULL)
{
sBuffer->Release();
}
if(pBuffer!=NULL)
{
pBuffer->Release();
}
if(d3d7!=NULL)
{
d3d7->Release();
}
return 0;
}
////////////////////////////////////////////////////////////
Это загрузчик основан на структурах BMP файла которые определены в заголовочном файле
windows.h, следовательно этот загрузчик
может работать только в Виндузе.
Вопрос на засыпку: как написать собственные структуры BMP файла для того чтобы загрузчик мог работать не только в Виндовсе, но и в Линуксе тоже.
Буду рад любой помощи.
