Chris Pollett > Old Classes > PIC197 ( Print View ) Enrollment info Course Info:
Homework Assignments: Practice Exams: PIC: |
HW1 Solutions PageNote only the files from Demo 01 that were changed are posted below. //bmp.h: header file for the bmp file reader // // Added to class draw direction flag and // red offset flag // //Modified by Chris Pollett, 2001 // //Copyright Ian Parberry, 1999 //Last updated September 2, 1999 #include <windows.h> #include <windowsx.h> #include <ddraw.h> #include "defines.h" #ifndef __bmp_h__ #define __bmp_h__ class CBmpFileReader{ //bmp file input class protected: BITMAPFILEHEADER m_BMPFileHead; //bmp header BITMAPINFOHEADER m_BMPFileInfo; //bmp file information RGBQUAD m_rgbPalette[COLORS]; //the palette BYTE *m_cImage; //the image BYTE redOffset; //red offset for each palette entry BOOL direction; // TRUE -- draw right side up // FAlSE -- draw upside down public: CBmpFileReader(); //constructor ~CBmpFileReader(); //destructor BOOL load(char *filename); //load from file BOOL draw(LPDIRECTDRAWSURFACE surface); //draw image BOOL setpalette(LPDIRECTDRAWPALETTE palette); //set palette void setdirection(BOOL d); // set the draw direction // TRUE - right side up // FALSE - up side down void incRedOffset(); // increase by one the offset // to the red palette entries }; #endif //bmp.cpp: member functions for the bmp file reader // //Modified by Chris Pollett, 2001 //Copyright Ian Parberry, 1999 //Last updated May 22, 2000 #include "bmp.h" //header file //constructors and destructors CBmpFileReader::CBmpFileReader(){ //constructor m_cImage=0; //memory not yet allocated redOffset=0; direction = TRUE; } CBmpFileReader::~CBmpFileReader(){ //destructor delete[]m_cImage; //reclaim memory from image data } //member functions void CBmpFileReader::incRedOffset(){ redOffset++;} //increase by one offset to red palette //entries void CBmpFileReader::setdirection(BOOL d){direction=d; } //set draw direction BOOL CBmpFileReader::load(char *filename){ //load bmp from this file HANDLE hfile; //input file handle DWORD actualRead; //number of bytes actually read int image_size; //size of image (width*height) BOOL OK=TRUE; //no error has occurred yet //open input file for reading hfile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL); //bail if file could not be opened if(hfile==INVALID_HANDLE_VALUE)return FALSE; //read the header and info structures OK=ReadFile(hfile,&m_BMPFileHead,sizeof(m_BMPFileHead), &actualRead,NULL); if(OK)OK=ReadFile(hfile,&m_BMPFileInfo, sizeof(m_BMPFileInfo),&actualRead,NULL); //make sure the bmp is 8-bit color if(OK)OK=m_BMPFileInfo.biBitCount==COLOR_DEPTH; //get the bmp palette if(OK)OK=ReadFile(hfile,m_rgbPalette,sizeof(m_rgbPalette), &actualRead,NULL); //bail out is something went wrong if(!OK){CloseHandle(hfile); return FALSE;} //allocate memory for image data image_size=m_BMPFileInfo.biWidth*m_BMPFileInfo.biHeight; if(m_cImage)delete[]m_cImage; //dispose of any old space m_cImage=new BYTE[image_size]; //allocate new space if(!m_cImage){ //bail if alloc failed CloseHandle(hfile); return FALSE; } //round up line width to next multiple of 4 int width=(m_BMPFileInfo.biWidth+3)&~3; //read bmp image int i=0; //counter BYTE trash[4]; //to hold the trash at the end of each line int remainder=width-m_BMPFileInfo.biWidth; //width of trash while(OK&&i<m_BMPFileInfo.biHeight){ //read data OK=OK&&ReadFile(hfile, (BYTE*)(m_cImage+i*m_BMPFileInfo.biWidth), m_BMPFileInfo.biWidth,&actualRead,NULL); //read trash at end of line OK=OK&&ReadFile(hfile,trash,remainder,&actualRead,NULL); i++; //next line } if(!OK)delete[]m_cImage; //clean up if failed //close up and exit CloseHandle(hfile); return OK; } //load BOOL CBmpFileReader::draw(LPDIRECTDRAWSURFACE surface){ DDSURFACEDESC ddsd; //direct draw surface descriptor BYTE *dest,*src; //destination and source pointers int src_width; //width of source //init surface descriptor memset(&ddsd,0,sizeof(DDSURFACEDESC)); ddsd.dwSize=sizeof(ddsd); //lock down surface if(FAILED(surface->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL))) return FALSE; //calculate addresses and width dest=(BYTE*)ddsd.lpSurface; //destination if(direction) src=m_cImage+ ((m_BMPFileInfo.biHeight-1)*m_BMPFileInfo.biWidth); else src = m_cImage; //trim bmp if too wide if(m_BMPFileInfo.biWidth>ddsd.lPitch)src_width=ddsd.lPitch; else src_width=m_BMPFileInfo.biWidth; //move data to surface if(direction) { for(int i=0; i<m_BMPFileInfo.biHeight; i++){ memcpy(dest,src,src_width); dest+=ddsd.lPitch; src-=src_width; } } else { for(int i=0; i<m_BMPFileInfo.biHeight; i++){ memcpy(dest,src,src_width); dest+=ddsd.lPitch; src+=src_width; } } //clean up and return surface->Unlock(NULL); return TRUE; } //draw BOOL CBmpFileReader::setpalette(LPDIRECTDRAWPALETTE palette){ PALETTEENTRY pe[COLORS]; //intermediate palette //construct pe[] for(int i=0; i<COLORS; i++){ //for each palette entry pe[i].peRed=m_rgbPalette[i].rgbRed + redOffset; //set red pe[i].peGreen=m_rgbPalette[i].rgbGreen; //set green pe[i].peBlue=m_rgbPalette[i].rgbBlue; //set blue } //load direct draw palette to surface palette->SetEntries(NULL,0,COLORS,pe); return TRUE; } // FileName: Main.cpp // // Purpose: Simple prectice with DirectDraw. Left and right // arrows change a BitMap to be displayed. // Space changes the red offset on each palette entry // Up and down flip an image. // // // Modified from Author below by Chris Pollett //Copyright Ian Parberry, 1999 //Last updated May 22, 2000 //system includes #include <windows.h> #include <windowsx.h> #include <ddraw.h> #include <stdio.h> //system defines #define WIN32_LEAN_AND_MEAN //custom includes #include "defines.h" #include "bmp.h" //globals LPDIRECTDRAW lpDirectDrawObject=NULL; //direct draw object LPDIRECTDRAWSURFACE lpPrimary=NULL; //primary surface LPDIRECTDRAWPALETTE lpPrimaryPalette; //its palette LPDIRECTDRAWSURFACE lpSecondary=NULL; //back buffer LPDIRECTDRAWPALETTE lpSecondaryPalette; //its palette BOOL ActiveApp; //is this application active? CBmpFileReader frame[3]; BYTE curFrame = 0; //helper functions LPDIRECTDRAWPALETTE CreatePalette(LPDIRECTDRAWSURFACE surface); BOOL InitDirectDraw(HWND hwnd); HWND CreateDefaultWindow(char* name,HINSTANCE hInstance); BOOL LoadImages(){ //draw the first image to the primary surface if(!frame[0].load("up.bmp"))return FALSE; //read from file if(!frame[0].setpalette(lpPrimaryPalette)) //set palette return FALSE; if(!frame[0].draw(lpPrimary))return FALSE; //draw if(!frame[0].setpalette(lpSecondaryPalette)) //set palette return FALSE; if(!frame[0].draw(lpSecondary))return FALSE; //draw //get other images if(!frame[1].load("down.bmp"))return FALSE; //read our other two images if(!frame[2].load("up2.bmp"))return FALSE; //success exit return TRUE; } //LoadImages BOOL RestoreSurfaces(){ //restore all surfaces BOOL result=TRUE; if(SUCCEEDED(lpPrimary->Restore())) result=result&&frame[curFrame].draw(lpPrimary)&& //redraw image frame[curFrame].setpalette(lpPrimaryPalette); //set palette else return FALSE; if(SUCCEEDED(lpSecondary->Restore())) result=result&&frame[curFrame].draw(lpSecondary)&& //redraw image frame[curFrame].setpalette(lpSecondaryPalette); //set palette else return FALSE; return result; } //RestoreSurfaces BOOL PageFlip(){ //return TRUE if page flip succeeds if(lpPrimary->Flip(NULL,DDFLIP_WAIT)==DDERR_SURFACELOST) return RestoreSurfaces(); return TRUE; } //PageFlip BOOL keyboard_handler(WPARAM keystroke){ //keyboard handler BOOL result=FALSE; //return TRUE if game is to end switch(keystroke){ case VK_ESCAPE: result=TRUE; break; //exit game case VK_LEFT: //change image to previous if(curFrame) curFrame--; else curFrame=2; frame[curFrame].draw(lpSecondary); result=!PageFlip(); frame[curFrame].setpalette(lpPrimaryPalette); break; case VK_RIGHT: //change image to next if(curFrame<3) curFrame++; else curFrame=0; frame[curFrame].draw(lpSecondary); result=!PageFlip(); frame[curFrame].setpalette(lpPrimaryPalette); break; case VK_UP: //flip image upright frame[curFrame].setdirection(TRUE); frame[curFrame].draw(lpSecondary); result=!PageFlip(); break; case VK_DOWN: // flip image upside down frame[curFrame].setdirection(FALSE); frame[curFrame].draw(lpSecondary); result=!PageFlip(); break; case VK_SPACE: // change red offset frame[curFrame].incRedOffset(); frame[curFrame].setpalette(lpPrimaryPalette); break; } return result; } //keyboard_handler //message handler (window procedure) long CALLBACK WindowProc(HWND hwnd,UINT message, WPARAM wParam,LPARAM lParam){ switch(message){ case WM_ACTIVATEAPP: ActiveApp=wParam; break; case WM_CREATE: break; case WM_KEYDOWN: //keyboard hit if(keyboard_handler(wParam))DestroyWindow(hwnd); break; case WM_DESTROY: //end of game if(lpDirectDrawObject!=NULL){ //if DD object exists if(lpSecondary!=NULL) //if secondary surface exists lpSecondary->Release(); //release secondary surface if(lpPrimary!=NULL) //if primary surface exists lpPrimary->Release(); //release primary surface lpDirectDrawObject->Release(); //release DD object } ShowCursor(TRUE); //show the mouse cursor PostQuitMessage(0); //and exit break; default: //default window procedure return DefWindowProc(hwnd,message,wParam,lParam); } //switch(message) return 0L; } //WindowProc int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow){ MSG msg; //current message HWND hwnd; //handle to fullscreen window hwnd=CreateDefaultWindow("directX demo 1",hInstance); if(!hwnd)return FALSE; //set up window ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); SetFocus(hwnd); //allow input from keyboard ShowCursor(FALSE); //hide the cursor //init graphics BOOL OK=InitDirectDraw(hwnd);//initialize DirectDraw if(OK)OK=LoadImages(); //load images from disk if(!OK){ //bail out if initialization failed DestroyWindow(hwnd); return FALSE; } //message loop while(TRUE) if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){ if(!GetMessage(&msg,NULL,0,0))return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else if(!ActiveApp)WaitMessage(); } //WinMain |