//----------------------------------------------------------------------------- // Name: dx_Affiche() // Desc: Affiche le contenu du buffer à l'écran //----------------------------------------------------------------------------- bool dx_Affiche () { if (PleinEcran) { ErrDd = SurfacePrimaire->Flip (0, DDFLIP_WAIT); } else { RECT tRectSrc; RECT tRectDest; POINT tPosition = {0,0}; // Copie de Surface suivant la position de la fenêtre ClientToScreen (Fenetre, &tPosition); GetClientRect (Fenetre, &tRectDest); if (TailleFenetre) SetRect (&tRectSrc, 0, 0, tRectDest.right-tRectDest.left, tRectDest.bottom-tRectDest.top); else SetRect (&tRectSrc, 0, 0, ResolutionX, ResolutionY); OffsetRect (&tRectDest, tPosition.x, tPosition.y); ErrDd = SurfacePrimaire->Blt (&tRectDest,SurfaceBack,&tRectSrc,DDBLT_WAIT,NULL); } return dx_Test (); };
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); // do the graphics Draw_Polygon2D(&asteroid, (UCHAR *)ddsd.lpSurface, ddsd.lPitch); // test for scale if (KEYDOWN('A')) // scale up Scale_Polygon2D(&asteroid, 1.1, 1.1); else if (KEYDOWN('S')) // scale down Scale_Polygon2D(&asteroid, 0.9, 0.9); // rotate the polygon by 5 degrees Rotate_Polygon2D(&asteroid, 5); // 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
int DD_Flip(void) { // this function flip the primary surface with the secondary surface // flip pages while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK); // flip the surface // return success return(1); } // end DD_Flip
//----------------------------------------------------------------------------- // Name: Flip() // Desc: this function flip the primary surface with the secondary surface //----------------------------------------------------------------------------- int Flip() {// this function flip the primary surface with the secondary surface // flip pages while( (ddReturnVal=lpddsPrimary->Flip(NULL, DDFLIP_WAIT) )!= DD_OK) { if(ddReturnVal!=DD_OK) if(ddReturnVal==DDERR_SURFACELOST) { OutputDebugString("Surfacelost Flip()\n"); lpddsPrimary->Restore(); return(1); } else if (DDFailedCheck(ddReturnVal, "Flip()", cpErrorBuf )) { MessageBox(NULL, cpErrorBuf, "SurfaceFuncs", MB_ICONEXCLAMATION); return(0); } } // return success return(1); } // end DD_Flip
void ProcessIdle() { HRESULT hRet; static int iX = 0, iY = 0; static iLastBlit; if(GetTickCount() - iLastBlit < 50) { return; } g_surfCar.Draw(g_pDDSBack, 245, 170, iX, iY, 150, 140); while( 1 ) { hRet = g_pDDSFront->Flip(NULL, 0 ); if( hRet == DD_OK ) { break; } if( hRet == DDERR_SURFACELOST ) { g_pDDSFront->Restore(); } if( hRet != DDERR_WASSTILLDRAWING ) { break; } } iX += 150; if(iX >= 1500) { iX = 0; iY += 140; if(iY >= 280) { iY = 0; } } iLastBlit = GetTickCount(); }
HRESULT STDMETHODCALLTYPE Flip(LPDIRECTDRAWSURFACE7 surface, LPDIRECTDRAWSURFACE7 lpDDSurface, DWORD flags) { //logOutput << CurrentTimeString() << "Hooked Flip()" << endl; HRESULT hr; EnterCriticalSection(&ddrawMutex); ddrawSurfaceFlip.Unhook(); hr = surface->Flip(lpDDSurface, flags); ddrawSurfaceFlip.Rehook(); g_bUseFlipMethod = true; if (getFrontSurface(surface)) { CaptureDDraw(); } LeaveCriticalSection(&ddrawMutex); return hr; }
////////////////////////////////////////////////////////////////////////////// //MAIN GAME LOOP ////////////////////////////////////////////////////////////////////////////// void Prog_Loop() { //set up the vertex positions vert[0].sx=(float) (cos(angle)*240.0+320.0); vert[0].sy=(float) (sin(angle)*240.0+240.0); vert[0].sz=(float) (sin(angle)*240.0+240.0); vert[1].sx=(float) (cos(angle+PI/2)*240.0+320.0); vert[1].sy=(float) (sin(angle+PI/2)*240.0+240.0); vert[1].sz=(float) (sin(angle+PI/2)*240.0+240.0); vert[2].sx=(float) (cos(angle-PI/2)*240.0+320.0); vert[2].sy=(float) (sin(angle-PI/2)*240.0+240.0); vert[2].sz=(float) (sin(angle-PI/2)*240.0+240.0); vert[3].sx=(float) (cos(angle-PI)*240.0+320.0); vert[3].sy=(float) (sin(angle-PI)*240.0+240.0); vert[3].sz=(float) (sin(angle-PI)*240.0+240.0); //add to the angle for next time angle+=PI/90; //clear the viewport to black lpd3ddev->Clear(0,NULL,D3DCLEAR_TARGET,0,0,0); //start the scene lpd3ddev->BeginScene(); //draw the triangle lpd3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_TLVERTEX,vert,4,0); //end the scene lpd3ddev->EndScene(); //flip lpddsPrime->Flip(NULL,DDFLIP_WAIT); }
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
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_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 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 // copy background to back buffer DDraw_Draw_Surface(lpddsbackground,0,0, SCREEN_WIDTH,SCREEN_HEIGHT, lpddsback,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; // 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 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++) { // draw objects but with scaled destination size DDraw_Draw_Surface_Scaled(aliens[index].frames[animation_seq[aliens[index].current_frame]], aliens[index].x, aliens[index].y, aliens[index].width,aliens[index].height, (float)aliens[index].width*aliens[index].scale, (float)aliens[index].height*aliens[index].scale, lpddsback); } // end for index // flip 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
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
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
/** * vdraw_ddraw_flip(): Flip the screen buffer. [Called by vdraw_flip().] * @return 0 on success; non-zero on error. */ int vdraw_ddraw_flip(void) { if (!lpDD) return -1; HRESULT rval = DD_OK; DDSURFACEDESC2 ddsd; ddsd.dwSize = sizeof(ddsd); RECT RectSrc; // Calculate the source rectangle. vdraw_ddraw_calc_RectSrc(RectSrc); if (vdraw_get_fullscreen()) { // Fullscreen. if (vdraw_ddraw_is_hw_render()) { // Hardware rendering. // 1x rendering. // TODO: Test this with border color stuff. // Wine doesn't seem to have a 320x240 fullscreen mode available... // TODO: Test this on a system that supports 1x in fullscreen on DirectDraw. vdraw_ddraw_draw_text(&ddsd, lpDDS_Back, true); if (Video.VSync_FS) { lpDDS_Flip->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL); lpDDS_Primary->Flip(NULL, DDFLIP_WAIT); } else { lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL); //lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, NULL, NULL); } } else { // Software rendering. LPDIRECTDRAWSURFACE7 curBlit = lpDDS_Blit; rval = curBlit->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); if (FAILED(rval)) goto cleanup_flip; vdraw_rInfo.destScreen = (void*)ddsd.lpSurface; vdraw_rInfo.width = 320; vdraw_rInfo.height = 240; vdraw_rInfo.destPitch = ddsd.lPitch; if (vdraw_needs_conversion) { // Color depth conversion is required. vdraw_rgb_convert(&vdraw_rInfo); } else { // Color conversion is not required. vdraw_blitFS(&vdraw_rInfo); } // Draw the text. vdraw_ddraw_draw_text(&ddsd, curBlit, false); curBlit->Unlock(NULL); if (curBlit == lpDDS_Back) // note: this can happen in windowed fullscreen, or if CORRECT_256_ASPECT_RATIO is defined and the current display mode is 256 pixels across { if (Video.VSync_FS) { int vb; lpDD->GetVerticalBlankStatus(&vb); if (!vb) lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); } lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL); } else { if (Video.VSync_FS) { lpDDS_Primary->Flip(NULL, DDFLIP_WAIT); } } } } else { // Windowed mode. if (!vdraw_ddraw_is_hw_render()) { rval = lpDDS_Blit->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); if (FAILED(rval)) goto cleanup_flip; vdraw_rInfo.destScreen = (void*)ddsd.lpSurface; vdraw_rInfo.width = 320; vdraw_rInfo.height = 240; vdraw_rInfo.destPitch = ddsd.lPitch; if (vdraw_needs_conversion) { // Color depth conversion is required. vdraw_rgb_convert(&vdraw_rInfo); } else { // Color conversion is not required. vdraw_blitW(&vdraw_rInfo); } // Draw the text. vdraw_ddraw_draw_text(&ddsd, lpDDS_Blit, false); lpDDS_Blit->Unlock(NULL); } else { // Draw the text. vdraw_ddraw_draw_text(&ddsd, lpDDS_Blit, true); } if (RectDest.top < RectDest.bottom) { if (Video.VSync_W) { int vb; lpDD->GetVerticalBlankStatus(&vb); if (!vb) lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); } // Blit the image. rval = lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL); //rval = lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, NULL, NULL); } } cleanup_flip: if (rval == DDERR_SURFACELOST) rval = vdraw_ddraw_restore_graphics(); return 1; }
/** * vdraw_ddraw_clear_primary_screen(): Clear the primary screen. * @return 0 on success; non-zero on error. */ int WINAPI vdraw_ddraw_clear_primary_screen(void) { if (!lpDD || !lpDDS_Primary) return -1; DDSURFACEDESC2 ddsd; DDBLTFX ddbltfx; RECT rd; POINT p; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); memset(&ddbltfx, 0, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); ddbltfx.dwFillColor = 0; // Black if (vdraw_get_fullscreen()) { if (Video.VSync_FS) { lpDDS_Flip->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); lpDDS_Primary->Flip(NULL, DDFLIP_WAIT); lpDDS_Flip->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); lpDDS_Primary->Flip(NULL, DDFLIP_WAIT); lpDDS_Flip->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); lpDDS_Primary->Flip(NULL, DDFLIP_WAIT); } else { lpDDS_Primary->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); } } else { p.x = p.y = 0; GetClientRect(gens_window, &rd); ClientToScreen(gens_window, &p); rd.left = p.x; rd.top = p.y; rd.right += p.x; rd.bottom += p.y; // Clip the destination rectangle to the screen. if (rd.bottom > vdraw_rectDisplay.bottom) rd.bottom += (vdraw_rectDisplay.bottom - rd.bottom); if (rd.top < vdraw_rectDisplay.top) rd.top += (vdraw_rectDisplay.top - rd.top); if (rd.left < vdraw_rectDisplay.left) rd.left += (vdraw_rectDisplay.left - rd.left); if (rd.right > vdraw_rectDisplay.right) rd.right += (vdraw_rectDisplay.right - rd.right); if (rd.top < rd.bottom) lpDDS_Primary->Blt(&rd, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); } return 0; }