Another newbie question :)
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
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:
Hope this helps.
Edited by - Nytegard on July 21, 2000 12:36:52 AM
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
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.
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.
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.
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
Popular Topics
Advertisement