Notices

Water Fountain General Chit/Chat

Reply
 
LinkBack Thread Tools
Old 02-02-06, 05:39 AM   #1 (permalink)
Aximsite Rookie
 
AceRimmer's Avatar
DAP Freshman
 
Join Date: Dec 2004
Posts: 42
Thanked 0 Times in 0 Posts
DirectX Resources and Tutorials

I've just got VS 2005 and am looking to have a go at writing some software for WM5. I've had a quick scout on the web for DirectX tutorials for WM5, but wondered if anyone else has any good sites to look at.

Thanks.
AceRimmer is offline   Reply With Quote
Sponsor Ads
Old 02-03-06, 10:08 AM   #2 (permalink)
Aximsite Minor League
 
Join Date: Feb 2006
Posts: 207
Thanked 1 Time in 1 Post
I'm waiting for my Axim to arrive (Monday) and I'm a VB.Net developer so I'm hoping to start writing stuff for WM5. Not graphics stuff right off though. I'll have to learn to turn it on first.
DaveK is offline   Reply With Quote
Old 02-03-06, 10:21 AM   #3 (permalink)
Aximsite Minor League
 
Join Date: Feb 2006
Posts: 207
Thanked 1 Time in 1 Post
Oh, this guy http://www.nicholaskingsley.co.uk had a post here and his site has a download about directx.
DaveK is offline   Reply With Quote
Old 02-04-06, 02:08 PM   #4 (permalink)
Aximsite Rookie
 
AceRimmer's Avatar
DAP Freshman
 
Join Date: Dec 2004
Posts: 42
Thanked 0 Times in 0 Posts
Thanks, I'll have a look at the code on that site and see how it goes.
AceRimmer is offline   Reply With Quote
Old 02-12-06, 06:17 AM   #5 (permalink)
Aximsite Rookie
 
Join Date: Dec 2005
Location: Chichester
Posts: 32
Thanked 0 Times in 0 Posts
I'm still working on the DirectX system - unfortunately I come across a nasty flicker no matter what, unless a delay of 13ms is added after a screen flip.

From what I can tell, its because the main loop is running too fast for DirectX to keep up, and despite using dual buffering, it still flickers like anything, unless the delay is there.

This is the current DirectX code :

Code:
// CDirectX.cpp : Defines the entry point for the DLL application.
//
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

//#include "stdafx.h"
#include "CDirectX.hpp"
#include <windows.h>
#include <commctrl.h>
#include "CDirectX\resourceppc.h"
#include "CDirectX\SetDisplayMode.h"

CCDirectX::CCDirectX()
{
register int loop;

	lpDirectDraw=NULL;
	for (loop=0; loop<MAX_SURFACES; loop++)
	{
		surfaces[loop]=NULL;
	}

	memset(&driverCaps,(char) NULL,sizeof(driverCaps));
	memset(&emulatorCaps,(char) NULL,sizeof(emulatorCaps));

	m_displayWidth=0;
	m_displayHeight=0;
	
	m_hasFlipSurface=false;
	m_hasBackBuffer=false;
	m_usingPortrait=false;
}

CCDirectX::~CCDirectX()
{
	destroy();
}

void CCDirectX::destroy(void)
{
register int loop;

	for (loop=0; loop<MAX_SURFACES; loop++)
	{
		if (surfaces[loop])
		{
			surfaces[loop]->Release();
			surfaces[loop]=NULL;
		}
	}
	if (lpDirectDraw)
	{
		lpDirectDraw->Release();
		lpDirectDraw=NULL;
	}
}

HRESULT CCDirectX::initialise(HWND hWnd,DWORD flag)
{
HRESULT hRet;

	hRet=DirectDrawCreate(NULL, &lpDirectDraw, NULL);
	if (SUCCEEDED(hRet))
	{
		hRet=lpDirectDraw->SetCooperativeLevel((hWnd==NULL ? GetActiveWindow() : hWnd),flag);
		if (SUCCEEDED(hRet))
		{
			lpDirectDraw->GetCaps(&driverCaps,&emulatorCaps);

			m_hasBackBuffer=driverCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER ? true : false;
			m_hasFlipSurface=driverCaps.ddsCaps.dwCaps & DDSCAPS_FLIP ? true : false;

			getDisplayMode();
			getOrientation();	// Get the display orientation
			setColourKey(0);
		}
	}
	
	return (hRet);
}

HRESULT CCDirectX::listScreenModes(LPVOID lpContext,
									HRESULT (*enumerateFunctions)(LPDDSURFACEDESC lpSurfaceDesc,
																LPVOID  lpContext))
{
	// Change context to a list of structs...  To do
	return (lpDirectDraw->EnumDisplayModes(0,NULL,lpContext,enumerateFunctions));
}

HRESULT CCDirectX::enumerateSurfaces(LPDIRECTDRAWSURFACE pSurface,
										LPDDSURFACEDESC lpSurfaceDesc,
										LPVOID  lpContext)
{
	*((LPDIRECTDRAWSURFACE *) lpContext) = pSurface;
    return DDENUMRET_OK;
}

HRESULT CCDirectX::createSurfaces(bool useTriple)
{
DDSURFACEDESC               ddsd;
HRESULT						hRet;

	if (lpDirectDraw==NULL)	return (DDERR_NOTFOUND);

	memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP;
	ddsd.dwBackBufferCount = (useTriple ? 2 : 1);
	hRet = lpDirectDraw->CreateSurface(&ddsd, &surfaces[PRIMARY_SURFACE], NULL);
	if (SUCCEEDED(hRet))
	{
		// Update the enumerator function later on to be able to handle more surfaces...
		hRet=surfaces[PRIMARY_SURFACE]->EnumAttachedSurfaces(&surfaces[SECONDARY_SURFACE],enumerateSurfaces);		
	}
	
	return (hRet);
}

HRESULT CCDirectX::CLS(DWORD colour)
{
DDBLTFX ddbltfx;
HRESULT hResult;

	if (surfaces[SECONDARY_SURFACE]==NULL)	return (DDERR_NOTFOUND);

	memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwFillColor = colour;

	while (surfaces[SECONDARY_SURFACE]->GetFlipStatus(DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING) ;

	while (true)  
    {
		hResult=surfaces[SECONDARY_SURFACE]->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx);
        if (SUCCEEDED(hResult))
		{
			return hResult;
		}

        if(hResult == DDERR_SURFACELOST )
        {
            if (FAILED(restoreLostSurfaces()))
			{
			}

			break;
        }
        if(hResult != DDERR_WASSTILLDRAWING )
        {
            break;
        }
    }

	return hResult;
}

HRESULT CCDirectX::flip(DWORD flag)
{
HRESULT hRet;

	if (lpDirectDraw==NULL || surfaces[PRIMARY_SURFACE]==NULL)	return (DDERR_NOTFOUND);
		
	while(surfaces[PRIMARY_SURFACE]->GetFlipStatus(DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING) ; 

	while (true)
	{
		hRet = surfaces[PRIMARY_SURFACE]->Flip(NULL, flag);
		if (SUCCEEDED(hRet))
		{		
			Sleep(13);
			break;
		}
		else
		{		
			if (hRet==DDERR_SURFACELOST)
			{
				if (FAILED(restoreLostSurfaces()))
				{
					break;
				}
			}

			if (hRet!=DDERR_WASSTILLDRAWING)
			{
				break;
			}
		}
	} 

	return (hRet);
}

HBITMAP CCDirectX::GetBitmapHandle(HINSTANCE hInstance, LPCTSTR szBitmap)
{
register HBITMAP hbm;

	hbm = (HBITMAP) LoadImage(hInstance, szBitmap, IMAGE_BITMAP, 0, 0, 0);
	if (hbm == NULL)
	{
		hbm = (HBITMAP) LoadImage(NULL,szBitmap,IMAGE_BITMAP, 0, 0, 0);		
	}
	return (hbm);
}

HRESULT CCDirectX::CopyBitmap(IDirectDrawSurface * pdds, HBITMAP hbm, int x, int y, int dx, int dy)
{
HDC hdcImage;
HDC hdc;
BITMAP bm;
DDSURFACEDESC ddsd;
HRESULT hr;

    if (hbm == NULL || pdds == NULL)
	{
        return E_FAIL;
	}

    //
    // Select bitmap into a memoryDC so we can use it.
    //
    hdcImage = CreateCompatibleDC(NULL);
    if (hdcImage==NULL) 
	{        
        return E_FAIL;
    }
    SelectObject(hdcImage, hbm);

    //
    // Get size of the bitmap
    //
    GetObject(hbm, sizeof(bm), &bm);
    dx = dx == 0 ? bm.bmWidth : dx;     // Use the passed size, unless zero
    dy = dy == 0 ? bm.bmHeight : dy;

    //
    // Get size of surface.
    //
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    pdds->GetSurfaceDesc(&ddsd);

    if (SUCCEEDED(pdds->GetDC(&hdc)))
    {
        if (StretchBlt(hdc,0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,dx, dy, SRCCOPY)==false) 
		{
			hr = E_FAIL;
		}
        pdds->ReleaseDC(hdc);
    }

    DeleteDC(hdcImage);
    return hr;
}

struct __BLIT *CCDirectX::LoadBlitObject(HINSTANCE hInstance, LPCTSTR szBitmap,DWORD width,DWORD height)
{
HBITMAP hbm;
BITMAP bm;
DDSURFACEDESC ddsd;
IDirectDrawSurface * pdds;
struct __BLIT *blit;

	if ((blit=new struct __BLIT)==NULL)
	{
		return (NULL);
	}

    //
    // Get a handle to the bitmap.
    //
    hbm = GetBitmapHandle(hInstance,szBitmap);
    if (hbm == NULL) 
	{      
		return NULL;
    }

    //
    // Get size of the bitmap
    //
    GetObject(hbm, sizeof(bm), &bm);

    //
    // Create a DirectDrawSurface for this bitmap
    //
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    ddsd.dwWidth = bm.bmWidth;
    ddsd.dwHeight = bm.bmHeight;
    if (FAILED(lpDirectDraw->CreateSurface(&ddsd, &pdds, NULL)))
	{
        return NULL;
	}

    if (FAILED(CopyBitmap(pdds, hbm, 0, 0, width,height)))
	{
		pdds->Release();
		pdds=NULL;    
    }

    //DeleteObject(hbm);

	blit->image=pdds;
	blit->width=(width==0 ? bm.bmWidth : width);
	blit->height=(height==0 ? bm.bmHeight : height);
	blit->bitmap=hbm;

    return blit;
}

void CCDirectX::FreeBlitObject(struct __BLIT *blit)
{
	if (blit)
	{
		if (blit->bitmap)	DeleteObject(blit->bitmap);
		if (blit->image)	blit->image->Release();
		free(blit);
	}
}

void CCDirectX::setColourKey(DWORD colour)
{
	colourKey.dwColorSpaceHighValue=HIWORD(colour);
	colourKey.dwColorSpaceLowValue=LOWORD(colour);
}

HRESULT CCDirectX::Blit(DWORD x,DWORD y,struct __BLIT *source,DWORD flags)
{
DDBLTFX         ddbltfx;
RECT			pos;
HRESULT			hResult;

	if ((source==NULL) || (source->image==NULL))	return (DDERR_GENERIC);

	pos.top=y;
	pos.left=x;
	pos.right=pos.left+source->width;
	pos.bottom=pos.top+source->height;

	memset(&ddbltfx, 0, sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	memcpy(&ddbltfx.ddckSrcColorkey,&colourKey,sizeof(ddbltfx.ddckSrcColorkey));
	ddbltfx.dwROP = SRCCOPY;

	while (1) {		
		hResult=surfaces[SECONDARY_SURFACE]->Blt(&pos,source->image,NULL,flags,&ddbltfx);

		if (SUCCEEDED(hResult))
		{
			return hResult;
		}

        if(hResult == DDERR_SURFACELOST )
        {
            if (FAILED(restoreLostSurfaces()))
			{
			}
			break;
        }
        if(hResult != DDERR_WASSTILLDRAWING )
        {
            break;
        }
	};

	return hResult;
}

HRESULT CCDirectX::Blit(RECT *pos,struct __BLIT *source,RECT *sourceRect,DWORD flags)
{
DDBLTFX         ddbltfx;
HRESULT			hResult;

	if ((source==NULL) || (source->image==NULL) || (lpDirectDraw==NULL))	return (DDERR_GENERIC);

	while (surfaces[PRIMARY_SURFACE]->GetBltStatus(DDGBS_ISBLTDONE)==DDERR_WASSTILLDRAWING); 
	if (pos->right==0)	pos->right=pos->left+source->width;
	if (pos->bottom==0)	pos->bottom=pos->top+source->height;

	memset(&ddbltfx, 0, sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	memcpy(&ddbltfx.ddckSrcColorkey,&colourKey,sizeof(ddbltfx.ddckSrcColorkey));
	ddbltfx.dwROP = SRCCOPY;

	while (1) {		
		hResult=surfaces[SECONDARY_SURFACE]->Blt(pos,source->image,sourceRect,flags,&ddbltfx);

		if (SUCCEEDED(hResult))
		{
			return hResult;
		}

        if(hResult == DDERR_SURFACELOST )
        {
			if (FAILED(restoreLostSurfaces()))
			{
				break;
			}
			break;
        }
        if(hResult != DDERR_WASSTILLDRAWING )
        {
            break;
        }
	};

	return hResult;
}

HRESULT CCDirectX::restoreLostSurfaces(void)
{
	if (surfaces[PRIMARY_SURFACE]==NULL)	return (DDERR_NOTFOUND);

	return (surfaces[PRIMARY_SURFACE]->Restore());
}

HRESULT CCDirectX::getCaps(void)
{
	if (lpDirectDraw==NULL)	return (DDERR_NOTFOUND);

	return (lpDirectDraw->GetCaps(&m_caps,&m_helCaps));
}

HRESULT CCDirectX::setDisplayMode(DWORD width,DWORD height,DWORD bpp,DWORD refreshRate)
{
HRESULT hRet;

	if (lpDirectDraw==NULL)	return (DDERR_NOTFOUND);

	hRet=lpDirectDraw->SetDisplayMode(width,height,bpp,refreshRate,0);
	if (SUCCEEDED(hRet))
	{
		return (getDisplayMode());	// Update display width, height etc
	}

	return (hRet);
}

DWORD CCDirectX::setDisplayMode(struct __SURFACEINFO *surfaceInfo,struct __SURFACEINFO *store,
							   DWORD *isPortrait,DWORD change)
{
CSetDisplayMode	displayMode;

	if (lpDirectDraw==NULL || surfaceInfo==NULL || store==NULL || isPortrait==false)
	{
		return (false);
	}

	displayMode.initialise(surfaceInfo,store,isPortrait);
	if (displayMode.DoModal()==IDOK)
	{
		if (change)
		{
			// Change the screen mode
			if (SUCCEEDED(setDisplayMode(store->width,store->height,
											store->bpp,store->refreshRate)))
			{
				getDisplayMode();	// Update screen details
				return (true);
			}

			return (false);
		}

		return true;

	}
	return false;
}

void CCDirectX::getOrientation(void)
{
int theScreenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
int theScreenHeight = GetSystemMetrics(SM_CYFULLSCREEN);

	m_usingPortrait=(theScreenWidth > theScreenHeight ? false : true);
}

HRESULT CCDirectX::getDisplayMode(void)
{
DDSURFACEDESC	surfaceDesc;
HRESULT			hRet;

	hRet=lpDirectDraw->GetDisplayMode(&surfaceDesc);
	if (SUCCEEDED(hRet))
	{
		m_displayWidth=surfaceDesc.dwWidth;
		m_displayHeight=surfaceDesc.dwHeight;
		m_refreshRate=surfaceDesc.dwRefreshRate;
		m_bpp=surfaceDesc.ddpfPixelFormat.dwRGBBitCount;
	}
	
	return (hRet);
}

HRESULT CCDirectX::Print(TCHAR *text,DWORD x,DWORD y,HWND hWnd)
{
HDC hDC;
HRESULT hResult;

	hResult=surfaces[SECONDARY_SURFACE]->GetDC(&hDC);
	if (SUCCEEDED(hResult))
	{
//		SetBkColor(hDC, RGB(0, 0, 255));
  //      SetTextColor(hDC, RGB(255, 255, 0));
        //GetClientRect(hWnd, &rc);

		ExtTextOut(hDC,x,y,ETO_OPAQUE,NULL,text,lstrlen(text),NULL);
		surfaces[SECONDARY_SURFACE]->ReleaseDC(hDC);
	}

	return (hResult);
}

and my main game loop looks like :

memset(&msg,(char) NULL,sizeof(msg));
	while (msg.message!=WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) 
		{			
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else
		{					
			directX.CLS(0);				
			state=processDisplay(state,tileWidth,tileHeight,&level,(struct __SETUP *) &setup,hWnd);
			timer.updateTimer();
			directX.flip();	
		}
	}
The only other WM 5 library that I know of is Edgelib. Unfortunately its £500+ a year(!), and whilst there is an evaluation version, it uses pure C++.
__________________
Mobile & PC Stuff at
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.

Be there or be square!

Last edited by MrTAToad; 02-12-06 at 08:56 AM.
MrTAToad is offline   Reply With Quote
Old 02-13-06, 04:37 AM   #6 (permalink)
Aximsite Rookie
 
Join Date: Dec 2005
Location: Chichester
Posts: 32
Thanked 0 Times in 0 Posts
As far as I can tell, there are currently no free game engines, and especially none that use DirectDraw. Unfortunately the only ones that do are for commerical use.

I think its time to see if the source code to my old DX7 Amnesia engine can be found, and start converting that. Hopefully, by that time, I will have worked out how to stop the flickering...
__________________
Mobile & PC Stuff at
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.

Be there or be square!
MrTAToad is offline   Reply With Quote
Old 02-14-06, 05:08 AM   #7 (permalink)
Aximsite Rookie
 
Join Date: Dec 2005
Location: Chichester
Posts: 32
Thanked 0 Times in 0 Posts
I think I've solved most of the flickering problem - the main window processing code needed to be changed somewhat. Unfortunately there is still flickering on the top 100 or so lines.

However, its possible that using SetTimer, with a speed of 1 (and using a guard variable) should be able to sort it, whilst retaining the ability to detect keys & mouse input quickly.

Which leads me to : I've now started my 2D graphics processing library :)
__________________
Mobile & PC Stuff at
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.

Be there or be square!
MrTAToad is offline   Reply With Quote
Reply

Tags
directx, resources, tutorials

Sponsor Ads

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -5. The time now is 03:51 AM.
Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
Copyright © 2003-09 LeckMedia, LLC