Another newbie question :)

Started by
5 comments, last by brianhj 23 years, 9 months ago
Hey it''s me... what do you expect? I was well on my way to making Quake 4 when I ran into a little problem. I found that article my Andre Lamothe about how to set up DirectX in VC++. And much to my delight, the article was aimed at game development! (what''s the name of this web site again?) Anywho, I was reading the article with renewed hope when I ran smack dab into a wall. DirecX 5. DIRECTX 5. Ouch. I load the source code anyway thinking hell, maybe I''ll get lucky and it will work with DirectX 7. Well, it didn''t. I''ve tried editing the code based on SDK samples, but to no avail. I''m a newbie, mind you, and if anyone here still remembers what it was like to be a newbie in Windows (Walls? Who said that?!) Programming and that someone is willing to help me translate this code into DirectX 7 / VC++ 6 then... well, then help me. I''d just like to get it working like he says it will in the article. Moving blob and all. Here''s the code: http://www.gamedev.net/reference/articles/article589.asp Thank you so much, Brian
Advertisement
The code that was on the page works with DirectX 7. Tested it and it works. What I think you might be believing is wrong is not with DX7, rather the compiler used. It uses several conventions that were popular in VC++5, but have changed in VC++6.

Just remember to include winmm.lib and ddraw.lib in your project.

Project->Settings->Object/library modules.
Only two lines of code you need to change are lines 239 and lines 282.



winclass.hbrBackground = GetStockObject(BLACK_BRUSH);
becomes
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);

EndPaint(hdc,&ps);
becomes
EndPaint(hwnd,&ps);

This should be the working source:

    // LISTING 1.0 - DIRECT X 5.0 GAME CONSOLE ////////////////////////////////////// INCLUDES ///////////////////////////////////////////////////////////////////#define WIN32_LEAN_AND_MEAN // make sure certain headers are included correctly#include <windows.h>  // include the standard windows stuff#include <windowsx.h> // include the 32 bit stuff#include <mmsystem.h> // include the multi media stuff// note you need winmm.lib also#include <ddraw.h>    // include direct draw components#include <stdlib.h>   // include all the good stuff#include <stdio.h>#include <math.h>#include <float.h>// DEFINES ////////////////////////////////////////////////////////////////////#define WINDOW_CLASS_NAME "WINDOW_CLASS" // this is the name of the window class// defines for screen parameters#define SCREEN_WIDTH 640   // the width of the viewing surface#define SCREEN_HEIGHT 480  // the height of the viewing surface#define SCREEN_BPP 8       // the bits per pixel#define MAX_COLORS 256     // the maximum number of colors// TYPES //////////////////////////////////////////////////////////////////////typedef unsigned char UCHAR;// MACROS /////////////////////////////////////////////////////////////////////// these query the keyboard in real-time#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// PROTOTYPES /////////////////////////////////////////////////////////////////int DD_Init(HWND hwnd);int DD_Shutdown(void);int Set_Pal_Entry(int index, int red, int green, int blue);void Game_Init(void);void Game_Main(void);void Game_Shutdown(void);// DIRECTDRAW GLOBALS ////////////////////////////////////////////////////////LPDIRECTDRAW lpdd = NULL;                // dd objectLPDIRECTDRAWSURFACE lpddsprimary = NULL; // dd primary surfaceLPDIRECTDRAWPALETTE lpddpal = NULL;      // a pointer to the created dd palettePALETTEENTRY color_palette[256];         // holds the shadow palette entriesDDSURFACEDESC ddsd;               // a direct draw surface description structDDSCAPS ddscaps;                  // a direct draw surface capabilities structHRESULT ddrval;                   // result back from dd callsHWND main_window_handle = NULL;   // used to store the window handleUCHAR *video_buffer = NULL;       // pointer to video ram// GAME GLOBALS GO HERE ///////////////////////////////////////////////////// // DIRECT X FUNCTIONS /////////////////////////////////////////////////////////int DD_Init(HWND hwnd){    // this function is responsible for initializing direct draw, it creates a    // primary surface 	    int index; // looping index	    // now that the windows portion is complete, start up direct draw    if (DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK)    {        // shutdown any other dd objects and kill window        DD_Shutdown();        return(0);    } // end if	    // now set the coop level to exclusive and set for full screen and mode x    if (lpdd->SetCooperativeLevel(hwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE |        DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX)!=DD_OK)    {        // shutdown any other dd objects and kill window        DD_Shutdown();        return(0);    } // end if	    // now set the display mode    if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP)!=DD_OK)    {        // shutdown any other dd objects and kill window        DD_Shutdown();        return(0);    } // end if	    // Create the primary surface    ddsd.dwSize = sizeof(ddsd);    ddsd.dwFlags = DDSD_CAPS;    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;	    if		(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)    {        // shutdown any other dd objects and kill window        DD_Shutdown();        return(0);    } // end if	    // create the palette and attach it to the primary surface	    // clear all the palette entries to RGB 0,0,0    memset(color_palette,0,256*sizeof(PALETTEENTRY));        // set all of the flags to the correct value    for (index=0; index<256; index++)    {        // create the GRAY/RED/GREEN/BLUE palette, 64 shades of each        if ((index / 64)==0)        {            color_palette[index].peRed = index*4;            color_palette[index].peGreen = index*4;            color_palette[index].peBlue = index*4;        } // end if        else			if ((index / 64)==1)				color_palette[index].peRed = (index%64)*4;			else				if ((index / 64)==2) 					color_palette[index].peGreen = (index%64)*4;				else					if ((index / 64)==3)						color_palette[index].peBlue = (index%64)*4;										// set the no collapse flag					color_palette[index].peFlags = PC_NOCOLLAPSE;					    } // end for index	    // now create the palette object, note that it is a member of the dd object itself    if (lpdd->CreatePalette((DDPCAPS_8BIT | DDPCAPS_INITIALIZE),color_palette,&lpddpal,NULL)!=DD_OK)    {        // shutdown any other dd objects and kill window        DD_Shutdown();        return(0);    } // end if	    // now attach the palette to the primary surface    lpddsprimary->SetPalette(lpddpal);	    // return success if we got this far    return(1);	} // end DD_Init///////////////////////////////////////////////////////////////////////////////int DD_Shutdown(void){    // this function tests for dd components that have been created and releases    // them back to the operating system	    // test if the dd object exists    if (lpdd)    {        // test if there is a primary surface        if(lpddsprimary)        {            // release the memory and set pointer to NULL            lpddsprimary->Release();            lpddsprimary = NULL;        } // end if		        // now release the dd object itself        lpdd->Release();        lpdd = NULL;		        // return success        return(1);		    } // end if    else        return(0);	} // end DD_Shutdown//////////////////////////////////////////////////////////////////////////////int Set_Pal_Entry(int index, int red, int green, int blue){    // this function sets a palette entry with the sent color	    PALETTEENTRY color; // used to build up color	    // set RGB value in structure    color.peRed = (BYTE)red;    color.peGreen = (BYTE)green;    color.peBlue = (BYTE)blue;    color.peFlags = PC_NOCOLLAPSE;	    // set the color palette entry    lpddpal->SetEntries(0,index,1,&color);	    // make copy in shadow palette    memcpy(&color_palette[index],        &color,        sizeof(PALETTEENTRY));	    // return success    return(1);	} // end Set_Pal_Entry// WINDOWS CALLBACK FUNCTION ////////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){    // this is the main message handler of the system	    HDC hdc; // handle to graphics context    PAINTSTRUCT ps; // used to hold the paint info	    // what is the message?	    switch(msg)    {     case WM_CREATE:        {            // do windows inits here            return(0);        } break;		    case WM_PAINT:        {            // this message occurs when your window needs repainting            hdc = BeginPaint(hwnd,&ps);             EndPaint(hwnd,&ps);			            return(0);        } break;		    case WM_DESTROY:        {            // this message is sent when your window is destroyed            PostQuitMessage(0);            return(0);        } break;		    default:break;		    } // end switch	    // let windows process any messages that we didn't take care of     return (DefWindowProc(hwnd, msg, wparam, lparam));	} // end WinProc// WINMAIN ////////////////////////////////////////////////////////////////////int WINAPI WinMain( HINSTANCE hinstance,				   HINSTANCE hprevinstance,				   LPSTR lpcmdline,				   int ncmdshow){    WNDCLASSEX winclass;  // this holds the windows class info    HWND hwnd;            // this holds the handle of our new window    MSG msg;              // this holds a generic message	    // first fill in the window class stucture	    winclass.cbSize = sizeof(WNDCLASSEX);    winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;    winclass.lpfnWndProc = WindowProc;    winclass.cbClsExtra = 0;    winclass.cbWndExtra = 0;    winclass.hInstance = hinstance;    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);    winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);    winclass.hCursor = LoadCursor(NULL, IDC_ARROW);    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);    winclass.lpszMenuName = NULL;    winclass.lpszClassName = WINDOW_CLASS_NAME;	    // register the window class    if (!RegisterClassEx(&winclass))        return(0);	    // create the window    if (!(hwnd = CreateWindowEx(WS_EX_TOPMOST,		WINDOW_CLASS_NAME,      // class		"You can't See This!",  // title		WS_VISIBLE | WS_POPUP,		0,0, // x,y		GetSystemMetrics(SM_CXSCREEN),		GetSystemMetrics(SM_CYSCREEN), 		NULL,           // parent		NULL,           // menu		hinstance,      // instance		NULL)))         // creation parms        return(0);	    // hide the mouse cursor    ShowCursor(0);	    // save the window handle    main_window_handle = hwnd;	    // initialize direct draw    if (!DD_Init(hwnd))    {        DestroyWindow(hwnd);        return(0);    } // end if	    // initialize game    Game_Init();	    // enter main event loop    while(1)    {        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))        {             // test if this is a quit            if (msg.message == WM_QUIT)                break;			            // translate any accelerator keys            TranslateMessage(&msg);			            // send the message to the window proc            DispatchMessage(&msg);        } // end if        else        {            // do asynchronous processing here			            // acquire pointer to video ram, note it is always linear            memset(&ddsd,0,sizeof(ddsd));            ddsd.dwSize = sizeof(ddsd);            lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR,NULL);            video_buffer = (UCHAR *)ddsd.lpSurface;			            // call main logic module            Game_Main();			            // release pointer to video ram            lpddsprimary->Unlock(ddsd.lpSurface);			        } // end else		    } // end while	    // shut down direct draw    DD_Shutdown();	    // shutdown game    Game_Shutdown();	    // return to Windows    return(msg.wParam);					   } // end WinMain				   // HERE ARE OUR GAME CONSOLE FUNCTIONS ///////////////////////////////////////////////////////void Game_Init(void){    // do any initialization here} // end Game_Init/////////////////////////////////////////////////////////////////////////////////////////////void Game_Shutdown(void){    // cleanup and release all resources here} // end Game_Shutdown/////////////////////////////////////////////////////////////////////////////////////////////void Game_Main(void){    // process your game logic and draw next frame    // this function must exit each frame and return back to windows    // also this function is responsible for controlling the frame rate    // therefore, if you want the game to run at 30fps, then the function should    // take 1/30th of a second before returning	    static int px = SCREEN_WIDTH/2,  // position of player		py = SCREEN_HEIGHT/2,		color = 0;                       // color of blob 0..3, gray, red, green, blue	    // on entry video_buffer is valid	    // get input, note how keyboard is accessed with constants "VK_"    // these are defined in "winuser.h" are basically the scan codes    // for letters just use capital ASCII codes	    if (KEY_DOWN(VK_ESCAPE))        PostMessage(main_window_handle,WM_CLOSE,0,0); // this is how you exit you game	    // which way is player moving    if (KEY_DOWN(VK_RIGHT))        if (++px>SCREEN_WIDTH-8) px=8;				if (KEY_DOWN(VK_LEFT))			if (--px<8) px=SCREEN_WIDTH-8;						if (KEY_DOWN(VK_UP))				if (--py<8) py=SCREEN_HEIGHT-8;								if (KEY_DOWN(VK_DOWN))					if (++py>SCREEN_HEIGHT-8) py=8;										// adjust color, notice 					if (KEY_DOWN('C'))					{						if (++color>=4)							color=0;						Sleep(100);					} // end if										// draw graphics					for (int pixels=0; pixels<32; pixels++)						video_buffer[(px-4+rand()%8)+(py-4+rand()%8)*SCREEN_WIDTH] = (color*64)+rand()%64;										// sync time (optional)										// use sleep to slow system down to 70ish fps					Sleep(14); // note that Sleep is extremly inaccurate, IRL you would use something more robust										// return and let windows have some time					} // end Game_Main    

Hope this helps.

Edited by - Nytegard on July 21, 2000 12:36:52 AM
Thanks! *crosses fingers and pushes ctrl+f7"....
ARRRGGG! Why does it always happen to me?!

lIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/H1.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
The unresolved external "_main" indicates that your VC project isn''t a windows app. The "WinMain" in the code from Nytegard indicates that the source IS for a windows app. Try creating a new project and choosing "Win32 Application" as the type.
I can''t just make a C++ source file?
No you can''t just make a c++ source file. You have to tell to Visual C++ that is a win32 application. You seems to have some hard time with that. Do you know how to configure VC properly in order to work with the DirectX libraries and all that stuff?

If you don''t I could give you a crash course on the subject, just page me on ICQ or send an e-mail.

This topic is closed to new replies.

Advertisement