Click here to Skip to main content
15,888,155 members
Articles / Multimedia / DirectX

A DirectX Wrapper

Rate me:
Please Sign up or sign in to vote.
4.69/5 (20 votes)
18 Jul 200333 min read 181.1K   4.3K   66  
A DirectX Wrapper
// testwin.cpp : Defines the entry point for the application.
//
/*

  test of dxsmith in a normal, minimal, windows program

  */

#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
HWND				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

CgsdxIO *gb_pDX=NULL;       // main DXSmith I/O object
CSprite *gb_pSprite=NULL;   // main test sprite

// some infomation about the boucing "ball"
typedef struct
    {
    gsdxBitmap_t *ball;
    DWORD soundfire;

    RECT rectBall;
    int x, y, xd, yd, ydd, done;
    int max_x, max_y;
    gsdxEvent_t event;
    HFONT font;
    int frame_count;
    DWORD last_time, elapsed;
    int paused;
    char music[228];
    }
TestInfo_t;

TestInfo_t tt;
TestInfo_t tt2;

// make a TesttInfo_t object "bounce"
int Bouncett(TestInfo_t *tt, CgsdxIO *dx, int sound=0)
{
    tt->x+=tt->xd;
    tt->yd+=tt->ydd;
    tt->y+=tt->yd;

    if ( tt->x < 0 )
        {
        tt->x=0;
        tt->xd=-tt->xd;
        if ( sound )
            dx->PlaySound(tt->soundfire);
        }
    else
        {
        if ( tt->x > tt->max_x )
            {
            tt->x=tt->max_x;
            tt->xd=-tt->xd;
            if ( sound )
                dx->PlaySound(tt->soundfire);
            }
        }

    if ( tt->y < 0 )
        {
        tt->y=0;
        tt->yd=-tt->yd;
        if ( sound )
            dx->PlaySound(tt->soundfire);
        }
    else
        {
        if ( tt->y > tt->max_y )
            {
            tt->y=tt->max_y;
            if ( tt->yd > 0 )
                tt->yd--;     // slow it down
            else
                tt->yd++;
            tt->yd=-tt->yd;
            if ( sound )
                dx->PlaySound(tt->soundfire);
            }
        }

    if ( tt->yd == 0 && tt->y == tt->max_y )
        {
        tt->ydd=4;
        tt->yd=-75;
        }
    return 0;
}

// all the test logic and i/o
int DoTestLogic(CgsdxIO *dx)
{
    gsdxEvent_t event;

    if ( tt.paused )
        return 0;

    dx->GetEvent(&event);
    if ( dx->IsKeyDown(DIK_ESCAPE) )
        tt.done=1;
    else
        {
        Bouncett(&tt, dx, 1);
        Bouncett(&tt2, dx);
        gb_pSprite->AnimateSpriteBank();
        }
    return tt.done;
}

// all the test drawing
int DoTestDraw(CgsdxIO *dx)
{
    int err=0;
    POINT pointBall;
    char temp[128];

    if ( tt.paused )
        return 0;

    dx->RectFill(NULL, 0); // fill screen black

    pointBall.x=tt.x;  // draw the ball
    pointBall.y=tt.y;
    dx->Blit(&pointBall, tt.ball);
    gb_pSprite->DrawSprite(0, tt2.x, tt2.y);
    gb_pSprite->DrawSprite(0, 200, 200);

    // draw some text
    tt.frame_count++;
    if ( tt.frame_count > 100 )
        {
        tt.elapsed=timeGetTime() - tt.last_time;
        tt.last_time=timeGetTime();
        tt.frame_count=0;
        }
    sprintf(temp, "X: %03d Y: %03d frameRate: %04d", tt.x, tt.y, tt.elapsed/10);
    dx->DrawText(tt.font, 1,1, RGB(0,255,0), 0, temp);

    dx->Flip();


    return err;
}

// winmain
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	// TODO: Place code here.
	MSG msg;
    HWND hwnd;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_TESTWIN, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if ( !(hwnd=InitInstance (hInstance, nCmdShow)) ) 
	    {
		return FALSE;
	    }

    /*  as created by vc++
	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
	}
    */

    // full screen
    WINDOWPLACEMENT info;

    memset(&info, 0, sizeof(info));
    info.length=sizeof(info);
    GetWindowPlacement(hwnd, &info);
    info.showCmd=SW_SHOWMAXIMIZED;
    SetWindowPlacement(hwnd, &info);

    // dx
    CgsdxIO dx;
    int count=0;

    if ( dx.InitResource(0) )
        return 1;
    if ( dx.InitGraphics(1024, 768, 32, GSDX_FULL_SCREEN, hInstance, hwnd) )
        return 2;
    if ( dx.InitSound(0) )
        return 3;
    if ( dx.InitIO() )
        return 4;

    // init the global pointer to the dx object
    gb_pDX=&dx;
    CSprite sprite(&dx);
    gb_pSprite=&sprite;
    gb_pSprite->LoadSpriteBank("pryamid.spr");

    // load bitmaps
    tt.done=0;
    TRACE("[winmain] load bitmaps\n");
    ZeroMemory(&tt.rectBall, sizeof(RECT));
    if ( !(tt.ball=dx.LoadBitmap("ball1.bmp", &tt.rectBall)) )
	    return 5;

    // load sounds, and music (midi)
    dx.LoadSound("fire.wav", &tt.soundfire);
    strcpy(tt.music, "Meteor Blast 4.mid");
    dx.PlayMusic(tt.music, 1);

    //init the balls
    tt.max_x=1024 - tt.rectBall.right;
    tt.max_y=768 - tt.rectBall.bottom;
    tt.x=1024 / 2;
    tt.y=30;
    tt.xd=15;
    tt.yd=0;
    tt.ydd=2;
    tt.font=dx.CreateFont(24, FW_MEDIUM, 0, 1);
    // last_time=GetTickCount();
    tt.last_time=timeGetTime();
    tt.elapsed=0;
    tt.frame_count=0;

    tt2.max_x=1024 - 300;
    tt2.max_y=768 - 300;
    tt2.x=1024 / 2;
    tt2.y=30;
    tt2.xd=15;
    tt2.yd=0;
    tt2.ydd=2;
    tt2.font=NULL;

    // prime the message structure
    PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE);
    ShowCursor(FALSE);

    // run till completed in a loop
    while ( msg.message!=WM_QUIT ) 
        {
        // is there a message to process?
        if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE) ) 
            {
            // dispatch the message via windows calls
            TranslateMessage(&msg);
            DispatchMessage(&msg); 
            } 
        else 
            {
            // no windows message to handle, do our test code
            if ( !DoTestLogic(&dx) )
                DoTestDraw(&dx);
            else
                break;
            }

        }

    // clean up
    if ( tt.ball )
        delete tt.ball;

    ShowCursor(TRUE);

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_TESTWIN);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= (LPCSTR)IDC_TESTWIN;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return NULL;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return hWnd;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
    WORD fActive, fMinimized;

	switch (message) 
	{
		case WM_COMMAND:
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   break;
				case IDM_EXIT:
				   DestroyWindow(hWnd);
				   break;
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			// TODO: Add any drawing code here...
			RECT rt;
			GetClientRect(hWnd, &rt);
			DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
			EndPaint(hWnd, &ps);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;

        case WM_ACTIVATE:
            fActive = LOWORD(wParam);           // activation flag 
            fMinimized = (BOOL) HIWORD(wParam); // minimized flag 
            TRACE("[WndProc] active= %d\n", fActive);
            if ( fActive )
                {
                // un-pause
                tt.paused=0;
                if ( gb_pDX )
                    {
                    gb_pDX->AcquireAllDevices();
                    gb_pDX->PlayMusic(tt.music, 1); // start the music
                    }
                }
            else
                {
                // pause the game
                if ( gb_pDX )
                    {
                    gb_pDX->PlayMusic(NULL, 0); // NULL = stop music
                    }
                tt.paused=1;
                }
            // note, falling thru to default action

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Canada Canada
Professional Programmer living in Beautiful Vancouver, BC, Canada.

Comments and Discussions