   Any guides to ensuring compatiblity out there?
  Yeah, I''m making a 2D game with DirectX.  It''s coming along quite well, and runs perfectly fine on my   computer.  However, about half the people who are trying out my demo engine complain of serious bugs.  I have serious compatibility issues!One tester claimed that my in-game text, which I blit using windows GDI functions, appeared as a bunch of "randomly coloured dots".  However, all his bitmaps rendered correctly.His video card: Nvidia RIVA TNT2 N64 16MBHis OS: Windows 98 Second EditionAnother tester claimed that the application flashed red and black then froze his computer.His video card: NVIDIA RIVA TNT2 Model 64His OS: Windows MEAnother tester claimed that the application failed to load certain   bitmaps.  Some bitmaps loaded and were displayed perfectly, but others couldn''t be loaded, even though all my bitmap images are found in the same folder.So, my program has quite a bit of compatibility issues!  Perhaps someone out there has had similar problems, and can offer me some assistance, or point me in the direction of some assistance?Here''s my engine, if you''re curious.  Please excuse my abysmal ripped graphics!  I have no intention of using any ripped graphics in the final version of my game!http://www.geocities.com/bigfundy/RPGdemo.ziphttp://www.geocities.com/aplaceforevil/RPGdemo.zip 
  The source code would probably help. ;  Okay, you asked for it!Here are some functions I consider relevant.  I''m using Windows SDK, C, and Direct X.Here''s what I use to load a bitmap from file onto an offscreen surface: //BITMAPTOSURFACE()////Creates an offscreen surface holding the specified bitmapLPDIRECTDRAWSURFACE BitmapToSurface(HINSTANCE hinstance, LPDIRECTDRAW lpdd, char * filename) {//Load the bitmap from resourceHBITMAP hbm;BITMAP bm;HDC bitmapDC;HDC surfaceDC;//Load the bitmap from filehbm = (HBITMAP)LoadImage(hinstance,filename,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);if(!hbm) {DeleteDC(surfaceDC);DeleteDC(bitmapDC);return 0;}//Store the bitmap''s attributes in the BITMAP structureGetObject(hbm,sizeof(BITMAP),&bm);if(bm.bmBitsPixel != 8) {DeleteDC(surfaceDC);DeleteDC(bitmapDC);return 0;//not an 8-bit image}//Setup the surfaceLPDIRECTDRAWSURFACE lpdds;DDSURFACEDESC ddsd;ZeroMemory(&ddsd,sizeof(DDSURFACEDESC));ddsd.dwSize = sizeof(DDSURFACEDESC);ddsd.dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_CAPS;ddsd.dwHeight = bm.bmHeight;ddsd.dwWidth = ddsd.lPitch = bm.bmWidth;ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;//Create the surfaceif(lpdd->CreateSurface(&ddsd,&lpdds,NULL)!=DD_OK) {//Surface cannot be created in video memory; resort to system memoryddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;if(lpdd->CreateSurface(&ddsd,&lpdds,NULL)!=DD_OK) {DeleteDC(surfaceDC);DeleteDC(bitmapDC);return 0;}}//Get a device context for the new surfacelpdds->GetDC(&surfaceDC);//Get a device context for the bitmapif(!(bitmapDC = CreateCompatibleDC(surfaceDC))) {DeleteDC(surfaceDC);DeleteDC(bitmapDC);return 0;}if(!(SelectObject(bitmapDC,hbm))) {DeleteDC(surfaceDC);DeleteDC(bitmapDC);return 0;}//Copy from the bitmap DC to the surface DCBitBlt(surfaceDC,0,0,bm.bmWidth,bm.bmHeight,bitmapDC,0,0,SRCCOPY);//Clean uplpdds->ReleaseDC(surfaceDC);DeleteDC(surfaceDC);DeleteDC(bitmapDC);DeleteObject(hbm);//Apply the universal source color keyDDCOLORKEY ddcolkey;ZeroMemory(&ddcolkey,sizeof(DDCOLORKEY));ddcolkey.dwColorSpaceHighValue = 239;lpdds->SetColorKey(DDCKEY_SRCBLT,&ddcolkey);//Return the surfacereturn lpdds;}Here''s what I use to blit the in-game text: //WRITEMSG()////Writes a message within the passed rectangle, with line breaks and formattingvoid WriteMsg(LPDIRECTDRAWSURFACE lpddsBack,char * msg,int nchar,HFONT font,RECT textrect,COLORREF color){//Create a device context and select it with the backbufferHDC hdc;lpddsBack->GetDC(&hdc);//Select the passed font into the device contextSelectObject(hdc,font);//Set the text blitting modeSetBkMode(hdc,TRANSPARENT);SetTextColor(hdc,color);char newmsg[200] = "";for(int i=0; i<nchar; i++) {char nextchar[2] = "";sprintf(nextchar,"%c",msg[i]);strcat(newmsg,nextchar);}//Write the text, but with formatting!DrawText(hdc,newmsg,-1,&textrect,DT_LEFT|DT_WORDBREAK);//CleanuplpddsBack->ReleaseDC(hdc);DeleteDC(hdc);}Here''s my windows class and initiation stuff: ////FUNCTIONS/////////////////////////////////////////WINDOWPROC()////The Windows event handler - necessary, but not importantLRESULT CALLBACK WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){HDC hdc;switch(msg) {case WM_DESTROY:PostQuitMessage(0);return 0;break;case WM_PAINT:hdc = GetDC(hwnd);ReleaseDC(hwnd, hdc);ValidateRect(hwnd, NULL);DeleteDC(hdc);return 0;break;default:break;}DeleteDC(hdc);return DefWindowProc(hwnd,msg,wparam,lparam);}////WINMAIN/////////////////////////////////////////int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hprevinstance,LPSTR lpcmdline,int nshowcmd){HWND hwnd;//Set up a window classWNDCLASS wndclass;wndclass.lpfnWndProc = WindowProc;wndclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;wndclass.cbClsExtra = 0;wndclass.cbWndExtra = 0;wndclass.hInstance = hinstance;wndclass.hIcon = LoadIcon(hinstance,IDI_APPLICATION);wndclass.hCursor = LoadCursor(hinstance,IDC_ARROW);wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);wndclass.lpszMenuName = NULL;wndclass.lpszClassName = "MYWINCLASS";//Register the window classif(RegisterClass(&wndclass)==0) {ErrorMsg("Error registering window class",hwnd);return 0;}//Create the game windowhwnd = CreateWindow("MYWINCLASS","Game Window",WS_POPUP|WS_VISIBLE,0,0,640,480,NULL,NULL,hinstance,NULL);//Hide the cursorShowCursor(false);//Windows message handlerMSG msg;////DIRECTDRAW SETUP////////////////////////////////////////Initiate DirectDrawLPDIRECTDRAW lpdd;if(DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK) ErrorMsg("Could not initiate DirectDraw",hwnd);if(lpdd->SetCooperativeLevel(hwnd,DDSCL_ALLOWREBOOT|DDSCL_FULLSCREEN|DDSCL_EXCLUSIVE)!=DD_OK) ErrorMsg("Could not initiate DirectDraw",hwnd);if(lpdd->SetDisplayMode(640,480,8)!=DD_OK) ErrorMsg("Error setting display mode!",hwnd);//Create the primary surfaceLPDIRECTDRAWSURFACE lpddsPrimary;DDSURFACEDESC ddsd;ZeroMemory(&ddsd,sizeof(DDSURFACEDESC));ddsd.dwSize = sizeof(DDSURFACEDESC);ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;ddsd.dwBackBufferCount = 1;if(lpdd->CreateSurface(&ddsd,&lpddsPrimary,NULL)!=DD_OK) ErrorMsg("Could not create primary surface",hwnd);//Get a backbufferLPDIRECTDRAWSURFACE lpddsBack;DDSCAPS ddscaps;ddscaps.dwCaps = DDSCAPS_BACKBUFFER;lpddsPrimary->GetAttachedSurface(&ddscaps,&lpddsBack);//Create the paletteLPDIRECTDRAWPALETTE lpddpal;//Load the standard palette from a bitmap fileif(GetBitmapPalette("Images/dude.bmp",normalpal)==0) ErrorMsg("Could not access dude.bmp.  Colors will be all screwy.",hwnd);if(lpdd->CreatePalette(DDPCAPS_8BIT|DDPCAPS_INITIALIZE|DDPCAPS_ALLOW256,normalpal,&lpddpal,NULL)!=DD_OK) ErrorMsg("Could not create palette.  Colors will be all screwy.", hwnd);//Set the palette to the primary surfaceif(lpddsPrimary->SetPalette(lpddpal)!=DD_OK) ErrorMsg("Could not set palette.  Colors will be all screwy.", hwnd);//Create a color-fill blit effect structureDDBLTFX ddbltfill;ZeroMemory(&ddbltfill,sizeof(DDBLTFX));ddbltfill.dwSize = sizeof(DDBLTFX);ddbltfill.dwFillColor = 239;//Create a clipping regionRECT fullscreen = {0,0,640,480};//Setting up the clipping regionLPDIRECTDRAWCLIPPER lpddclip;if((lpddclip = SetClipRegion(lpdd,lpddsBack,&fullscreen,1))==NULL) ErrorMsg("Could not set clipping region",hwnd);//Load important bitmaps to offscreen surfacesLPDIRECTDRAWSURFACE lpddsTiles;LPDIRECTDRAWSURFACE lpddsDude;LPDIRECTDRAWSURFACE lpddsIcons;LPDIRECTDRAWSURFACE lpddsBigFoes;LPDIRECTDRAWSURFACE lpddsSmallFoes;if((lpddsDude = BitmapToSurface(hinstance,lpdd,"Images/dude.bmp"))==NULL) ErrorMsg("Could not locate Images/dude.bmp",hwnd);if((lpddsIcons = BitmapToSurface(hinstance,lpdd,"Images/icons.bmp"))==NULL) ErrorMsg("Could not locate Images/icons.bmp",hwnd);if((lpddsSmallFoes = BitmapToSurface(hinstance,lpdd,"Images/smallfoes.bmp"))==NULL) ErrorMsg("Could not locate Images/smallfoes.bmp",hwnd);if((lpddsBigFoes = BitmapToSurface(hinstance,lpdd,"Images/bigfoes.bmp"))==NULL) ErrorMsg("Could not locate Images/bigfoes.bmp",hwnd);if((lpddsTiles = BitmapToSurface(hinstance,lpdd,"Images/tiles1.bmp"))==NULL) ErrorMsg("Could not locate Images/tiles1.bmp",hwnd);////DIRECT INPUT SETUP//////////////////////////////////////Initiate Direct InputLPDIRECTINPUT lpdi;if(DirectInputCreate(hinstance,DIRECTINPUT_VERSION,&lpdi,NULL)!=DI_OK) ErrorMsg("Error creating DirectInput interface",hwnd);//Create a keyboard deviceLPDIRECTINPUTDEVICE lpKeyboard;if(lpdi->CreateDevice(GUID_SysKeyboard,&lpKeyboard,NULL)!=DI_OK) ErrorMsg("Error creating keyboard device!",hwnd);//Set the cooperative level for the devicelpKeyboard->SetCooperativeLevel(hwnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE);//Set the data format to a predefined DIDATAFORMAT structurelpKeyboard->SetDataFormat(&c_dfDIKeyboard);if(lpKeyboard->Acquire()!=DI_OK) ErrorMsg("Error aquiring keyboard device!",hwnd);//Create a joystick deviceLPDIRECTINPUTDEVICE2 lpJoyStick2;//for loopfor(int i=0; i<1; i++) {//Enumerate to find the first joystick - return it''s GUIDGUID joyGUID;if(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK,EnumJoyStick,&joyGUID,DIEDFL_ATTACHEDONLY)!=DI_OK) break;//Create a joystick deviceLPDIRECTINPUTDEVICE lpJoyStick;if(lpdi->CreateDevice(joyGUID,&lpJoyStick,NULL)!=DI_OK) break;//Request a DIRECTINPUTDEVICE2 interfacelpJoyStick->QueryInterface(IID_IDirectInputDevice2,(void **) &lpJoyStick2);//Release the old joystick devicelpJoyStick->Release();//Set the cooperative level for the devicelpJoyStick2->SetCooperativeLevel(hwnd,DISCL_NONEXCLUSIVE|DISCL_BACKGROUND);//Set the data format to the pre-defined Joystick formatif(lpJoyStick2->SetDataFormat(&c_dfDIJoystick)!=DI_OK) {ErrorMsg("Error setting joystick data format!",hwnd);lpJoyStick2->Release();break;}//GamePad properties structureDIPROPRANGE joystickprop;//Set axis to range from -128 to 128joystickprop.lMin = -128;joystickprop.lMax = 128;joystickprop.diph.dwSize = sizeof(DIPROPRANGE);joystickprop.diph.dwHeaderSize = sizeof(DIPROPHEADER);joystickprop.diph.dwObj = DIJOFS_X;//we''re changing the x-axis properties herejoystickprop.diph.dwHow = DIPH_BYOFFSET;//Now set the propertylpJoyStick2->SetProperty(DIPROP_RANGE,&joystickprop.diph);//Now do the same for the y-axisjoystickprop.lMin = -128;joystickprop.lMax = 128;joystickprop.diph.dwSize = sizeof(DIPROPRANGE);joystickprop.diph.dwHeaderSize = sizeof(DIPROPHEADER);joystickprop.diph.dwObj = DIJOFS_Y;//we''re changing the y-axis properties herejoystickprop.diph.dwHow = DIPH_BYOFFSET;//Now set the propertylpJoyStick2->SetProperty(DIPROP_RANGE,&joystickprop.diph);//Finally, acquire the gamepadif(lpJoyStick2->Acquire()!=DI_OK) {lpJoyStick2->Release();ErrorMsg("Error acquiring joystick device",hwnd);break;}//If all has gone well, we can set the joystick global variable to truejoystick = true;}//Set all input booleans to falsefor(i=0; i<256; i++) {keydown[i] = false;if(i<32) buttondown[i] = false; };  I could really   use some help with this!In my file i/o code, I use fopen, fwrite, fgets, and fclose.  Are these functions out of date?  Please, I''m lost when it comes to compatibility issues. 