int Game_Init(void *parms = NULL, int num_parms = 0) { // this is called once after the initial window is created and // before the main event loop is entered, do all your initialization // here // seed random number generator srand(GetTickCount()); // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screen if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return(0); // set display mode to 640x480x8 if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0))) return(0); // clear ddsd and set size DDRAW_INIT_STRUCT(ddsd); // enable valid fields ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // set the backbuffer count field to 1, use 2 for triple buffering ddsd.dwBackBufferCount = 1; // request a complex, flippable ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0); // now query for attached surface from the primary surface // this line is needed by the call ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; // get the attached back buffer surface if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) return(0); // build up the palette data array for (int color=1; color < 255; color++) { // fill with random RGB values palette[color].peRed = rand()%256; palette[color].peGreen = rand()%256; palette[color].peBlue = rand()%256; // set flags field to PC_NOCOLLAPSE palette[color].peFlags = PC_NOCOLLAPSE; } // end for color // now fill in entry 0 and 255 with black and white palette[0].peRed = 0; palette[0].peGreen = 0; palette[0].peBlue = 0; palette[0].peFlags = PC_NOCOLLAPSE; palette[255].peRed = 255; palette[255].peGreen = 255; palette[255].peBlue = 255; palette[255].peFlags = PC_NOCOLLAPSE; // create the palette object if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette,&lpddpal, NULL))) return(0); // finally attach the palette to the primary surface if (FAILED(lpddsprimary->SetPalette(lpddpal))) return(0); // clear the surfaces out DDraw_Fill_Surface(lpddsprimary, 0 ); DDraw_Fill_Surface(lpddsback, 0 ); // define points of asteroid VERTEX2DF asteroid_vertices[8] = {33,-3, 9,-18, -12,-9, -21,-12, -9,6, -15,15, -3,27, 21,21}; // loop and initialize all asteroids for (int curr_index = 0; curr_index < NUM_ASTEROIDS; curr_index++) { // initialize the asteroid asteroids[curr_index].state = 1; // turn it on asteroids[curr_index].num_verts = 8; asteroids[curr_index].x0 = rand()%SCREEN_WIDTH; // position it asteroids[curr_index].y0 = rand()%SCREEN_HEIGHT; asteroids[curr_index].xv = -8 + rand()%17; asteroids[curr_index].yv = -8 + rand()%17; asteroids[curr_index].color = rand()%256; asteroids[curr_index].vlist = new VERTEX2DF [asteroids[curr_index].num_verts]; for (int index = 0; index < asteroids[curr_index].num_verts; index++) asteroids[curr_index].vlist[index] = asteroid_vertices[index]; } // end for curr_index // create sin/cos lookup table // generate the tables for (int ang = 0; ang < 360; ang++) { // convert ang to radians float theta = (float)ang*PI/(float)180; // insert next entry into table cos_look[ang] = cos(theta); sin_look[ang] = sin(theta); } // end for ang // return success or failure or your own return code here return(1); } // end Game_Init
int Game_Init(void *parms = NULL, int num_parms = 0) { // this is called once after the initial window is created and // before the main event loop is entered, do all your initialization // here // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screen if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return(0); // set display mode to 640x480x8 if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0))) return(0); // clear ddsd and set size DDRAW_INIT_STRUCT(ddsd); // enable valid fields ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // set the backbuffer count field to 1, use 2 for triple buffering ddsd.dwBackBufferCount = 1; // request a complex, flippable ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0); // now query for attached surface from the primary surface // this line is needed by the call ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; // get the attached back buffer surface if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) return(0); // build up the palette data array for (int color=1; color < 255; color++) { // fill with random RGB values palette[color].peRed = 0; palette[color].peGreen = 0; palette[color].peBlue = color; // set flags field to PC_NOCOLLAPSE palette[color].peFlags = PC_NOCOLLAPSE; } // end for color // now fill in entry 0 and 255 with black and white palette[0].peRed = 0; palette[0].peGreen = 0; palette[0].peBlue = 0; palette[0].peFlags = PC_NOCOLLAPSE; palette[255].peRed = 255; palette[255].peGreen = 255; palette[255].peBlue = 255; palette[255].peFlags = PC_NOCOLLAPSE; // create the palette object if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette,&lpddpal, NULL))) { return(0); } // finally attach the palette to the primary surface if (FAILED(lpddsprimary->SetPalette(lpddpal))) return(0); // return success or failure or your own return code here return(1); } // end Game_Init
int Game_Main(void *parms = NULL, int num_parms = 0) { // this is the main loop of the game, do all your processing // here // make sure this isn't executed again if (window_closed) return(0); // for now test if user is hitting ESC and send WM_CLOSE if (KEYDOWN(VK_ESCAPE)) { PostMessage(main_window_handle,WM_CLOSE,0,0); window_closed = 1; } // end if // clear out the back buffer DDraw_Fill_Surface(lpddsback, 0); // lock primary buffer DDRAW_INIT_STRUCT(ddsd); if (FAILED(lpddsback->Lock(NULL,&ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL))) return(0); // draw all the asteroids for (int curr_index = 0; curr_index < NUM_ASTEROIDS; curr_index++) { // do the graphics Draw_Polygon2D(&asteroids[curr_index], (UCHAR *)ddsd.lpSurface, ddsd.lPitch); // move the asteroid Translate_Polygon2D(&asteroids[curr_index], asteroids[curr_index].xv, asteroids[curr_index].yv); // rotate the polygon by 5 degrees Rotate_Polygon2D(&asteroids[curr_index], 5); // test for out of bounds if (asteroids[curr_index].x0 > SCREEN_WIDTH+100) asteroids[curr_index].x0 = - 100; if (asteroids[curr_index].y0 > SCREEN_HEIGHT+100) asteroids[curr_index].y0 = - 100; if (asteroids[curr_index].x0 < -100) asteroids[curr_index].x0 = SCREEN_WIDTH+100; if (asteroids[curr_index].y0 < -100) asteroids[curr_index].y0 = SCREEN_HEIGHT+100; } // end for curr_asteroid // unlock primary buffer if (FAILED(lpddsback->Unlock(NULL))) return(0); // perform the flip while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT))); // wait a sec Sleep(33); // return success or failure or your own return code here return(1); } // end Game_Main
LPDIRECTDRAWSURFACE CreateSurfByGafSequence (LPDIRECTDRAW LpDD, PGAFSequence Cursor_P, bool VidMem) { IDDrawSurface::OutptTxt ( "CreateSurfByGafSequence"); if (NULL==Cursor_P) { return NULL; } LPDIRECTDRAWSURFACE RetSurf= NULL; LPBYTE GafBits; POINT GafSize={0, 0}; int Width= 0; int Height= 0; Width= Cursor_P->PtrFrameAry[0].PtrFrame->Width; Height= Cursor_P->PtrFrameAry[0].PtrFrame->Height; for (int i= 0; i<Cursor_P->Frames; ++i) { GafSize.x= Cursor_P->PtrFrameAry[i].PtrFrame->Width; GafSize.y= Cursor_P->PtrFrameAry[i].PtrFrame->Height; if (Width<GafSize.x) { Width= GafSize.x; } if (Height<GafSize.y) { Height= GafSize.y; } } GafBits= (LPBYTE)malloc ( Width* Height); GafSize.x= Width; GafSize.y= Height; CopyGafSequenceToBits ( GafBits, &GafSize, Cursor_P, 0); DDSURFACEDESC ddsd; DDRAW_INIT_STRUCT(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; if(VidMem) ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; else ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = Width; ddsd.dwHeight = Height; LpDD->CreateSurface ( &ddsd, &RetSurf, NULL); DDRAW_INIT_STRUCT(ddsd); RetSurf->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); unsigned char *SurfPTR = (unsigned char*)ddsd.lpSurface; if (NULL!=SurfPTR) { for(int i=0; i<GafSize.y; i++) { memcpy(&SurfPTR[i*ddsd.lPitch], &GafBits[i* Width], Width); } } free ( GafBits); RetSurf->Unlock(NULL); return RetSurf; }
int Game_Main(void *parms = NULL, int num_parms = 0) { // this is the main loop of the game, do all your processing // here // not doing this will cause occasional errors // make sure this isn't executed again if (window_closed) return(0); // for now test if user is hitting ESC and send WM_CLOSE if (KEYDOWN(VK_ESCAPE)) { PostMessage(main_window_handle,WM_CLOSE,0,0); window_closed = 1; } // end if // lock the back buffer DDRAW_INIT_STRUCT(ddsd); lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // alias pointer to back buffer surface UCHAR *back_buffer = (UCHAR *)ddsd.lpSurface; // now clear the back buffer out // linear memory? if (ddsd.lPitch == SCREEN_WIDTH) { memset(back_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT); } else { // non-linear memory // make copy of video pointer UCHAR *dest_ptr = back_buffer; // clear out memory one line at a time for (int y=0; y<SCREEN_HEIGHT; y++) { // clear next line memset(dest_ptr,0,SCREEN_WIDTH); // advance pointer to next line dest_ptr+=ddsd.lPitch; } // end for y } // end else // you would perform game logic... // draw the next frame into the back buffer, notice that we // must use the lpitch since it's a surface and may not be linear // plot 5000 random pixels for (int index=0; index < 5000; index++) { int x = rand()%SCREEN_WIDTH; int y = rand()%SCREEN_HEIGHT; UCHAR col = rand()%256; back_buffer[x+y*ddsd.lPitch] = col; } // end for index // unlock the back buffer if (FAILED(lpddsback->Unlock(NULL))) return(0); // perform the flip while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT))); // return success or failure or your own return code here return(1); } // end Game_Main
int Game_Init(void *parms = NULL, int num_parms = 0) { // this is called once after the initial window is created and // before the main event loop is entered, do all your initialization // here // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screen if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return(0); // set display mode to 640x480x8 if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0))) return(0); // we need a complex surface system with a primary and backbuffer // clear ddsd and set size DDRAW_INIT_STRUCT(ddsd); // enable valid fields ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // set the backbuffer count field to 1, use 2 for triple buffering ddsd.dwBackBufferCount = 1; // request a complex, flippable ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0); // now query for attached surface from the primary surface // this line is needed by the call ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; // get the attached back buffer surface if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) return(0); // build up the palette data array for (int color=1; color < 255; color++) { // fill with random RGB values palette[color].peRed = rand()%256; palette[color].peGreen = rand()%256; palette[color].peBlue = rand()%256; // set flags field to PC_NOCOLLAPSE palette[color].peFlags = PC_NOCOLLAPSE; } // end for color // now fill in entry 0 and 255 with black and white palette[0].peRed = 0; palette[0].peGreen = 0; palette[0].peBlue = 0; palette[0].peFlags = PC_NOCOLLAPSE; palette[255].peRed = 255; palette[255].peGreen = 255; palette[255].peBlue = 255; palette[255].peFlags = PC_NOCOLLAPSE; // create the palette object if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette,&lpddpal, NULL))) return(0); // finally attach the palette to the primary surface if (FAILED(lpddsprimary->SetPalette(lpddpal))) return(0); // set clipper up on back buffer since that's where well clip RECT screen_rect= {0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1}; lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect); // load the 8-bit image if (!Load_Bitmap_File(&bitmap,"alley8.bmp")) return(0); // load it's palette into directdraw if (FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette))) return(0); // clean the surfaces DDraw_Fill_Surface(lpddsprimary,0); DDraw_Fill_Surface(lpddsback,0); // create the buffer to hold the background lpddsbackground = DDraw_Create_Surface(640,480,0,-1); // copy the background bitmap image to the background surface // lock the surface lpddsbackground->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // get video pointer to primary surfce UCHAR *image_buffer = (UCHAR *)ddsd.lpSurface; // test if memory is linear if (ddsd.lPitch == SCREEN_WIDTH) { // copy memory from double buffer to primary buffer memcpy((void *)image_buffer, (void *)bitmap.buffer, SCREEN_WIDTH*SCREEN_HEIGHT); } // end if else { // non-linear // make copy of source and destination addresses UCHAR *dest_ptr = image_buffer; UCHAR *src_ptr = bitmap.buffer; // memory is non-linear, copy line by line for (int y=0; y < SCREEN_HEIGHT; y++) { // copy line memcpy((void *)dest_ptr, (void *)src_ptr, SCREEN_WIDTH); // advance pointers to next line dest_ptr+=ddsd.lPitch; src_ptr +=SCREEN_WIDTH; } // end for } // end else // now unlock the primary surface if (FAILED(lpddsbackground->Unlock(NULL))) return(0); // unload the bitmap file, we no longer need it Unload_Bitmap_File(&bitmap); // seed random number generator srand(GetTickCount()); // initialize all the aliens (in real life do this in a loop or function) // alien on level 1 of complex aliens[0].x = rand()%SCREEN_WIDTH; aliens[0].y = 116 - 72; aliens[0].velocity = 2+rand()%4; aliens[0].current_frame = 0; aliens[0].counter = 0; aliens[0].width = 72; // set real size aliens[0].height = 80; aliens[0].scale = ((float)(1+rand()%20))/10; // scale from 0.1 to 2.0 // fix up feet so they still contact floor aliens[0].y+=(72 - aliens[0].scale*72); // alien on level 2 of complex aliens[1].x = rand()%SCREEN_WIDTH; aliens[1].y = 246 - 72; aliens[1].velocity = 2+rand()%4; aliens[1].current_frame = 0; aliens[1].counter = 0; aliens[1].width = 72; // set real size aliens[1].height = 80; aliens[1].scale = ((float)(1+rand()%20))/10; // scale from 0.1 to 2.0 // fix up feet so they still contact floor aliens[1].y+=(72 - aliens[1].scale*72); // alien on level 3 of complex aliens[2].x = rand()%SCREEN_WIDTH; aliens[2].y = 382 - 72; aliens[2].velocity = 2+rand()%4; aliens[2].current_frame = 0; aliens[2].counter = 0; aliens[2].width = 72; // set real size aliens[2].height = 80; aliens[2].scale = ((float)(1+rand()%20))/10; // scale from 0.1 to 2.0 // fix up feet so they still contact floor aliens[2].y+=(72 - aliens[2].scale*72); // now load the bitmap containing the alien imagery // then scan the images out into the surfaces of alien[0] // and copy then into the other two, be careful of reference counts! // load the 8-bit image if (!Load_Bitmap_File(&bitmap,"dedsp0.bmp")) return(0); // create each surface and load bits for (int index = 0; index < 3; index++) { // create surface to hold image aliens[0].frames[index] = DDraw_Create_Surface(72,80,0); // now load bits... Scan_Image_Bitmap(&bitmap, // bitmap file to scan image data from aliens[0].frames[index], // surface to hold data index, 0); // cell to scan image from } // end for index // unload the bitmap file, we no longer need it Unload_Bitmap_File(&bitmap); // now for the tricky part. There is no need to create more surfaces with the same // data, so I'm going to copy the surface pointers member for member to each alien // however, be careful, since the reference counts do NOT go up, you still only need // to release() each surface once! for (index = 0; index < 3; index++) aliens[1].frames[index] = aliens[2].frames[index] = aliens[0].frames[index]; // return success or failure or your own return code here return(1); } // end Game_Init
BOOL GameInitialize() { OutputDebugString(L"GameInitialize\n"); if(FAILED(DirectDrawCreateEx(NULL, (LPVOID*)&lpdd, IID_IDirectDraw7, NULL))) { return FALSE; } if(FAILED(lpdd->SetCooperativeLevel(g_hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) { return FALSE; } if(FAILED(lpdd->SetDisplayMode(WND_WIDTH, WND_HEIGHT, SCREEN_BPP, 0, 0))) { return FALSE; } DDRAW_INIT_STRUCT(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsPrimary, NULL))) { return FALSE; } ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if(FAILED(lpddsPrimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsBack))) { return FALSE; } DDRAW_INIT_STRUCT(ddsd); if(FAILED(lpddsBack->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL))) { OutputDebugString(L"Lock\n"); return FALSE; } UINT* backBuffer = (UINT*)ddsd.lpSurface; INT lPitch = ddsd.lPitch >> 2; for (int y = 0; y < WND_HEIGHT; ++y) { UINT color = RGB32BIT(0, 0, (UCHAR)((FLOAT)y / (FLOAT)WND_HEIGHT * 256.0), 0); for (int x = 0; x < WND_WIDTH; ++x) { backBuffer[x + y * lPitch] = color; } } if(FAILED(lpddsBack->Unlock(NULL))) { OutputDebugString(L"Unlock\n"); return FALSE; } return TRUE; }
static HRESULT CreateWindowedDisplay(HWND hWnd, DWORD dwWidth, DWORD dwHeight) { // Set cooperative level if (FAILED(lpdd->SetCooperativeLevel(hWnd, DDSCL_NORMAL))) { return E_FAIL; } RECT rcWork; RECT rc; DWORD dwStyle; // If we are still a WS_POPUP window // We should convert to a normal app window so we look like a windows app. dwStyle = GetWindowLong(hWnd, GWL_STYLE); dwStyle &= ~WS_POPUP; dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; SetWindowLong(hWnd, GWL_STYLE, dwStyle); // Adapt window size SetRect(&rc, 0, 0, dwWidth, dwHeight); AdjustWindowRectEx(&rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL, GetWindowExStyle(hWnd)); SetWindowPos(hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); // Make sure our window does not hang outside of the work area SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0); GetWindowRect(hWnd, &rc); if (rc.left < rcWork.left) rc.left = rcWork.left; if (rc.top < rcWork.top) rc.top = rcWork.top; SetWindowPos(hWnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); // Create the primary surface DDSURFACEDESC2 ddsd; DDRAW_INIT_STRUCT(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsMain, NULL))) { return E_FAIL; } // Create the backbuffer surface ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; ddsd.dwWidth = dwWidth; ddsd.dwHeight = dwHeight; if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsBack, NULL))) { return E_FAIL; } // Set surface color key DDCOLORKEY ddCK; ddCK.dwColorSpaceLowValue = 0; ddCK.dwColorSpaceHighValue = 0; if (lpddsBack->SetColorKey(DDCKEY_SRCBLT, &ddCK)) { return E_FAIL; } // Create clipper for the primary surface LPDIRECTDRAWCLIPPER lpClipper; if (FAILED(lpdd->CreateClipper(0, &lpClipper, NULL))) { return E_FAIL; } if (FAILED(lpClipper->SetHWnd(0, hWnd))) { lpClipper->Release(); return E_FAIL; } if (FAILED(lpddsMain->SetClipper(lpClipper))) { lpClipper->Release(); return E_FAIL; } lpClipper->Release(); lpClipper = NULL; // Update window flag SetClassLong(hWnd, GCL_HICONSM, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICONSM))); SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LONG)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICONSM))); UpdateWindow(hWnd); return S_OK; }
int Game_Main(void *parms = NULL, int num_parms = 0) { // this is the main loop of the game, do all your processing // here DDBLTFX ddbltfx; // the blitter fx structure static int feeling_counter = 0; // tracks how we feel :) static int happy = 1; // let's start off being happy // make sure this isn't executed again if (window_closed) return(0); // for now test if user is hitting ESC and send WM_CLOSE if (KEYDOWN(VK_ESCAPE)) { PostMessage(main_window_handle,WM_CLOSE,0,0); window_closed = 1; } // end if // use the blitter to erase the back buffer // first initialize the DDBLTFX structure DDRAW_INIT_STRUCT(ddbltfx); // now set the color word info to the color we desire ddbltfx.dwFillColor = 0; // make the blitter call if (FAILED(lpddsback->Blt(NULL, // pointer to dest RECT, NULL for whole thing NULL, // pointer to source surface NULL, // pointer to source RECT DDBLT_COLORFILL | DDBLT_WAIT, // do a color fill and wait if you have to &ddbltfx))) // pointer to DDBLTFX holding info return(0); // initialize ddsd DDRAW_INIT_STRUCT(ddsd); // lock the back buffer surface if (FAILED(lpddsback->Lock(NULL,&ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL))) return(0); // increment how we feel if (++feeling_counter > 200) { feeling_counter = 0; happy = -happy; } // end if // draw all the happy faces for (int face=0; face < 100; face++) { // are we happy or sad? if (happy==1) // we are happy :) Blit_Clipped(happy_faces[face].x, happy_faces[face].y, 8,8, happy_bitmap, (UCHAR *)ddsd.lpSurface, ddsd.lPitch); else // we must be sad :( Blit_Clipped(happy_faces[face].x, happy_faces[face].y, 8,8, sad_bitmap, (UCHAR *)ddsd.lpSurface, ddsd.lPitch); } // end face // move all happy faces for (face=0; face < 100; face++) { // move happy_faces[face].x+=happy_faces[face].xv; happy_faces[face].y+=happy_faces[face].yv; // check for off screen, if so wrap if (happy_faces[face].x > SCREEN_WIDTH) happy_faces[face].x = -8; else if (happy_faces[face].x < -8) happy_faces[face].x = SCREEN_WIDTH; if (happy_faces[face].y > SCREEN_HEIGHT) happy_faces[face].y = -8; else if (happy_faces[face].y < -8) happy_faces[face].y = SCREEN_HEIGHT; } // end face // unlock surface if (FAILED(lpddsback->Unlock(NULL))) return(0); // flip the pages while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT))); // wait a sec Sleep(30); // return success or failure or your own return code here return(1); } // end Game_Main
static HRESULT CreateFullScreenDisplay(HWND hWnd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) { RECT rc; DWORD dwStyle; // Set app window's style to WS_POPUP so that it can fit for full screen mode. dwStyle = GetWindowLong(hWnd, GWL_STYLE); dwStyle &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); dwStyle |= WS_POPUP; SetWindowLong(hWnd, GWL_STYLE, dwStyle); // Adapt window size SetRect(&rc, 0, 0, dwWidth, dwHeight); AdjustWindowRectEx(&rc, GetWindowStyle(hWnd), GetMenu(hWnd) != NULL, GetWindowExStyle(hWnd)); // Set cooperative level if (FAILED(lpdd->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT))) { return E_FAIL; } // Set the display mode if (FAILED(lpdd->SetDisplayMode(dwWidth, dwHeight, dwBPP, 0, 0))) { return E_FAIL; } // Create primary surface (with backbuffer attached) DDSURFACEDESC2 ddsd; DDRAW_INIT_STRUCT(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT | DDSD_CKSRCBLT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE; ddsd.dwBackBufferCount = 1; if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsMain, NULL))) { return E_FAIL; } // Get a pointer to the back buffer DDSCAPS2 ddscaps; ZeroMemory(&ddscaps, sizeof(ddscaps)); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; if (FAILED(lpddsMain->GetAttachedSurface(&ddscaps, &lpddsBack))) { return E_FAIL; } //lpddsBack->AddRef(); // Set surface color key DDCOLORKEY ddCK; ddCK.dwColorSpaceLowValue = 0; ddCK.dwColorSpaceHighValue = 0; if (lpddsBack->SetColorKey(DDCKEY_SRCBLT, &ddCK)) { return E_FAIL; } // Update window flag SetClassLong(hWnd, GCL_HICONSM, NULL); SendMessage(hWnd, WM_SETICON, ICON_SMALL, NULL); UpdateWindow(hWnd); return S_OK; }
int Game_Init(void *parms = NULL, int num_parms = 0) { // this is called once after the initial window is created and // before the main event loop is entered, do all your initialization // here // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screen if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return(0); // set display mode to 640x480x24 if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0))) return(0); // clear ddsd and set size DDRAW_INIT_STRUCT(ddsd); // enable valid fields ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; // // request primary surface ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0); ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) return 0; // 把主屏和缓冲屏都填充为黑色初始化 DDraw_Fill_Surface(lpddsprimary, _RGB32BIT(0, 0,0,0)); DDraw_Fill_Surface(lpddsback, _RGB32BIT(0, 0,0,0)); // load the 24-bit image char* bmp_wc = "WarCraft24.bmp"; char* bmp_b8 = "bitmap8b.bmp"; char* bmp_b24 = "bitmap24.bmp"; char* bmp_b24e = "bitmap24_edit.bmp"; char* bmp_mo24 = "mosaic-600x.bmp"; char* bmp_ni24 = "nightelf-640x.bmp"; char* bmp_alley24 = "alley8_24bit.bmp"; // 载入背景图片 if (!Load_Bitmap_File(&bitmap, bmp_ni24)) return(0); // 创建背景表面、但实际上不是直接用背景表面来显示的、而是拷贝去缓冲表面和人物动作混合 // 后才一次性打到显示表面 // 这里头两个参数是指在屏幕的高和宽、第二个是指表面建立的地点、0指在显存建立、其它表示在 // 系统内存建立、当然速度自然是在显存建立快了、最后一个参数是是否设置为色彩键、这里设定为-1 // 也就是不设定任何色彩过滤、因为这个是背景表面、所以不需要任何透明的色彩键 lpddsbackground = DDraw_Create_Surface(640,480,0,-1); // 把bmp的内容拷贝至缓冲表面中 Bmp2Surface(lpddsbackground, SCREEN_WIDTH, SCREEN_HEIGHT); // 从现在开始创建人物动作了 if (!Load_Bitmap_File(&bitmap, "Dedsp0_24bit.bmp")) return(0); // seed random number generator // GetTickCount是一个系统启动至今的毫秒数、 // 配合srandg来产生一个随机数 srand(GetTickCount()); // initialize all the aliens // alien on level 1 of complex // //系统在调用rand()之前都会自动调用srand(),如果用户在rand()之前曾调用过srand()给参数seed指定了一个值, //那么rand()就会将seed的值作为产生伪随机数的初始值; //而如果用户在rand()前没有调用过srand(),那么rand()就会自动调用srand(1),即系统默认将1作为伪随机数的初始值。 //所以前面要调用一次srand来确保以下调用rand()的值会产生不同 // aliens[0].x = rand()%SCREEN_WIDTH; aliens[0].y = 116 - 72; aliens[0].velocity = 2+rand()%4; aliens[0].current_frame = 0; aliens[0].counter = 0; // alien on level 2 of complex aliens[1].x = rand()%SCREEN_WIDTH; aliens[1].y = 246 - 72; aliens[1].velocity = 2+rand()%4; aliens[1].current_frame = 0; aliens[1].counter = 0; // alien on level 3 of complex aliens[2].x = rand()%SCREEN_WIDTH; aliens[2].y = 382 - 72; aliens[2].velocity = 2+rand()%4; aliens[2].current_frame = 0; aliens[2].counter = 0; // now load the bitmap containing the alien imagery // then scan the images out into the surfaces of alien[0] // and copy then into the other two, be careful of reference counts! // 现在开始载入人物的动画帧图片了 if (!Load_Bitmap_File(&bitmap,"Dedsp0_24bit.bmp")) return(0); // create each surface and load bits // 初始化异形0号的三个动作帧表面、 // 其实、所有的异形动作帧表面都一样的、所以没有必要为每个异形都创建相应的动作帧、 // 所以其它异形的动作帧都指向这个异形0号的动作帧就可以了 for (int index = 0; index < 3; index++) { // create surface to hold image aliens[0].frames[index] = DDraw_Create_Surface(72,80,0); // now load bits... Scan_Image_Bitmap(&bitmap, // bitmap file to scan image data from aliens[0].frames[index], // surface to hold data index, 0); // cell to scan image from } // end for index // unload the bitmap file, we no longer need it Unload_Bitmap_File(&bitmap); // now for the tricky part. There is no need to create more surfaces with the same // data, so I'm going to copy the surface pointers member for member to each alien // however, be careful, since the reference counts do NOT go up, you still only need // to release() each surface once! for (index = 0; index < 3; index++) aliens[1].frames[index] = aliens[2].frames[index] = aliens[0].frames[index]; // return success or failure or your own return code here return(1); } // end Game_Init
int Game_Main(void *parms = NULL, int num_parms = 0) { // this is the main loop of the game, do all your processing // here // lookup for proper walking sequence // 动画帧、先播放站立动作、然后是摆左手、然后再恢复站立动作、然后是摆右手 // 如此重复播放 // 声明为静态、所以不会随着Game_Main的调用而重复初始化 static int animation_seq[4] = {0,1,0,2}; int index; // general looping variable // make sure this isn't executed again if (window_closed) return(0); // for now test if user is hitting ESC and send WM_CLOSE if (KEYDOWN(VK_ESCAPE)) { PostMessage(main_window_handle,WM_CLOSE,0,0); window_closed = 1; } // end if DDRAW_INIT_STRUCT(ddbltfx); if(lpddsback->Blt(NULL, lpddsbackground, NULL, DDBLT_WAIT, &ddbltfx)) return 0; // move objects around // 这里是移动异形 for (index=0; index < 3; index++) { // move each object to the right at its given velocity // 移动异形向右走 aliens[index].x++; // =aliens[index].velocity; // 测试异形的位置是否已经到达了右边界已经完全看不着了 // 就把它又扔会左边从头走过来 // 因为x是左上角的坐标、所以x超过了屏幕宽度刚好完全看不见 // 而因为异形图片的人物宽度刚好为80、所以重置到左边时设置为-80 // test if off screen edge, and wrap around if (aliens[index].x > SCREEN_WIDTH) aliens[index].x = - 80; // animate bot if (++aliens[index].counter >= (8 - aliens[index].velocity)) { // reset counter aliens[index].counter = 0; // advance to next frame // 如果超过第三帧、则重置为第0帧、这里是由前面的结构所决定的、只有三个动作 // 由于采用了先自增再比较的办法、所以条件这里current_frame的范围恒为1~4 // 所谓的第零帧、也就是标准的站立动作、可以从位图图片得知、 if (++aliens[index].current_frame > 3) aliens[index].current_frame = 0; } // end if } // end for index // draw all the bots for (index=0; index < 3; index++) { /* 原型 int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, // source surface to draw int x, int y, // position to draw at int width, int height, // size of source surface LPDIRECTDRAWSURFACE7 dest, // surface to draw the surface on int transparent = 1) // transparency flag */ // draw objects // 把相应的三个异形的每帧动作拷贝进缓冲表面中 // 其中animation_seq[aliens[index].current_frame]决定了产生哪些动作帧 // 在Game_Main函数就已经有定义了static int animation_seq[4] = {0,1,0,2}; // 这里current_frame的范围就是0~3 DDraw_Draw_Surface(aliens[index].frames[animation_seq[aliens[index].current_frame]], aliens[index].x, aliens[index].y, 72,80, lpddsback); } // end for index while(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT))); // 每秒30帧 Sleep(33); // do nothing -- look at pretty picture // return success or failure or your own return code here return(1); } // end Game_Main
BOOL TAGameAreaReDrawer::GrayBlitOfBits (LPRECT DescRect, LPBYTE SrcBits, LPPOINT SrcAspect, LPRECT SrcScope, BOOL NoMapped) { BOOL Rtn_B= FALSE; LPBYTE TAGrayTABLE_p= (*TAmainStruct_PtrPtr)->TAProgramStruct_Ptr->GRAY_TABLE; if (NULL!=GameAreaSurfaceBack_ptr) { if ( DD_OK!=GameAreaSurfaceBack_ptr->IsLost ( )) { GameAreaSurfaceBack_ptr->Restore ( ); } DDSURFACEDESC ddsd; DDRAW_INIT_STRUCT ( ddsd); if (DD_OK==GameAreaSurfaceBack_ptr->Lock ( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR| DDLOCK_WAIT, NULL)) { DWORD DescYStart; DWORD DescXStart; DWORD SrcXStart; DWORD SrcYStart; DWORD CopyHeight; DWORD CopyWidth; DWORD DescPitch; DWORD DescHeight; DWORD DescWidth; LPBYTE DescMem; DescMem= reinterpret_cast<LPBYTE>(ddsd.lpSurface); DescPitch= ddsd.lPitch; if (NULL==DescRect) { DescXStart= 0; DescYStart= 0; DescWidth= ddsd.dwWidth; DescHeight= ddsd.dwHeight; } else { DescXStart= DescRect->left; DescYStart= DescRect->top; DescWidth= DescRect->right; DescHeight= DescRect->bottom; } if (NULL==SrcScope) { SrcXStart= 0; SrcYStart= 0; CopyHeight= SrcAspect->y; CopyWidth= SrcAspect->x; } else { SrcXStart= SrcScope->left; SrcYStart= SrcScope->right; CopyHeight= SrcScope->bottom; CopyWidth= SrcScope->right; } if ((ddsd.dwWidth<DescXStart) ||(DescHeight<0) ||(ddsd.dwHeight<DescYStart) ||(DescWidth<0) ||(CopyHeight<0) ||(CopyWidth<0)) { return Rtn_B; } if (DescXStart<0) { DescXStart= 0; } if (DescYStart<0) { DescYStart= 0; } if (ddsd.dwWidth<DescWidth) { DescWidth= ddsd.dwWidth; } if (ddsd.dwHeight<DescHeight) { DescHeight= ddsd.dwHeight; } // if (SrcXStart<0) { SrcXStart= 0; } if (SrcYStart<0) { SrcYStart= 0; } if (CopyHeight>static_cast<DWORD>(SrcAspect->y)) { CopyHeight= static_cast<DWORD>(SrcAspect->y); } if (CopyWidth>static_cast<DWORD>(SrcAspect->x)) { CopyWidth= static_cast<DWORD>(SrcAspect->x); } if ((CopyHeight)>DescHeight) { CopyHeight= DescHeight; } if ((CopyWidth)>DescWidth) { CopyWidth= DescWidth; } DWORD i, i_1, i_2, i_3; if (NoMapped) { for ( i= DescYStart, i_1= SrcYStart; i< CopyHeight; ++i, ++i_1) { int DescYOffset= i* DescPitch; int SrcYOffset= i_1* SrcAspect->x; for ( i_2= DescXStart, i_3= SrcXStart; i_2< CopyWidth; i_2++, i_3++) { if (0==SrcBits[SrcYOffset+ i_3]) { // black DescMem[DescYOffset+ i_2]= 0; } } } } else { for ( i= DescYStart, i_1= SrcYStart; i< CopyHeight; ++i, ++i_1) { int DescYOffset= i* DescPitch; int SrcYOffset= i_1* SrcAspect->x; for ( i_2= DescXStart, i_3= SrcXStart; i_2< CopyWidth; i_2++, i_3++) { if (0==SrcBits[SrcYOffset+ i_3]) { DescMem[DescYOffset+ i_2]= TAGrayTABLE_p[SrcBits[SrcYOffset+ i_3]];//TAGrayTABLE_p[DescMem[DescYOffset+ i_2]]; } } } } GameAreaSurfaceBack_ptr->Unlock ( ddsd.lpSurface); Rtn_B= TRUE; } } return Rtn_B; }
BOOL TAGameAreaReDrawer::MixBitsInBlit (LPRECT DescRect, LPBYTE SrcBits, LPPOINT SrcAspect, LPRECT SrcScope) { BOOL Rtn_B= FALSE; if (NULL!=GameAreaSurfaceBack_ptr) { if ( DD_OK!=GameAreaSurfaceBack_ptr->IsLost ( )) { GameAreaSurfaceBack_ptr->Restore ( ); } DDSURFACEDESC ddsd; DDRAW_INIT_STRUCT ( ddsd); if (DD_OK==GameAreaSurfaceBack_ptr->Lock ( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR| DDLOCK_WAIT, NULL)) { DWORD DescYStart; DWORD DescXStart; DWORD SrcXStart; DWORD SrcYStart; DWORD CopyHeight; DWORD CopyWidth; DWORD DescPitch; DWORD DescHeight; DWORD DescWidth; LPBYTE DescMem; DescMem= reinterpret_cast<LPBYTE>(ddsd.lpSurface); DescPitch= ddsd.lPitch; if (NULL==DescRect) { DescXStart= 0; DescYStart= 0; DescWidth= ddsd.dwWidth; DescHeight= ddsd.dwHeight; } else { DescXStart= DescRect->left; DescYStart= DescRect->top; DescWidth= DescRect->right; DescHeight= DescRect->bottom; } if (NULL==SrcScope) { SrcXStart= 0; SrcYStart= 0; CopyHeight= SrcAspect->y; CopyWidth= SrcAspect->x; } else { SrcXStart= SrcScope->left; SrcYStart= SrcScope->right; CopyHeight= SrcScope->bottom; CopyWidth= SrcScope->right; } if ((ddsd.dwWidth<DescXStart) ||(DescHeight<0) ||(ddsd.dwHeight<DescYStart) ||(DescWidth<0) ||(CopyHeight<0) ||(CopyWidth<0)) { return Rtn_B; } if (DescXStart<0) { DescXStart= 0; } if (DescYStart<0) { DescYStart= 0; } if (ddsd.dwWidth<DescWidth) { DescWidth= ddsd.dwWidth; } if (ddsd.dwHeight<DescHeight) { DescHeight= ddsd.dwHeight; } // if (SrcXStart<0) { SrcXStart= 0; } if (SrcYStart<0) { SrcYStart= 0; } if (CopyHeight>static_cast<DWORD>(SrcAspect->y)) { CopyHeight= static_cast<DWORD>(SrcAspect->y); } if (CopyWidth>static_cast<DWORD>(SrcAspect->x)) { CopyWidth= static_cast<DWORD>(SrcAspect->x); } if ((CopyHeight)>DescHeight) { CopyHeight= DescHeight; } if ((CopyWidth)>DescWidth) { CopyWidth= DescWidth; } DWORD TailCopyWidth= CopyWidth% 4; DWORD i, i_1, i_2, i_3; CopyWidth= CopyWidth- TailCopyWidth; for ( i= DescYStart, i_1= SrcYStart; i< CopyHeight; ++i, ++i_1) { int DescYOffset= i* DescPitch; int SrcYOffset= i_1* SrcAspect->x; for ( i_2= DescXStart, i_3= SrcXStart; i_2< CopyWidth; i_2= i_2+ 4, i_3= i_3+ 4) { *reinterpret_cast<LPDWORD>( &(DescMem[DescYOffset+ i_2]))= *reinterpret_cast<LPDWORD>( &(SrcBits[SrcYOffset+ i_3])); } for (DWORD temp_counter= 0; temp_counter<TailCopyWidth; ++temp_counter) { DescMem[DescYOffset+ i_2+ temp_counter]= SrcBits[SrcYOffset+ i_3+ temp_counter]; } } GameAreaSurfaceBack_ptr->Unlock ( ddsd.lpSurface); Rtn_B= TRUE; } } return Rtn_B; }