Пример #1
0
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

// copy the bitmap image to the primary buffer line by line
// notice the 24 to 16 bit conversion pixel by pixel

// lock the primary surface
lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer to primary surfce
USHORT *primary_buffer = (USHORT *)ddsd.lpSurface;       

// process each line and copy it into the primary buffer
for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
    {
    for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
        {
        // get BGR values, note the scaling down of the channels, so that they
        // fit into the 5.6.5 format
        UCHAR blue  = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]) >> 3,
              green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]) >> 3,
              red   = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]) >> 3;

        // this builds a 16 bit color value in 5.6.5 format (green dominant mode)
        USHORT pixel = _RGB16BIT565(red,green,blue);

        // write the pixel
        primary_buffer[index_x + (index_y*ddsd.lPitch >> 1)] = pixel;

        } // end for index_x

    } // end for index_y

// now unlock the primary surface
if (FAILED(lpddsprimary->Unlock(NULL)))
   return(0);

// do nothing -- look at pretty picture

// return success or failure or your own return code here
return(1);

} // end Game_Main
Пример #2
0
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
Пример #3
0
//-----------------------------------------------------------------------------
// Name: Lock()
// Desc: Fucntion to lock the entire surface
//-----------------------------------------------------------------------------
int Lock(LPDIRECTDRAWSURFACE7 lpddsSurface)
{
	memset(&ddsd,0,sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	ddReturnVal  = lpddsSurface->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
	if (DDFailedCheck(ddReturnVal, "Lock(), failed", cpErrorBuf ))
	{	MessageBox(main_window_handle, cpErrorBuf, "SurfaceFuncs, Lock()", MB_ICONEXCLAMATION); return(0); }
	
	return (1);
}
Пример #4
0
int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,     // bitmap file to scan image data from
                      LPDIRECTDRAWSURFACE7 lpdds, // surface to hold data
                      int cx, int cy)             // cell to scan image from
{
// this function extracts a bitmap out of a bitmap file

UCHAR *source_ptr,   // working pointers
      *dest_ptr;

DDSURFACEDESC2 ddsd;  //  direct draw surface description 

// get the addr to destination surface memory

// set size of the structure
ddsd.dwSize = sizeof(ddsd);

// lock the display surface
lpdds->Lock(NULL,
            &ddsd,
            DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
            NULL);

// compute position to start scanning bits from
cx = cx*(ddsd.dwWidth+1) + 1;
cy = cy*(ddsd.dwHeight+1) + 1;

gwidth  = ddsd.dwWidth;
gheight = ddsd.dwHeight;

// extract bitmap data
source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;

// assign a pointer to the memory surface for manipulation
dest_ptr = (UCHAR *)ddsd.lpSurface;

// iterate thru each scanline and copy bitmap
for (int index_y=0; index_y < ddsd.dwHeight; index_y++)
    {
    // copy next line of data to destination
    memcpy(dest_ptr, source_ptr, ddsd.dwWidth);

    // advance pointers
    dest_ptr   += (ddsd.lPitch);
    source_ptr += bitmap->bitmapinfoheader.biWidth;
    } // end for index_y

// unlock the surface 
lpdds->Unlock(NULL);

// return success
return(1);

} // end Scan_Image_Bitmap
Пример #5
0
int Bmp2Surface(LPDIRECTDRAWSURFACE7 lpdds, int SurfaceWidth, int SurfaceHeight)
{
	// copy the bitmap image to the lpddsback buffer line by line
	// notice the 24 to 32 bit conversion pixel by pixel

	// 一个像素一个像素的逐粒拷贝至表面

	// lock the lpddsback surface
	lpdds->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

	// get video pointer to primary surfce
	DWORD *back_buffer = (DWORD *)ddsd.lpSurface;       

	// process each line and copy it into the lpddsback buffer
	if (ddsd.lPitch == SurfaceWidth)
	{
	   // copy memory from double buffer to lpddsback buffer
	   memcpy((void *)back_buffer, (void *)bitmap.buffer, SurfaceWidth*SurfaceHeight);
	}
	else
	{


		
		for (int index_y = 0; index_y < SurfaceHeight; index_y++)
		{
			for (int index_x = 0; index_x < SurfaceWidth; index_x++)
			{
				// get BGR values
				UCHAR blue  = (bitmap.buffer[index_y*SurfaceWidth*3 + index_x*3 + 0]),
					  green = (bitmap.buffer[index_y*SurfaceWidth*3 + index_x*3 + 1]),
					  red   = (bitmap.buffer[index_y*SurfaceWidth*3 + index_x*3 + 2]);

				// this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
				DWORD pixel = _RGB32BIT(0,red,green,blue);

				// write the pixel
				back_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

			} // end for index_x

		} // end for index_y

		
		
	}

	// now unlock the lpddsback surface
	if (FAILED(lpdds->Unlock(NULL)))
	   return(0);
}  // end Bmp2Surface
Пример #6
0
HRESULT GameDisplayLoop(HWND hWnd, PFPImage pImage, LONG destX, LONG destY)
{
	HRESULT hResult;
	DDBLTFX ddBltFx;
	memset(&ddBltFx, 0, sizeof(ddBltFx));
	ddBltFx.dwSize = sizeof(ddBltFx);
	ddBltFx.dwROP = SRCCOPY;

	RECT rcMain = { 0 };
	GetClientRect(hWnd, &rcMain);
	ClientToScreen(hWnd, ((LPPOINT)&rcMain) + 0);
	ClientToScreen(hWnd, ((LPPOINT)&rcMain) + 1);
	//FP_DEBUG_MSG(_T("CLINET RECT: (%d, %d) - (%d, %d)\n"), rcMain.top, rcMain.bottom, rcMain.left, rcMain.right);

	RECT rcBack = { 0 };
	DDSURFACEDESC2 ddsd;
	DDRAW_INIT_STRUCT(ddsd);
	if (FAILED(hResult = lpddsBack->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
	{
		FP_DEBUG_MSG(_T("Lock Error: 0x%08x\n"), hResult);
		return E_FAIL;
	}
	LPPALETTEENTRY lpPalet = NULL;
	if (FAILED(gameGraphics->ChangePalette(FP_PALETTE_DAY, &lpPalet)))
	{
		return E_FAIL;
	}
	LPBYTE lpPixel = (LPBYTE)ddsd.lpSurface;
	LPBYTE lpData = (LPBYTE)pImage->data;
	LONG n = 0;
	for (LONG i = 0; i < pImage->height; i++)
	{
		n = (i + destY) * ddsd.lPitch + destX * sizeof(PALETTEENTRY);
		for (LONG j = 0; j < pImage->width; j++, n += 4)
		{
			LPBYTE lpPtr = &lpPixel[n];
			*(lpPtr + 0) = lpPalet[lpData[(pImage->height - i - 1) * pImage->width + j]].peRed;
			*(lpPtr + 1) = lpPalet[lpData[(pImage->height - i - 1) * pImage->width + j]].peGreen;
			*(lpPtr + 2) = lpPalet[lpData[(pImage->height - i - 1) * pImage->width + j]].peBlue;
			*(lpPtr + 3) = 0;
		}
	}
	lpddsBack->Unlock(NULL);

	lpddsMain->Blt(&rcMain, lpddsBack, NULL, DDBLT_WAIT, &ddBltFx);
	return S_OK;
}
Пример #7
0
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


// lock primary buffer
DDRAW_INIT_STRUCT(ddsd);

if (FAILED(lpddsprimary->Lock(NULL,&ddsd,
                              DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
                              NULL)))
return(0);

// draw 1000 random lines
for (int index=0; index < 1000; index++)
    {
    Draw_Line(rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT,
              rand()%SCREEN_WIDTH, rand()%SCREEN_HEIGHT,
              rand()%256,
              (UCHAR *)ddsd.lpSurface, ddsd.lPitch);

    } // end for index


// unlock primary buffer
if (FAILED(lpddsprimary->Unlock(NULL)))
   return(0);

// wait a sec
Sleep(33);

// return success or failure or your own return code here
return(1);

} // end Game_Main
Пример #8
0
//-----------------------------------------------------------------------------
// Name: dx_AccessMemoire(...)
// Desc: Vérouille/déverouille l'accès à la mémoire vidéo
//-----------------------------------------------------------------------------
bool dx_AccessMemoire (bool pVerrou)
{
    if (pVerrou)
    {
        SurfaceBack->Lock (NULL, &SurfaceDesc, DDLOCK_WAIT, NULL);

        Pitch = (int)SurfaceDesc.lPitch;
        Ecran = (BVRA*)SurfaceDesc.lpSurface;
    }
    else
    {
        SurfaceBack->Unlock (NULL);

        Pitch = 0;
        Ecran = NULL;
    }

    return dx_Test ();
}
Пример #9
0
//! Load the bitmap and copy it to the overlay surface
bool DrawOverlay()
{
    HRESULT        hRet;       // This is where we put return values from DirectDraw.
    DDSURFACEDESC2 surfDesc;
    // Setup structure
    memset(&surfDesc, 0, sizeof(surfDesc)); surfDesc.dwSize = sizeof(surfDesc);

    hRet = g_pDDSOverlay->Lock(NULL, &surfDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_NOSYSLOCK | DDLOCK_WRITEONLY, NULL);
    if (hRet != DD_OK ||  surfDesc.lpSurface == NULL)
        return DisplayError("Can't lock overlay surface", hRet);
    else {
        g_pImg = (unsigned int *)surfDesc.lpSurface;
        //g_pDDSOverlay->Unlock(NULL); is not needed?
    }
    // Setup effects structure
    memset(&g_OverlayFX, 0, sizeof(g_OverlayFX)); g_OverlayFX.dwSize = sizeof(g_OverlayFX);
    // Setup overlay flags.
    g_OverlayFlags = DDOVER_SHOW;
    // Check for destination color keying capability
    if ((g_DDCaps.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) && ((g_DDCaps.dwCaps & DDCAPS_OVERLAYCANTCLIP) || (g_DDCaps.dwCKeyCaps & DDCKEYCAPS_NOCOSTOVERLAY) ))
    {
        // If so, we'll use it to clip the bitmap when other windows go on top
        // of us. Just for the record - this color range for color keying (the
        // high/low values) are not heavily supported right now, so for almost
        // all cards, just use the same color for both.
        g_OverlayFX.dckDestColorkey.dwColorSpaceLowValue =
        g_OverlayFX.dckDestColorkey.dwColorSpaceHighValue = DDColorMatch(g_pDDSPrimary, RGBKEY);
        g_OverlayFlags |= DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
    } else {
        // If not, we'll setup a clipper for the window.  This will fix the
        // problem on a few video cards - but the ones that don't shouldn't care.
        hRet = g_pDD->CreateClipper(0, &g_pClipper, NULL);
        if (hRet != DD_OK)
            return DisplayError("Can't create clipper", hRet);
        hRet = g_pClipper->SetHWnd(0, g_hAppWnd);
        if (hRet != DD_OK)
            return DisplayError("Can't attach clipper", hRet);
        hRet = g_pDDSPrimary->SetClipper(g_pClipper);
        if (hRet != DD_OK)
            return DisplayError("Can't set clipper", hRet);
    }
    return true;
}
Пример #10
0
void DDAccurateUpdateDisplay(bool singlestep)
{
        static int framecounter=0;
        HRESULT hRet;
        RECT rDest;

        if (++framecounter > zx81.frameskip || singlestep)
                framecounter=0;
        else
                return;

        DDFrame->Unlock(NULL);

        POINT p = {0, 0};
        if(!Form1->FullScreen) p=Form1->ClientToScreen(p);

        rDest=rcdest;
        rDest.left += p.x;
        rDest.top += p.y;
        rDest.right += p.x;
        rDest.bottom += p.y;

        //if (Form1->FullScreen) DDDrawBorder();
        while(1)
        {
                hRet = m_pddsFrontBuffer->Blt(&rDest, DDFrame, &rcsource, DDBLT_WAIT, NULL);

                if (hRet == DD_OK) break;
                else
                if(hRet == DDERR_SURFACELOST)
                {
                        m_pddsFrontBuffer->Restore();
                        m_pddsFrame->Restore();
                }
                else if(hRet != DDERR_WASSTILLDRAWING) return;
        }


        DDFrame->Lock(NULL, &DDFrameSurface, DDLOCK_WAIT |  DDLOCK_NOSYSLOCK, NULL);
        dest=buffer= (BYTE*)DDFrameSurface.lpSurface;
}
Пример #11
0
void DDAccurateInit(int resize)
{
        DDPIXELFORMAT DDpf;
        DDSURFACEDESC2 ddsd;

        float OrigW, OrigH, ScaleW, ScaleH;

        OrigW=Form1->ClientWidth;
        OrigH=Form1->ClientHeight;
        if (Form1->StatusBar1->Visible) OrigH -= Form1->StatusBar1->Height;

        if (Form1->BaseWidth==0) Form1->BaseWidth= NoWinR-NoWinL;
        if (Form1->BaseHeight==0) Form1->BaseHeight= NoWinT-NoWinB;

        ScaleW = OrigW / Form1->BaseWidth;
        ScaleH = OrigH / Form1->BaseHeight;

        RasterX=0;
        RasterY=random(256);

        //fill the DDpf structure and get the BytesPerPixel
        ZeroMemory (&DDpf, sizeof(DDpf));
        DDpf.dwSize = sizeof(DDpf);
        m_pddsFrontBuffer->GetPixelFormat(&DDpf);
        BPP = DDpf.dwRGBBitCount/8;

        Paletteised = (BPP==1) ? true:false;
        Scale= tv.AdvancedEffects?2:1;

        //ScanLen=460*BPP;
        ScanLen=(2+machine.tperscanline*2)*BPP;

        switch(zx81.bordersize)
        {
        case BORDERNONE:
                WinL=BlWinL; WinR=BlWinR; WinT=BlWinT; WinB=BlWinB;
                if (zx81.NTSC) { WinT-=24; WinB-=24; }
                break;
        case BORDERSMALL:
                WinL=SmWinL; WinR=SmWinR; WinT=SmWinT; WinB=SmWinB;
                if (zx81.NTSC) { WinT-=24; WinB-=24; }
                break;
        case BORDERNORMAL:
                WinL=NoWinL; WinR=NoWinR; WinT=NoWinT; WinB=NoWinB;
                if (zx81.NTSC) { WinT-=24; WinB-=24; }
                break;
        case BORDERLARGE:
                WinL=LaWinL; WinR=LaWinR; WinT=LaWinT; WinB=LaWinB;
                if (zx81.NTSC) { WinB-=24; }
                break;
        case BORDERFULL:
                WinL=FuWinL; WinR=FuWinR; WinT=FuWinT; WinB=FuWinB;
                if (zx81.NTSC) WinB-=51;
                break;
        }

        ZeroMemory( &ddsd, sizeof( ddsd ) );
        ddsd.dwSize = sizeof( ddsd );
        // Create the backbuffer surface
        ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;

        if (tv.AdvancedEffects)
        {
                WinL*=2; WinR*=2; WinT*=2; WinB*=2; ScanLen*=2;
                TVW=ddsd.dwWidth = 1024;
                TVH=ddsd.dwHeight = 768;
                HSYNC_TOLLERANCE=HTOL*2; HSYNC_MINLEN=10;
                VSYNC_TOLLERANCE=VTOL*2; VSYNC_MINLEN=350;
        }
        else
        {
                TVW=ddsd.dwWidth = 520;
                TVH=ddsd.dwHeight = 380;
                HSYNC_TOLLERANCE=HTOL; HSYNC_MINLEN=10;
                VSYNC_TOLLERANCE=VTOL; VSYNC_MINLEN=350;
        }

        m_pddsFrame->Release(); m_pddsFrame = NULL;
        m_pDD->CreateSurface(&ddsd, &m_pddsFrame, NULL);

        if (zx81.NTSC) VSYNC_TOLLERANCE-=60;

        if ((resize) && (!Form1->FullScreen))
        {
                Form1->BaseWidth=WinR-WinL;
                Form1->BaseHeight=WinB-WinT;

                OrigW = Form1->BaseWidth * ScaleW;
                OrigH = Form1->BaseHeight * ScaleH;
                if (Form1->StatusBar1->Visible) OrigH += Form1->StatusBar1->Height;

                Form1->ClientWidth = OrigW;
                Form1->ClientHeight = OrigH;
        }

        DDFrame=m_pddsFrame;

        ZeroMemory(&DDFrameSurface, sizeof(DDFrameSurface));
        DDFrameSurface.dwSize = sizeof(DDFrameSurface);
        DDFrame->Lock(NULL, &DDFrameSurface, DDLOCK_WAIT |  DDLOCK_NOSYSLOCK, NULL);
        dest=buffer= (BYTE*)DDFrameSurface.lpSurface;
        TVP=DDFrameSurface.lPitch;

        RecalcPalette();
        RecalcWinSize();
}
Пример #12
0
static inline void WINAPI vdraw_ddraw_draw_text(DDSURFACEDESC2* pddsd, LPDIRECTDRAWSURFACE7 lpDDS_Surface, const BOOL lock)
{
	if (lock)
		lpDDS_Surface->Lock(NULL, pddsd, DDLOCK_WAIT, NULL);
	
	// Determine the window size using the scaling factor.
	const int curHPix = vdp_getHPix();
	
	// +(8*bytespp) is needed for the lpSurface pointer because the DDraw module
	// includes the entire 336x240 MD_Screen. The first 8 pixels are offscreen,
	// so they won't show up at all.
	
	uint8_t bytespp = (bppOut == 15 ? 2 : bppOut / 8);
	
	// NOTE: fullW must be (pddsd->lPitch / bytespp).
	// DirectDraw likes to use absurdly large line lengths in full screen mode.
	// (pddsd->lPitch / bytespp) does match pddsd->dwWidth in windowed mode, though.
	uint8_t *start = (uint8_t*)pddsd->lpSurface;
	
	int msg_height;
	int msg_width;
	if (vdraw_ddraw_is_hw_render())
	{
		// Hardware rendering uses 1x internally.
		msg_height = VDP_Lines.Visible.Total;
		msg_width = curHPix;
		start += (pddsd->lPitch * VDP_Lines.Visible.Border_Size);
		if (curHPix < 320)
			start += (vdp_getHPixBegin() * bytespp);
		
		// DirectDraw's hardware rendering uses MD_Screen / MD_Screen32 directly.
		// Thus, it has an invisible 8px column at the beginning.
		start += (8 * bytespp);
	}
	else
	{
		// Software rendering.
		msg_height = VDP_Lines.Visible.Total * vdraw_scale;
		msg_width = curHPix * vdraw_scale;
		start += (pddsd->lPitch * (VDP_Lines.Visible.Border_Size * vdraw_scale));
		if (curHPix < 320)
			start += (vdp_getHPixBegin() * vdraw_scale * bytespp);
	}
	
	if (vdraw_msg_visible)
	{
		// Message is visible.
		draw_text(start, pddsd->lPitch / bytespp,
				msg_width, msg_height,
				vdraw_msg_text, &vdraw_msg_style);
	}
	else if (vdraw_fps_enabled && (Game != NULL) && Settings.Active && !Settings.Paused && !IS_DEBUGGING())
	{
		// FPS is enabled.
		draw_text(start, pddsd->lPitch / bytespp,
				msg_width, msg_height,
				vdraw_msg_text, &vdraw_fps_style);
	}
	
	if (lock)
		lpDDS_Surface->Unlock(NULL);
}
Пример #13
0
	BOOL JCDD_Wrapper::loadBitmapDataFromFile(INT surfaceID, LPWCH filePath)
	{
		if(lpjcdd->containsTheOffscreenSurface(surfaceID))
		{
			return FALSE;
		}

		JCDD_File file;
		if(!file.loadData(filePath))
		{
			return FALSE;
		}

		JCDD_BitmapData bmpd;
		if(!bmpd.create(file.getData()))
		{
			return FALSE;
		}
		BOOL reverseRow = bmpd.bmpInfoHeader.biHeight < 0;
		INT biWidth = bmpd.bmpInfoHeader.biWidth;
		INT biHeight = reverseRow ? -bmpd.bmpInfoHeader.biHeight : bmpd.bmpInfoHeader.biHeight;
		
		if(bmpd.bmpInfoHeader.biBitCount != BitmapDataBitCount_8 && 
			bmpd.bmpInfoHeader.biBitCount != BitmapDataBitCount_24 && 
			bmpd.bmpInfoHeader.biBitCount != BitmapDataBitCount_32)
		{
			return FALSE;
		}

		if(!lpjcdd->createOffscreenSurface(surfaceID, bmpd.bmpInfoHeader.biWidth, biHeight))
		{
			return FALSE;
		}

		LPJCDD_Surface surface = lpjcdd->getOffscreenSurface(surfaceID);
		LPDIRECTDRAWSURFACE7 lpdds = surface->getSurface();
		DDSURFACEDESC2 ddsd;
		jcdd_initStruct(&ddsd);
		if(FAILED(lpdds->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
		{
			lpjcdd->deleteOffscreenSurface(surfaceID);
			return FALSE;
		}

		UINT* buffer = (UINT*)ddsd.lpSurface;
		INT pixelWidth = bmpd.bmpInfoHeader.biWidth;
		INT pixelHeight = biHeight;
		INT pixelWidthCount = 0;
		INT pixelHeightCount = biHeight - 1;
		INT pitch = ddsd.lPitch >> 2;

		if(bmpd.bmpInfoHeader.biBitCount == BitmapDataBitCount_8)
		{
			JCDD_BitmapDataColorIterator8Bit it(&bmpd);
			while(it.hasNext())
			{
				PALETTEENTRY color = bmpd.palette[it.next()];
				buffer[pixelWidthCount + pixelHeightCount * pitch] = jcdd_rgb32Bit(0x00, color.peRed, color.peGreen, color.peBlue);
				if(++pixelWidthCount == pixelWidth)
				{
					pixelWidthCount = 0;
					--pixelHeightCount;
				}
			}
		}
		else if(bmpd.bmpInfoHeader.biBitCount == BitmapDataBitCount_24)
		{
			JCDD_BitmapDataColorIterator24Bit it(&bmpd);
			while(it.hasNext())
			{
				JCDD_BitmapDataRGB* color = it.next();
				buffer[pixelWidthCount + pixelHeightCount * pitch] = jcdd_rgb32Bit(0x00, color->r, color->g, color->b);
				if(++pixelWidthCount == pixelWidth)
				{
					pixelWidthCount = 0;
					--pixelHeightCount;
				}
			}
		}
		else if(bmpd.bmpInfoHeader.biBitCount == BitmapDataBitCount_32)
		{
			JCDD_BitmapDataColorIterator32Bit it(&bmpd);
			while(it.hasNext())
			{
				JCDD_BitmapDataXRGB* color = it.next();
				buffer[pixelWidthCount + pixelHeightCount * pitch] = jcdd_rgb32Bit(0x00, color->r, color->g, color->b);
				if(++pixelWidthCount == pixelWidth)
				{
					pixelWidthCount = 0;
					--pixelHeightCount;
				}
			}
		}

		if(FAILED(lpdds->Unlock(NULL)))
		{
			lpjcdd->deleteOffscreenSurface(surfaceID);
			return FALSE;
		}

		return TRUE;
	}
Пример #14
0
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
Пример #15
0
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
Пример #16
0
/**
 * 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;
}
Пример #17
0
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
Пример #18
0
int Game_Main(void *parms = NULL, int num_parms = 0)
{

   DDBLTFX ddbltfx;
   RECT    dest_rect;
   static short   curr_color = 0;
   static short   top = 0;
   static short   left = 0;
      
   if (window_closed)
   {
      return (0);
   }
      // for now test if user is hitting ESC and send WM_CLOSE
   if (KEYDOWN(VK_ESCAPE))
   {
      window_closed = true;
      SendMessage(main_window_handle,WM_CLOSE,0,0);
   }

   
   
   // just blast pixels here..
#if 0
   // this is the main loop of the game, do all your processing
   // here
   memset(&ddsd,0,sizeof(ddsd));
   ddsd.dwSize = sizeof(ddsd);
   
   if (FAILED(lpddsprimary->Lock(NULL,
                                 &ddsd,
                                 DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
                                 NULL)
             )
      )
   {
      // BAD SHIT HAPPENED HERE...
      g_ddStepFailure = DDSF_LOCKFAILED;
      SendMessage(main_window_handle,WM_CLOSE,0,0);   
   }
   
   int   mempitch       = (ddsd.lPitch >> 1); // adjust for words..
   WORD  *video_buffer  = (WORD *) ddsd.lpSurface;
#endif   
   // prefigure mPitchlookup for even greater speed.
   

   // x1,y1
   dest_rect.left = left;
   dest_rect.top  = top;
   // x2,y2
   dest_rect.right   = dest_rect.left+20;
   dest_rect.bottom  = dest_rect.top+20;

   // setup structure!!!!          
   memset(&ddbltfx,0,sizeof(ddbltfx));
   ddbltfx.dwSize = sizeof(ddbltfx);
   // color to fill.
   ddbltfx.dwFillColor = colors16[curr_color];

   // blit it baby!
   if (FAILED(lpddsprimary->Blt(&dest_rect,
                                NULL,           // no source surface.. its just a fill
                                NULL,           // no source RECT, since no source surface..
                                DDBLT_COLORFILL | DDBLT_WAIT,
                                &ddbltfx                       )))
   {
      return(0);
   }

#if 0
   
   lpddsprimary->Unlock(NULL);
#endif   
   top = top + 10;
   left = left + 10;
   
   if (top > SCREEN_HEIGHT - 20)
   {
      top = 0;
   }
   if (left > SCREEN_WIDTH - 20)
   {
      left = 0;
   }
   
   curr_color++;
   if (curr_color > 5000)
   {
      curr_color = 0;
   }
   
   // return success or failure or your own return code here
   return(1);

} // end Game_Main
Пример #19
0
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
Пример #20
0
int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,     // bitmap file to scan image data from
                      LPDIRECTDRAWSURFACE7 lpdds, // surface to hold data
                      int cx, int cy)             // cell to scan image from
{
// this function extracts a bitmap out of a bitmap file

UCHAR *source_ptr,   // working pointers
      *dest_ptr;

DDSURFACEDESC2 ddsd;  //  direct draw surface description 

// get the addr to destination surface memory

// set size of the structure
ddsd.dwSize = sizeof(ddsd);

lpdds->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// compute position to start scanning bits from
/*
(0, 0)  =》 cx=1, cy=1
(1, 0)  =>  cx=dwWidth+2, cy=1
(2, 0)  =>  cx=2dwWeight + 3, cy = 1
*/
// 因为白线的缘故、一条线一个像素点、
// cx负责人物动画帧的起点x坐标、因为人物的左右总有两条白线
// cy负责人物动画帧的起点的y坐标、因为人物的顶头总有一条白色的线
// 所以总是从第二行开始、因为这里传入的cy恒为0、所以cy恒为1
cx = cx*(ddsd.dwWidth + 1) + 1;
cy = cy*(ddsd.dwHeight+1) + 1;


//gwidth  = ddsd.dwWidth;
//gheight = ddsd.dwHeight;


// dwWidth和dwHeight分别是指人物表面的高宽
// 而biWidth和biHeight分别是指人物动画帧位图的高宽
// extract bitmap data
// 为什么要加上biWidth呢、原因是要从第二行才开始录入动画帧表面、因为
// 图片的上方有一条一像素的白色、所以这就是总是要从第二行开始的原因了
// 为什么要加上1呢、因为最左边有一条白线、所以总是要加上1、过滤过它
// ptr => buffer + biWidth + 1
// ptr => buffer + biWidth + dwWidth + 2
// ptr => buffer + biWidth + 2dwWidth + 3

int ptr_offset = cy*bitmap->bitmapinfoheader.biWidth+cx;

source_ptr = bitmap->buffer + ptr_offset;




// assign a pointer to the memory surface for manipulation
dest_ptr = (UCHAR *)ddsd.lpSurface;

// iterate thru each scanline and copy bitmap
// 一行一行的把位图相应的动画帧拷贝到帧表面上
for (int index_y=0; index_y < ddsd.dwHeight; index_y++)
    {
    // copy next line of data to destination
	// 这个狠好理解、前面确定好要拷贝哪帧的位置后、便从这个source_ptr这个位置点、
	// 拷贝dwWidth个字节的位置
    memcpy(dest_ptr, source_ptr, ddsd.dwWidth);

    // advance pointers
	// 在这里、由于动画帧表面是自己创建的、所以其实lPitch就是dwWidth人物表面的宽度而已
	// 这里写lPitch主要也是为了安全而已

	// 虽然内容是已经拷贝到相应位置了、但莪们还是要为下一行的拷贝做准备、因为指针还未移动呢!
	// 
	// 动画帧表面、在拷贝下一行之前移动一整行、刚好就是动画帧的宽、这个比较好理解
	// 虽然位图表面要拷贝的不是一整行、而是其中的dwWidth个像素而已、但也依然要移动位图宽度个字节
	// 想想、把(x, y)移动到(x, y+1)刚好不就是当前行的下一行么、所以刚好也就是相差biWidth个位置
    dest_ptr   += (ddsd.lPitch); // (ddsd.dwWidth);
    source_ptr += bitmap->bitmapinfoheader.biWidth;
    } // end for index_y

// unlock the surface 
lpdds->Unlock(NULL);

// return success
return(1);

} // end Scan_Image_Bitmap