Här är källkoden...
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdio.h>
#include <math.h>
#include <ddraw.h>
#include <io.h>
#define WINDOW_CLASS_NAME "WINCLASS1"
#define WINDOW_CLASS_NAME "WINCLASS1"
#define msHEIGHT 480
#define msWIDTH 640
#define msBPP 8
#define msTITLE "MY GAME"
#define BITMAPID 0x4D42
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// container structure för .bmp filer
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader; //bitmap file header
BITMAPINFOHEADER bitmapinfoheader; //info (bla paletten)
PALETTEENTRY palette[256]; //här sparars paletten
UCHAR *buffer; //pekare till data
} BITMAP_FILE, *BITMAP_FILE_PTR;
//win/directx variabler
HWND main_window_handle = NULL;
LPDIRECTDRAW lpdd;
LPDIRECTDRAWSURFACE lpddsprimary;
LPDIRECTDRAWSURFACE lpwork;
LPDIRECTDRAWPALETTE lpddpal;
DDSURFACEDESC ddsd;
HRESULT hr;
PALETTEENTRY palette[256];
UCHAR *double_buffer = NULL, *primary_buffer = NULL;
BITMAP_FILE Bitmap8;
int dxInit(void *params = NULL);
int dxShutdown(void *params = NULL);
int dxMain(void *params = NULL);
int dxBild(int x, int y, char* filename, BITMAP_FILE_PTR bitmap);
int dxUnBild(BITMAP_FILE_PTR BildFil);
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg) //en switch för olika msg
{
case WM_CREATE: //när fönstret skapas
return 0;
break;
case WM_PAINT: //när fönstret ska ritas om
hdc = BeginPaint(hwnd, &ps); //startar omritning
EndPaint(hwnd, &ps); //slutar omritning
return 0;
break;
case WM_DESTROY: //när fönstret ska stängas
PostQuitMessage(0); //skickar stängnings meddelande
return 0;
break;
default: break; //default, gör inget
} //switch(msg) end
return (DefWindowProc(hwnd, msg, wparam, lparam));
} //WindowProc end
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcdmline, int ncmdshow)
{
WNDCLASS winclass;
HWND hwnd;
MSG msg;
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
if (!RegisterClass(&winclass))
return 0;
if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, msTITLE, WS_POPUP | WS_VISIBLE, 0, 0, msWIDTH, msHEIGHT, NULL, NULL, hinstance, NULL)))
return(0);
main_window_handle = hwnd;
dxInit();
while(1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
dxMain();
}
dxShutdown();
return (msg.wParam);
} //WinMain end
int dxMain(void *params = NULL)
{
if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE)) //om man trycker ner Esc eller space
PostMessage(main_window_handle, WM_DESTROY, 0, 0); //posta ett avslutningsmeddelande
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
memset(double_buffer, 0, msHEIGHT * msWIDTH); //fixa minnet
lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
primary_buffer = (UCHAR *)ddsd.lpSurface;
primary_buffer = (UCHAR *)ddsd.lpSurface;
/* for (int y=0; y < msHEIGHT; y++)
{
memcpy(&primary_buffer[y * ddsd.lPitch], &Bitmap8.buffer[y * msWIDTH], msWIDTH);
} */
//dxBild(0, 0, "test.bmp", &Bitmap8);
lpddpal -> SetEntries(0, 0, 256, Bitmap8.palette); //ladda paletten till ddraw
lpddsprimary -> Unlock(primary_buffer);
Sleep(3); //vila lite
return 1;
} //DxMain end
int dxShutdown(void *params = NULL)
{
if (lpdd)
lpdd -> Release(); //frigör lpdd
if (lpddsprimary)
lpddsprimary -> Release(); //frigör lpddsprimary
if (lpwork)
lpwork -> Release(); //frigör lpwork
if (lpddpal)
lpddpal -> Release(); //frigör lpddpal
if (double_buffer)
free(double_buffer); //frigör double_buffer
dxUnBild(&Bitmap8);
return 1;
} //dxShutdown end
int dxInit(void *params = NULL)
{
if (DirectDrawCreate(NULL, &lpdd, NULL) != DD_OK) //skapa ddraw objekt
return 0;
//ställ in samverkansnivån
if (lpdd -> SetCooperativeLevel(main_window_handle, DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) != DD_OK)
return 0;
if ((lpdd -> SetDisplayMode(msWIDTH, msHEIGHT, msBPP)) != DD_OK) //ställ in skärmen (640x480x8)
return 0;
memset(&ddsd, 0, sizeof(ddsd)); //fixa minne
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (lpdd -> CreateSurface(&ddsd, &lpddsprimary, NULL) != DD_OK) //skapa en yta
return 0;
/* memset(&ddsd, 0, sizeof(ddsd)); //fixa minne
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.dwHeight = msHEIGHT;
ddsd.dwWidth = msWIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
if (lpdd -> CreateSurface(&ddsd, &lpwork, NULL) != DD_OK) //skapa en sekundär yta
return 0; */
memset(palette,0,256*sizeof(PALETTEENTRY));
for (int index=0; index<256; index++)
{
palette[index].peFlags = PC_NOCOLLAPSE;
}
if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,palette,&lpddpal,NULL)!=DD_OK)
return(0);
if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
return(0);
double_buffer = (UCHAR *)malloc(msHEIGHT * msWIDTH);
dxBild(0, 0, "test.bmp", &Bitmap8);
return 1;
} //dxInit end
int dxBild(int x, int y, char* FileName, BITMAP_FILE_PTR BildFil)
{
int FileCheck;
OFSTRUCT FilData; //fil data informationen
if (!(FileCheck = OpenFile(FileName, &FilData, OF_READ)))
return(0); //Om inte filen finns, return 0
_lread(FileCheck, &BildFil -> bitmapfileheader, sizeof(BITMAPFILEHEADER)); //laddar bitmapheadern
if (BildFil -> bitmapfileheader.bfType != BITMAPID) //om det inte är en bitmap
{
_lclose(FileCheck); //stäng filen
return(0);
}
if (BildFil -> bitmapinfoheader.biBitCount == 8) //om palet info finns
{
_lread(FileCheck, &BildFil -> palette, 256 * sizeof(PALETTEENTRY));
for (int i = 0; i < 256; i++)
{
//vänder på de gröna och röda fälten
int TempColor = BildFil -> palette[i].peRed;
BildFil -> palette[i].peBlue = TempColor;
BildFil -> palette[i].peFlags = PC_NOCOLLAPSE;
}
}
_lseek(FileCheck, -(int)(BildFil -> bitmapinfoheader.biSizeImage), SEEK_END); //laddar bild datan
if (!(BildFil -> buffer = (UCHAR *)malloc(BildFil -> bitmapinfoheader.biSizeImage))) //allokera minnet för bilden
{
_lclose(FileCheck); //stäng filen
return(0);
}
_lread(FileCheck, BildFil -> buffer, BildFil -> bitmapinfoheader.biSizeImage); //läs in filen
_lclose(FileCheck); //stäng filen
return(1); //allt lyckades
} //dxBild end
int dxUnBild(BITMAP_FILE_PTR BildFil)
{
if (BildFil -> buffer)
{
free(BildFil -> buffer); //frigör minnet
BildFil -> buffer = NULL; //reset pekaren
}
return 1;
} //dxUnBil end