|
我很茫然。build能过,但是run起来的时候,会在Game_Main下的Lock那里中断,并抛出exception:
Unhandled exception at 0x00414115 in T3DEngine.exe :0xC0000005: Access violation reading location 0x00000000
不知道问题出在哪。我用的是Direct9.0c(Feb 2010)的SDK。
求赐教
//engine practice
#define WIN32_LEAN_AND_MEAN //say no to MFC
#define INITGUID //make sure Direct GUID are included
//includes/////////////////////////////
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <conio.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <io.h>
#include <fcntl.h>
#include <ddraw.h> //include direct head
using namespace std;//adding c++ stuffs
//DEFINES/////////////////////////////
//class name
#define WINDOW_CLASS_NAME "WNDCLASS1"
//window size
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8
#define SCREEN_MAX_COLOR 256
//TYPES////////////////////////////////
typedef unsigned char BYTE;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned short WORD;
//MACROS///////////////////////////////
//
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000)? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000)? 0 : 1)
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize = sizeof(ddstruct); }
//GLOBALS//////////////////////////////
HINSTANCE hInstance_app = NULL; //save the app
HWND MainWindowHandle = NULL; //save the main handle
//direct stuff
LPDIRECTDRAW7 lpdd = NULL;//dd object
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;//primary surface
LPDIRECTDRAWSURFACE7 lpddsback = NULL;//back surface
LPDIRECTDRAWPALETTE lpddpal = NULL;//a pointer to the created dd
LPDIRECTDRAWCLIPPER lpddclipper = NULL;//clipper of directdraw
PALETTEENTRY Palette[256]; // color palette
PALETTEENTRY SavePalette[256];
DDSURFACEDESC2 ddsd; //a directdraw description
DDBLTFX ddbltfx; // use to fill
DDSCAPS2 ddscaps2; //a directdraw surface capbility structure
HRESULT ddrval; //result back for dd call
DWORD start_clock_count = 0; // used for timing
//FUNCTIONS///////////////////////////
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;//used into WM_PAINT
HDC hdc;//handle to device context
//what the message is
switch(msg)
{
case WM_CREATE:
{
//do your init here
//return success
return (0);
}break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
//do your paint operation here
EndPaint(hwnd,&ps);
//return success
return (0);
}break;
case WM_DESTROY:
{
//send the WM_QUIT
PostQuitMessage(0);
//return success
return (0);
}break;
default:break;
}//end switch
//return to default windows
return (DefWindowProc(hwnd,msg,wParam,lParam));
}//end winproc
int Game_Main(void *parm = NULL, int NumParms = 0)
{
//Main loop of your game.
if(KEYDOWN(VK_ESCAPE))
SendMessage(MainWindowHandle,WM_CLOSE,0,0);
//return success or failure or your own code
//plot 1000 random pixel to the primary surface and return
//clear ddsd and set size , never assume it's clean
//clear and set the size
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
//lock the work memory
lpddsprimary->Lock(NULL, &ddsd,
DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
NULL);//debug的时候就停在这行,不用debug直接运行的话也是死在这。
//now ddsd.lPitch is valid and so is ddsd.lpsurface
//make a couple aliases to make code cleaner, so we don't have to cast
int mempitch=(int)ddsd.lPitch;
UCHAR *video_buffer=(UCHAR *)ddsd.lpSurface;
//plot 1000 random pixels with random color on the
//primary surface, they will be instantly visible
for(int index = 0; index < 1000; index ++)
{
//select random position and color for 1024x768x8
UCHAR color = rand()%256;
int x = rand()%640;
int y = rand()%480;
//plot the pixel
video_buffer[x+y*mempitch] = color;
}//end for
//so we finish drawing, we can unlock it
if(FAILED(lpddsprimary->Unlock(NULL)))
return (0);
//sleep a bit
Sleep(30);
return (1);
}//end gamemain
int Game_Init(void *parm = NULL, int NumParms = 0)
{
//do the initialize before your game here
//Create DirectDraw
if(FAILED(DirectDrawCreateEx(NULL,(void **)lpdd,IID_IDirectDraw7,NULL)))
return (0);
//set the cooperative level to fullscreen
if(FAILED(lpdd->SetCooperativeLevel(MainWindowHandle,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
//error
return (0);
}
if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)))
{
//error
return (0);
}
//return success or failure or your own code
return (1);
//display picture
//clear the structure
memset(&ddsd,0,sizeof(ddsd));
//so I can fill the struct now
ddsd.dwSize = sizeof(ddsd);
//fill the control part. this valid the caps option
ddsd.dwFlags = DDSD_CAPS;
//fill the caps opton
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
//create the surface
if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)))
return (0);
//
//operation about palette
//fill em up with color!
for(int color = 1; color < 255; color++)
{
Palette[color].peBlue = rand()%256;
Palette[color].peRed = rand()%256;
Palette[color].peGreen = rand()%256;
//set flag filed to PC_NOCOLLAPSE
Palette[color].peFlags = PC_NOCOLLAPSE;
}// end for color
//fill with the start and the end
Palette[0].peBlue = 0;
Palette[0].peRed = 0;
Palette[0].peGreen = 0;
Palette[0].peFlags = PC_NOCOLLAPSE;
Palette[255].peRed = 255;
Palette[255].peBlue = 255;
Palette[255].peGreen =255;
Palette[255].peFlags = PC_NOCOLLAPSE;
//create the palette
if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE,Palette,&lpddpal,NULL)))
return (0);
//select your palette
if(FAILED(lpddsprimary->SetPalette(lpddpal)))
return (0);
//So after create directdraw and set co-work with windows
//What I need to do is setup a palette(remember fill it with
//random.After that create the canvas——surface which we use
//for drawing. And use your surface choose your palette. All
//the initialize work done here(for now)
}//end gameinit
int Game_Shutdown(void *parm = NULL, int NumParms = 0)
{
//do the sweep work after running
//release the used device
if(lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
}
if(lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
}
if(lpdd)
{
lpdd->Release();
lpdd = NULL;
}
//return success or failure or your own code
return (1);
}// end game shutdown
//WINMAIN///////////////////////////
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
WNDCLASSEX wndclass;//announce a window class
HWND hwnd;
MSG msg;
HDC hdc;//handle to device context
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpfnWndProc = WindowProc;
wndclass.lpszClassName = WINDOW_CLASS_NAME;
wndclass.lpszMenuName = "NULL";
wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
//save the hinstance in global
hInstance_app = hInstance;
//register the window
if(!(RegisterClassEx(&wndclass)))
return (0);
//create the window
if(!(hwnd = CreateWindowEx(NULL,
WINDOW_CLASS_NAME,
"T3D Engine",
WS_POPUP | WS_VISIBLE,
0,0,
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL)))
return (0);
//save the window handle
MainWindowHandle = hwnd;
//initialize the game
Game_Init();
//go to message loop
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
//translate the message
TranslateMessage(&msg);
//dispatch the message
DispatchMessage(&msg);
//call GameMain for every frame
Game_Main();
}//end if
}//end while
//shutdown the game
Game_Shutdown();
//return success
return (msg.wParam);
}//end winmain
|
|