home *** CD-ROM | disk | FTP | other *** search
Wrap
/*========================================================================== * * Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved. * * File: viewer.cpp * ***************************************************************************/ #define INITGUID #include "d3drmwin.h" #include "viewer.h" #include <windows.h> #include <stdio.h> #include <string.h> #include <malloc.h> #include <math.h> #include <direct.h> #include "sel.h" static char ViewerClass[32] = "ViewerClass"; static BOOL Render(void); HRESULT loadTextures(char *name, void *arg, LPDIRECT3DRMTEXTURE *tex); typedef struct _AppInfo { LPDIRECT3DRMFRAME scene, camera; LPDIRECT3DRMDEVICE dev; LPDIRECT3DRMVIEWPORT view; D3DRMCOLORMODEL model; BOOL bMinimized; } AppInfo; AppInfo *active_window = NULL; LPDIRECT3DRM lpD3DRM = 0; LPDIRECTDRAWCLIPPER lpDDClipper = 0; BOOL bQuit = FALSE; static BOOL FirstInstance(HINSTANCE); static BOOL AnyInstance(HINSTANCE, int); long FAR PASCAL WindowProc(HWND, UINT, WPARAM, LPARAM); static BOOL CreateDevice(HWND, AppInfo*); static void Idle(); char* MyErrorToString(HRESULT error); /* Msg * Message output for error notification. */ void __cdecl Msg( LPSTR fmt, ... ) { char buff[256]; wvsprintf(buff, fmt, (char *)(&fmt+1)); lstrcat(buff, "\r\n"); MessageBox( NULL, buff, "Viewer Message", MB_OK ); } char* LSTRRCHR( const char* lpString, int bChar ) { if( lpString != NULL ) { const char* lpBegin; lpBegin = lpString; while( *lpString != 0 ) { lpString++; } while( 1 ) { if( *lpString == bChar ) { return (char*)lpString; } if( lpString == lpBegin ) { break; } lpString--; } } return NULL; } /* LSTRRCHR */ /* * Initialization, message loop */ int PASCAL WinMain (HINSTANCE this_inst, HINSTANCE prev_inst, LPSTR cmdline, int cmdshow) { MSG msg; int idle; int done = FALSE; HACCEL accel; HRESULT rval; prev_inst = prev_inst; cmdline = cmdline; rval = Direct3DRMCreate(&lpD3DRM); if (rval != D3DRM_OK) { Msg("Failed to create Direct3DRM.\n%s", MyErrorToString(rval)); return 1; } if (!prev_inst) if (!FirstInstance(this_inst)) return 1; if (!AnyInstance(this_inst, cmdshow)) return 1; accel = LoadAccelerators(this_inst, "ViewerAccel"); while (!done) { idle = TRUE; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { idle = FALSE; if (msg.message == WM_QUIT) { done = TRUE; break; } if (!TranslateAccelerator(msg.hwnd, accel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } if (!active_window->bMinimized && !bQuit) { if (idle) Idle(); if (!Render()) { Msg("Rendering failed.\n"); done = TRUE; break; } } } RELEASE(active_window->scene); RELEASE(active_window->camera); RELEASE(active_window->view); RELEASE(active_window->dev); ClearClipboard(); RELEASE(lpD3DRM); RELEASE(lpDDClipper); return msg.wParam; } /* * Register window class for the application, and do any other * application initialization */ static BOOL FirstInstance(HINSTANCE this_inst) { WNDCLASS wc; BOOL rc; /* * set up and register window class */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(DWORD); wc.hInstance = this_inst; wc.hIcon = LoadIcon(this_inst, "ViewerIcon"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "ViewerMenu"; wc.lpszClassName = ViewerClass; rc = RegisterClass(&wc); return rc; } /* * Do work required for every instance of the application: * create the window, initialize data */ static BOOL AnyInstance(HINSTANCE this_inst, int cmdshow) { HWND win; AppInfo *info; /* * create main window */ win = CreateWindow ( ViewerClass, /* class */ "Direct3D Object Viewer",/* caption */ WS_OVERLAPPEDWINDOW, /* style */ CW_USEDEFAULT, /* init. x pos */ CW_USEDEFAULT, /* init. y pos */ 400, /* init. x size */ 400, /* init. y size */ NULL, /* parent window */ NULL, /* menu handle */ this_inst, /* program handle */ NULL /* create parms */ ); if (!win) return FALSE; /* * Create a clipper for this window */ if (FAILED(DirectDrawCreateClipper(0, &lpDDClipper, NULL))) { return FALSE; } if (FAILED(lpDDClipper->SetHWnd(0, win))) { RELEASE(lpDDClipper); return FALSE; } /* * set up data associated with this window */ info = (AppInfo*) malloc(sizeof(AppInfo)); SetWindowLong(win, 0, (long) info); info->model = D3DCOLOR_MONO; if (!CreateDevice(win, info)) { return FALSE; } /* * display window */ ShowWindow(win, cmdshow); UpdateWindow(win); return TRUE; } /* * Processes messages for the about dialog. */ BOOL FAR PASCAL AboutDlgProc (HWND win, unsigned msg, WORD wparam, LONG lparam) { lparam = lparam; switch (msg) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: if (wparam == IDOK) { EndDialog(win, TRUE); return TRUE; } break; } return FALSE; } /* * Create a simple scene. */ static BOOL CreateScene(AppInfo* info) { LPDIRECT3DRMFRAME frame = NULL; LPDIRECT3DRMFRAME light = NULL; LPDIRECT3DRMMESHBUILDER builder = NULL; LPDIRECT3DRMLIGHT light1 = NULL; LPDIRECT3DRMLIGHT light2 = NULL; LPDIRECT3DRMMATERIAL mat = NULL; HRESULT rval; if (FAILED(lpD3DRM->CreateFrame(NULL, &info->scene))) goto generic_error; if (FAILED(lpD3DRM->CreateLightRGB(D3DRMLIGHT_DIRECTIONAL, D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0), &light1))) goto generic_error; if (FAILED(lpD3DRM->CreateLightRGB(D3DRMLIGHT_AMBIENT, D3DVAL(0.1), D3DVAL(0.1), D3DVAL(0.1), &light2))) goto generic_error; if (FAILED(lpD3DRM->CreateFrame(info->scene, &light))) goto generic_error; if (FAILED(light->SetPosition(info->scene, D3DVAL(2.0), D3DVAL(2.0), D3DVAL(5.0)))) goto generic_error; if (FAILED(light->SetOrientation(info->scene, D3DVAL(-1.0), D3DVAL(-1.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0)))) goto generic_error; if (FAILED(light->AddLight(light1))) goto generic_error; RELEASE(light1); if (FAILED(info->scene->AddLight(light2))) goto generic_error; RELEASE(light2); if (FAILED(lpD3DRM->CreateMeshBuilder(&builder))) goto generic_error; rval = builder->Load("camera.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL); if (rval != D3DRM_OK) { Msg("Failed to load camera.x.\n%s", MyErrorToString(rval)); goto ret_with_error; } if (FAILED(builder->SetQuality(D3DRMRENDER_UNLITFLAT))) goto generic_error; if (FAILED(light->AddVisual(builder))) goto generic_error; RELEASE(builder); RELEASE(light); if (FAILED(lpD3DRM->CreateFrame(info->scene, &frame))) goto generic_error; if (FAILED(frame->SetRotation(info->scene, D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(-0.02)))) goto generic_error; if (FAILED(frame->SetPosition(info->scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(10.0)))) goto generic_error; if (FAILED(lpD3DRM->CreateMeshBuilder(&builder))) goto generic_error; rval = builder->Load("mslogo.x", NULL, D3DRMLOAD_FROMFILE, loadTextures, NULL); if (rval != D3DRM_OK) { Msg("Failed to load mslogo.x.\n%s", MyErrorToString(rval)); goto ret_with_error; } if (FAILED(builder->SetColorRGB(D3DVAL(0.8), D3DVAL(0.8), D3DVAL(0.8)))) goto generic_error; if (FAILED(lpD3DRM->CreateMaterial(D3DVAL(10.0), &mat))) goto generic_error; if (FAILED(builder->SetMaterial(mat))) goto generic_error; RELEASE(mat); if (FAILED(frame->AddVisual(builder))) goto generic_error; RELEASE(builder); RELEASE(frame); if (FAILED(lpD3DRM->CreateFrame(info->scene, &info->camera))) goto generic_error; if (FAILED(info->camera->SetPosition(info->scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0)))) goto generic_error; return TRUE; generic_error: Msg("A failure occurred while creating the scene.\n"); ret_with_error: RELEASE(frame); RELEASE(light); RELEASE(builder); RELEASE(light1); RELEASE(light2); RELEASE(mat); return FALSE; } static DWORD bppToddbd(int bpp) { switch(bpp) { case 1: return DDBD_1; case 2: return DDBD_2; case 4: return DDBD_4; case 8: return DDBD_8; case 16: return DDBD_16; case 24: return DDBD_24; case 32: return DDBD_32; } return 0; } /* * Find a device, preferably hardware, for a particular color model. */ LPGUID FindDevice(D3DCOLORMODEL cm) { LPDIRECTDRAW lpDD; LPDIRECT3D lpD3D; D3DFINDDEVICESEARCH search; static D3DFINDDEVICERESULT result; HRESULT error; HDC hdc; int bpp; hdc = GetDC(NULL); bpp = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(NULL, hdc); if (DirectDrawCreate(NULL, &lpDD, NULL)) return NULL; if (lpDD->QueryInterface(IID_IDirect3D, (void**) &lpD3D)) { lpDD->Release(); return NULL; } memset(&search, 0, sizeof search); search.dwSize = sizeof search; search.dwFlags = D3DFDS_COLORMODEL; search.dcmColorModel = (cm == D3DCOLOR_MONO) ? D3DCOLOR_MONO : D3DCOLOR_RGB; memset(&result, 0, sizeof result); result.dwSize = sizeof result; error = lpD3D->FindDevice(&search, &result); if (error == DD_OK) { /* * If the device found is hardware but cannot support the current * bit depth, then fall back to software rendering. */ if (result.ddHwDesc.dwFlags && !(result.ddHwDesc.dwDeviceRenderBitDepth & bppToddbd(bpp))) { search.dwFlags |= D3DFDS_HARDWARE; search.bHardware = FALSE; memset(&result, 0, sizeof result); result.dwSize = sizeof result; error = lpD3D->FindDevice(&search, &result); } } lpD3D->Release(); lpDD->Release(); if (error) return NULL; else return &result.guid; } /* * Create the device and viewport. */ static BOOL CreateDevice(HWND win, AppInfo* info) { RECT r; int bpp; HDC hdc; GetClientRect(win, &r); if (FAILED(lpD3DRM->CreateDeviceFromClipper(lpDDClipper, FindDevice(info->model), r.right, r.bottom, &info->dev))) goto generic_error; hdc = GetDC(win); bpp = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(win, hdc); switch (bpp) { case 1: if (FAILED(info->dev->SetShades(4))) goto generic_error; if (FAILED(lpD3DRM->SetDefaultTextureShades(4))) goto generic_error; break; case 16: if (FAILED(info->dev->SetShades(32))) goto generic_error; if (FAILED(lpD3DRM->SetDefaultTextureColors(64))) goto generic_error; if (FAILED(lpD3DRM->SetDefaultTextureShades(32))) goto generic_error; if (FAILED(info->dev->SetDither(FALSE))) goto generic_error; break; case 24: case 32: if (FAILED(info->dev->SetShades(256))) goto generic_error; if (FAILED(lpD3DRM->SetDefaultTextureColors(64))) goto generic_error; if (FAILED(lpD3DRM->SetDefaultTextureShades(256))) goto generic_error; if (FAILED(info->dev->SetDither(FALSE))) goto generic_error; break; default: if (FAILED(info->dev->SetDither(FALSE))) goto generic_error; } if (!CreateScene(info)) goto ret_with_error; if (FAILED(lpD3DRM->CreateViewport(info->dev, info->camera, 0, 0, info->dev->GetWidth(), info->dev->GetHeight(), &info->view))) goto generic_error; if (FAILED(info->view->SetBack(D3DVAL(5000.0)))) goto generic_error; return TRUE; generic_error: Msg("An error occurred while creating the device.\n"); ret_with_error: return FALSE; } /* * Regenerate the device if the color model changes or the window size * changes. */ static BOOL RebuildDevice(HWND win, AppInfo* info, int width, int height) { HRESULT rval; int old_dither = info->dev->GetDither(); D3DRMRENDERQUALITY old_quality = info->dev->GetQuality(); int old_shades = info->dev->GetShades(); RELEASE(info->view); RELEASE(info->dev); rval = lpD3DRM->CreateDeviceFromClipper(lpDDClipper, FindDevice(info->model), width, height, &info->dev); if (rval != D3DRM_OK) { Msg("Creating a device from HWND failed while rebuilding device.\n%s", MyErrorToString(rval)); return FALSE; } if (FAILED(info->dev->SetDither(old_dither))) goto generic_error; if (FAILED(info->dev->SetQuality(old_quality))) goto generic_error; if (FAILED(info->dev->SetShades(old_shades))) goto generic_error; width = info->dev->GetWidth(); height = info->dev->GetHeight(); if (FAILED(lpD3DRM->CreateViewport(info->dev, info->camera, 0, 0, width, height, &info->view))) goto generic_error; if (FAILED(info->view->SetBack(D3DVAL(400.0)))) goto generic_error; return TRUE; generic_error: Msg("A failure occurred while rebuilding the device.\n"); return FALSE; } /* * Resize the viewport and device when the window size changes. */ static BOOL ResizeViewport(HWND win, AppInfo* info, int width, int height) { int view_width = info->view->GetWidth(); int view_height = info->view->GetHeight(); int dev_width = info->dev->GetWidth(); int dev_height = info->dev->GetHeight(); if (view_width == width && view_height == height) return TRUE; if (width <= dev_width && height <= dev_height) { RELEASE(info->view); if (FAILED(lpD3DRM->CreateViewport(info->dev, info->camera, 0, 0, width, height, &info->view))) goto generic_error; if (FAILED(info->view->SetBack(D3DVAL(400.0)))) goto generic_error; } if (!RebuildDevice(win, info, width, height)) return FALSE; return TRUE; generic_error: Msg("A failure occurred while resizing the viewport.\n"); return FALSE; } /* * Place an object in front of the camera. */ static BOOL PlaceMesh(LPDIRECT3DRMMESHBUILDER mesh, AppInfo *info) { LPDIRECT3DRMFRAME frame; if (FAILED(lpD3DRM->CreateFrame(info->scene, &frame))) return FALSE; if (FAILED(frame->AddVisual(mesh))) return FALSE; if (FAILED(frame->SetPosition(info->camera, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(15.0)))) return FALSE; frame->Release(); return TRUE; } static BOOL ScaleScene(LPDIRECT3DRMFRAME frame, AppInfo *info) { /* Some trickery form the RL2 viewer to scale a scene down to managable proportions */ LPDIRECT3DRMMESHBUILDER mbuilder; D3DRMBOX box; D3DVALUE maxDim; lpD3DRM->CreateMeshBuilder(&mbuilder); mbuilder->AddFrame(frame); mbuilder->GetBox(&box); mbuilder->Release(); maxDim = box.max.x - box.min.x; if (box.max.y - box.min.y > maxDim) maxDim = box.max.y - box.min.y; if (box.max.z - box.min.z > maxDim) maxDim = box.max.z - box.min.z; frame->AddScale(D3DRMCOMBINE_BEFORE, D3DDivide(D3DVAL(8.0), maxDim), D3DDivide(D3DVAL(8.0), maxDim), D3DDivide(D3DVAL(8.0), maxDim)); frame->SetPosition(info->scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(15.0)); return TRUE; } typedef struct { LPDIRECT3DRMANIMATIONSET animset; D3DVALUE time; } animationCallbackArgs; static void animationCallback(LPDIRECT3DRMFRAME obj, void* arg, D3DVALUE delta) { animationCallbackArgs* cb = (animationCallbackArgs *) arg; obj = obj; cb->animset->SetTime(cb->time); cb->time += delta; } static BOOL setAnimationCallback(LPDIRECT3DRMFRAME frame, LPDIRECT3DRMANIMATIONSET animset) { animationCallbackArgs *cb; cb = (animationCallbackArgs*)malloc(sizeof(animationCallbackArgs)); if (!cb) return FALSE; cb->animset = animset; cb->time = D3DVAL(0); if (FAILED(frame->AddMoveCallback(animationCallback, (void *) cb))) return FALSE; return TRUE; } static BOOL LoadAnimationSet(const char *filename, AppInfo *info) { LPDIRECT3DRMANIMATIONSET lpAnimSet; LPDIRECT3DRMFRAME lpFrame; /* Create a new parent frame for the animation, load it, and set up the callback */ if (FAILED(lpD3DRM->CreateFrame(info->scene, &lpFrame))) return FALSE; if (FAILED(lpD3DRM->CreateAnimationSet(&lpAnimSet))) return FALSE; if (FAILED(lpAnimSet->Load((LPVOID)filename, NULL, D3DRMLOAD_FROMFILE, loadTextures, NULL, lpFrame))) return FALSE; ScaleScene(lpFrame, info); setAnimationCallback(lpFrame, lpAnimSet); return TRUE; } static BOOL LoadFrameHierarchy(const char *filename, AppInfo *info) { LPDIRECT3DRMFRAME lpFrame; if (FAILED(lpD3DRM->CreateFrame(info->scene, &lpFrame))) return FALSE; if (FAILED(lpFrame->Load((LPVOID)filename, NULL, D3DRMLOAD_FROMFILE, loadTextures, NULL))) return FALSE; ScaleScene(lpFrame, info); return TRUE; } static int left_drag = FALSE, right_drag = FALSE, last_x, last_y; /* * Render the scene into the viewport. */ static BOOL Render() { if (FAILED(active_window->scene->Move(D3DVAL(1.0)))) return FALSE; if (FAILED(active_window->view->Clear())) return FALSE; if (FAILED(active_window->view->Render(active_window->scene))) return FALSE; if (FAILED(active_window->dev->Update())) return FALSE; return TRUE; } static void Idle() { LPDIRECT3DRMFRAME selected = SelectedFrame(); if (active_window == NULL) return; if (left_drag && selected) selected->SetRotation(active_window->scene, D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0)); if (right_drag && selected) selected->SetVelocity(active_window->scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), FALSE); } static int FillModeToMenuItem(D3DRMFILLMODE fm) { switch (fm) { case D3DRMFILL_POINTS: return 2; case D3DRMFILL_WIREFRAME: return 3; case D3DRMFILL_SOLID: return 4; } return -1; } static int ShadeModeToMenuItem(D3DRMSHADEMODE sm) { switch (sm) { case D3DRMSHADE_FLAT: return 6; case D3DRMSHADE_GOURAUD: return 7; case D3DRMSHADE_PHONG: return 8; } return -1; } static BOOL ToggleLighting(HWND win, AppInfo* info) { HMENU menu; D3DRMRENDERQUALITY quality = info->dev->GetQuality(); D3DRMLIGHTMODE mode = (D3DRMLIGHTMODE)(quality & D3DRMLIGHT_MASK); HRESULT rval; if (mode == D3DRMLIGHT_ON) mode = D3DRMLIGHT_OFF; else mode = D3DRMLIGHT_ON; menu = GetMenu(win); menu = GetSubMenu(menu, 2); CheckMenuItem(menu, 0, (MF_BYPOSITION | (mode == D3DRMLIGHT_ON ? MF_CHECKED : MF_UNCHECKED))); quality = (quality & ~D3DRMLIGHT_MASK) | mode; rval = info->dev->SetQuality(quality); if (rval != D3DRM_OK) { Msg("Setting the render quality while toggling lighting failed.\n%s", MyErrorToString(rval)); return FALSE; } return TRUE; } static BOOL SetFillMode(HWND win, AppInfo* info, D3DRMFILLMODE fm) { HMENU menu; D3DRMRENDERQUALITY quality = info->dev->GetQuality(); D3DRMFILLMODE oldfm = (D3DRMFILLMODE)(quality & D3DRMFILL_MASK); HRESULT rval; menu = GetMenu(win); menu = GetSubMenu(menu, 2); CheckMenuItem(menu, FillModeToMenuItem(oldfm), MF_BYPOSITION|MF_UNCHECKED); CheckMenuItem(menu, FillModeToMenuItem(fm), MF_BYPOSITION|MF_CHECKED); quality = (quality & ~D3DRMFILL_MASK) | fm; rval = info->dev->SetQuality(quality); if (rval != D3DRM_OK) { Msg("Setting the render quality while changing the fill mode failed.\n%s", MyErrorToString(rval)); return FALSE; } return TRUE; } static BOOL SetShadeMode(HWND win, AppInfo* info, D3DRMSHADEMODE sm) { HMENU menu; D3DRMRENDERQUALITY quality = info->dev->GetQuality(); D3DRMSHADEMODE oldsm = (D3DRMSHADEMODE)(quality & D3DRMSHADE_MASK); HRESULT rval; menu = GetMenu(win); menu = GetSubMenu(menu, 2); CheckMenuItem(menu, ShadeModeToMenuItem(oldsm), MF_BYPOSITION|MF_UNCHECKED); CheckMenuItem(menu, ShadeModeToMenuItem(sm), MF_BYPOSITION|MF_CHECKED); quality = (quality & ~D3DRMSHADE_MASK) | sm; rval = info->dev->SetQuality(quality); if (rval != D3DRM_OK) { Msg("Setting the render quality while changing the shade mode failed.\n%s", MyErrorToString(rval)); return FALSE; } return TRUE; } static BOOL SetModel(HWND win, AppInfo* info, D3DRMCOLORMODEL model) { HMENU menu; D3DRMCOLORMODEL oldModel = info->model; if (oldModel == model) return TRUE; info->model = model; if (!RebuildDevice(win, info, info->dev->GetWidth(), info->dev->GetHeight())) return FALSE; menu = GetMenu(win); menu = GetSubMenu(menu, 2); CheckMenuItem(menu, 9 + (int) oldModel, MF_BYPOSITION|MF_UNCHECKED); CheckMenuItem(menu, 9 + (int) model, MF_BYPOSITION|MF_CHECKED); return TRUE; } static BOOL ToggleDither(HWND win, AppInfo *info) { HMENU menu; int dither = info->dev->GetDither(); int checked; dither = !dither; if (FAILED(info->dev->SetDither(dither))) { Msg("Toggling dithering failed.\n"); return FALSE; } menu = GetMenu(win); menu = GetSubMenu(menu, 2); if (dither) checked = MF_CHECKED; else checked = MF_UNCHECKED; //CheckMenuItem(menu, MENU_DITHER, MF_BYCOMMAND|checked); CheckMenuItem(menu, 13, MF_BYPOSITION|checked); return TRUE; } static BOOL ToggleTextureFiltering(HWND win, AppInfo *info) { HMENU menu; D3DRMTEXTUREQUALITY tq = info->dev->GetTextureQuality(); int checked; if (tq == D3DRMTEXTURE_NEAREST) tq = D3DRMTEXTURE_LINEAR; else tq = D3DRMTEXTURE_NEAREST; if (FAILED(info->dev->SetTextureQuality(tq))) { Msg("Setting texture quality failed.\n"); return FALSE; } menu = GetMenu(win); menu = GetSubMenu(menu, 2); if (tq == D3DRMTEXTURE_LINEAR) checked = MF_CHECKED; else checked = MF_UNCHECKED; CheckMenuItem(menu, 14, MF_BYPOSITION|checked); return TRUE; } static BOOL CreateLight(WPARAM wparam, AppInfo* info) { LPDIRECT3DRMMESHBUILDER builder = NULL; LPDIRECT3DRMLIGHT light = NULL; LPDIRECT3DRMFRAME frame = NULL; HRESULT rval; if (FAILED(lpD3DRM->CreateMeshBuilder(&builder))) goto generic_error; if (wparam == MENU_LIGHT_DIRECTIONAL) { rval = builder->Load("camera.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL); if (rval != D3DRM_OK) { Msg("Failed to load camera.x.\n%s", MyErrorToString(rval)); goto ret_with_error; } if (FAILED(builder->SetQuality(D3DRMRENDER_UNLITFLAT))) goto generic_error; if (FAILED(lpD3DRM->CreateLightRGB (D3DRMLIGHT_DIRECTIONAL, D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0), &light))) goto generic_error; } else if (wparam == MENU_LIGHT_PARALLEL_POINT) { rval = builder->Load("sphere2.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL); if (rval != D3DRM_OK) { Msg("Failed to load sphere2.x.\n%s", MyErrorToString(rval)); goto ret_with_error; } if (FAILED(builder->SetQuality(D3DRMRENDER_UNLITFLAT))) goto generic_error; if (FAILED(builder->Scale(D3DVAL(0.2), D3DVAL(0.2), D3DVAL(0.2)))) goto generic_error; if (FAILED(lpD3DRM->CreateLightRGB (D3DRMLIGHT_PARALLELPOINT, D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0), &light))) goto generic_error; } else if (wparam == MENU_LIGHT_POINT) { rval = builder->Load("sphere2.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL); if (rval != D3DRM_OK) { Msg("Failed to load sphere2.x.\n%s", MyErrorToString(rval)); goto ret_with_error; } if (FAILED(builder->SetQuality(D3DRMRENDER_UNLITFLAT))) goto generic_error; if (FAILED(builder->Scale(D3DVAL(0.2), D3DVAL(0.2), D3DVAL(0.2)))) goto generic_error; if (FAILED(lpD3DRM->CreateLightRGB (D3DRMLIGHT_POINT, D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0), &light))) goto generic_error; } else if (wparam == MENU_LIGHT_SPOT) { rval = builder->Load("camera.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL); if (rval != D3DRM_OK) { Msg("Failed to load camera.x.\n%s", MyErrorToString(rval)); goto ret_with_error; } if (FAILED(builder->SetQuality(D3DRMRENDER_UNLITFLAT))) goto generic_error; if (FAILED(lpD3DRM->CreateLightRGB(D3DRMLIGHT_SPOT, D3DVAL(1.0), D3DVAL(1.0), D3DVAL(1.0), &light))) goto generic_error; } if (FAILED(lpD3DRM->CreateFrame(info->scene, &frame))) goto generic_error; if (FAILED(frame->SetPosition(info->camera, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(10.0)))) goto generic_error; if (FAILED(frame->AddVisual(builder))) goto generic_error; if (FAILED(frame->AddLight(light))) goto generic_error; builder->Release(), frame->Release(), light->Release(); return TRUE; generic_error: Msg("A failure occurred while creating a new light.\n"); ret_with_error: RELEASE(builder); RELEASE(light); RELEASE(frame); return FALSE; } HRESULT loadTextures(char *name, void *arg, LPDIRECT3DRMTEXTURE *tex) { char* ext = LSTRRCHR(name, (int)'.'); if (ext && !lstrcmpi(ext, ".ppm")) return lpD3DRM->LoadTexture(name, tex); else return -1; } #define SIGN_EXTEND(w) ((((int)(w)) << 16) >> 16) /* * Handle messages for the main application window */ LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam) { static HCURSOR oldCursor = NULL; AppInfo *info; LPDIRECT3DRMFRAME sFrame = SelectedFrame(); LPDIRECT3DRMMESHBUILDER sVisual = SelectedVisual(); info = (AppInfo *) GetWindowLong(win, 0); active_window = info; switch (msg) { case WM_KEYDOWN: { D3DVECTOR dir, up, right; info->camera->GetOrientation(info->scene, &dir, &up); D3DRMVectorCrossProduct(&right, &up, &dir); up.x /= D3DVAL(4.0); up.y /= D3DVAL(4.0); up.z /= D3DVAL(4.0); right.x /= D3DVAL(4.0); right.y /= D3DVAL(4.0); right.z /= D3DVAL(4.0); switch (wparam) { case 'T': info->camera->SetVelocity(info->scene, dir.x, dir.y, dir.z, FALSE); break; case 'Y': info->camera->SetVelocity(info->scene, D3DVAL(-100.0) * dir.x, D3DVAL(-100.0) * dir.y, D3DVAL(-100.0) * dir.z, FALSE); case 'R': info->camera->SetVelocity(info->scene, -dir.x, -dir.y, -dir.z, FALSE); break; case 'E': info->camera->SetVelocity(info->scene, D3DVAL(100.0) * dir.x, D3DVAL(100.0) * dir.y, D3DVAL(100.0) * dir.z, FALSE); case VK_UP: info->camera->SetVelocity(info->scene, up.x, up.y, up.z, FALSE); break; case VK_DOWN: info->camera->SetVelocity(info->scene, -up.x, -up.y, -up.z, FALSE); break; case VK_RIGHT: info->camera->SetVelocity(info->scene, right.x, right.y, right.z, FALSE); break; case VK_LEFT: info->camera->SetVelocity(info->scene, -right.x, -right.y, -right.z, FALSE); break; case 'X': if (sFrame) sFrame->SetVelocity(info->scene, dir.x, dir.y, dir.z, FALSE); break; case 'Z': if (sFrame) sFrame->SetVelocity(info->scene, -dir.x, -dir.y, -dir.z, FALSE); break; case VK_SUBTRACT: if (sFrame) { sVisual->Scale(D3DVAL(0.9), D3DVAL(0.9), D3DVAL(0.9)); SelectVisual(sVisual, sFrame); } break; case VK_ADD: if (sFrame) { sVisual->Scale(D3DVAL(1.1), D3DVAL(1.1), D3DVAL(1.1)); SelectVisual(sVisual, sFrame); } break; } } break; case WM_KEYUP: switch (wparam) { case 'T': case 'R': case VK_UP: case VK_DOWN: case VK_LEFT: case VK_RIGHT: info->camera->SetVelocity(info->scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), FALSE); break; case 'Z': case 'X': if (sFrame) sFrame->SetVelocity(info->scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0), FALSE); break; } break; case WM_LBUTTONDOWN: { HCURSOR hCur; int x = LOWORD(lparam); int y = HIWORD(lparam); last_x = x; last_y = y; FindAndSelectVisual(info->view, x, y); left_drag = TRUE; SetCapture(win); /* change to a groovy cursor */ hCur = LoadCursor(NULL, IDC_ARROW); if (hCur) oldCursor = SetCursor(hCur); else oldCursor = NULL; } break; case WM_LBUTTONUP: ReleaseCapture(); left_drag = FALSE; if (oldCursor) SetCursor(oldCursor); break; case WM_RBUTTONDOWN: { HCURSOR hCur; int x = LOWORD(lparam); int y = HIWORD(lparam); last_x = x; last_y = y; FindAndSelectVisual(info->view, x, y); right_drag = TRUE; SetCapture(win); /* change to a groovy cursor */ hCur = LoadCursor(NULL, IDC_ARROW); if (hCur) oldCursor = SetCursor(hCur); else oldCursor = NULL; } break; case WM_RBUTTONUP: right_drag = FALSE; ReleaseCapture(); if (oldCursor) SetCursor(oldCursor); break; case WM_MOUSEMOVE: if ((wparam & MK_LBUTTON) && sFrame && left_drag) { double delta_x, delta_y; delta_x = SIGN_EXTEND(LOWORD(lparam)) - last_x; delta_y = -SIGN_EXTEND((HIWORD(lparam)) - last_y); last_x = SIGN_EXTEND(LOWORD(lparam)); last_y = SIGN_EXTEND(HIWORD(lparam)); { double delta_r = sqrt(delta_x * delta_x + delta_y * delta_y); double radius = 50; double denom; denom = sqrt(radius * radius + delta_r * delta_r); if (delta_r == 0 || denom == 0) break; sFrame->SetRotation ( info->camera, D3DDivide(D3DVAL((float) delta_y), D3DVAL((float) delta_r)), D3DDivide(D3DVAL((float) -delta_x), D3DVAL((float) delta_r)), D3DVAL(0.0), D3DDivide(D3DVAL((float) delta_r), D3DVAL((float) denom)) ); } } else if ((wparam & MK_RBUTTON) && sFrame && right_drag) { double delta_x, delta_y; D3DVECTOR p1; D3DRMVECTOR4D p2; delta_x = SIGN_EXTEND(LOWORD(lparam)) - last_x; delta_y = SIGN_EXTEND(HIWORD(lparam)) - last_y; last_x = SIGN_EXTEND(LOWORD(lparam)); last_y = SIGN_EXTEND(HIWORD(lparam)); sFrame->GetPosition(info->scene, &p1); info->view->Transform(&p2, &p1); p2.x += D3DMultiply(D3DVAL((float)delta_x), p2.w); p2.y += D3DMultiply(D3DVAL((float)delta_y), p2.w); info->view->InverseTransform(&p1, &p2); sFrame->SetPosition(info->scene, p1.x, p1.y, p1.z); } break; case WM_COMMAND: switch( wparam & 0xffff ) { case MENU_FILE_ABOUT: DialogBox((HINSTANCE) GetWindowLong(win, GWL_HINSTANCE),"AboutBox", win, (DLGPROC)AboutDlgProc); break; case MENU_FILE_OPEN: { LPDIRECT3DRMMESHBUILDER builder; HRESULT rval; char *file = OpenNewFile(win, "Open a Mesh file"); if (file) { if (FAILED(lpD3DRM->CreateMeshBuilder(&builder))) { Msg("Failed the create a builder for the new mesh.\n"); break; } rval = builder->Load(file, NULL, D3DRMLOAD_FROMFILE, loadTextures, NULL); if (rval != D3DRM_OK) { Msg("Loading %s failed.\n%s", file, MyErrorToString(rval)); builder->Release(); break; } if (!PlaceMesh(builder, info)) { Msg("Placing the mesh in the scene failed.\n"); builder->Release(); break; } builder->Release(); } /*LoadAnimationSet(file, info);*/ break; } case MENU_FILE_OPEN_ANIMSET: { char *file = OpenNewFile(win, "Open Animation ..."); if (file) { if (LoadAnimationSet(file, info) == FALSE) { Msg("Loading and placing of %s failed.\n", file); } } break; } case MENU_FILE_OPEN_FRAME: { char *file = OpenNewFile(win, "Open Frame ..."); if (file) { if (LoadFrameHierarchy(file, info) == FALSE) { Msg("Loading and placing of %s failed.\n", file); } } break; } case MENU_FILE_EXIT: PostQuitMessage(0); break; case MENU_EDIT_CUT: CutVisual(); break; case MENU_EDIT_COPY: CopyVisual(); break; case MENU_EDIT_PASTE: PasteVisual(info->scene); break; case MENU_EDIT_DELETE: DeleteVisual(); break; case MENU_EDIT_COLOR: if (sFrame) { LPDIRECT3DRMMESHBUILDER mesh; HRESULT rval; if (FAILED(sVisual->QueryInterface(IID_IDirect3DRMMeshBuilder, (void**) &mesh))) break; if (SelectedLight()) { D3DCOLOR c = SelectedLight()->GetColor(); if (ChooseNewColor(win, &c)) { mesh->SetColor(c); SelectedLight()->SetColor(c); } } else { D3DCOLOR c; if (mesh->GetFaceCount()) { LPDIRECT3DRMFACEARRAY faces; LPDIRECT3DRMFACE face; mesh->GetFaces(&faces); faces->GetElement(0, &face); c = face->GetColor(); RELEASE(face); RELEASE(faces); } else c = D3DRMCreateColorRGB(D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0)); if (ChooseNewColor(win, &c)) { rval = mesh->SetColor(c); if (rval != D3DRM_OK) Msg("Failed to set the mesh's color.\n%s", MyErrorToString(rval)); } } RELEASE(mesh); } break; case MENU_EDIT_BOXES: { HMENU menu; int checked = ToggleBoxes() ? MF_CHECKED : MF_UNCHECKED; menu = GetMenu(win); menu = GetSubMenu(menu, 1); CheckMenuItem(menu, MENU_EDIT_BOXES, MF_BYCOMMAND|checked); } break; case MENU_QUALITY_LIGHTING: ToggleLighting(win, info); break; case MENU_QUALITY_POINTS: SetFillMode(win, info, D3DRMFILL_POINTS); break; case MENU_QUALITY_WIREFRAME: SetFillMode(win, info, D3DRMFILL_WIREFRAME); break; case MENU_QUALITY_SOLID: SetFillMode(win, info, D3DRMFILL_SOLID); break; case MENU_QUALITY_FLAT: SetShadeMode(win, info, D3DRMSHADE_FLAT); break; case MENU_QUALITY_GOURAUD: SetShadeMode(win, info, D3DRMSHADE_GOURAUD); break; case MENU_QUALITY_PHONG: SetShadeMode(win, info, D3DRMSHADE_PHONG); break; case MENU_MODEL_MONO: SetModel(win, info, D3DCOLOR_MONO); break; case MENU_MODEL_RGB: SetModel(win, info, D3DCOLOR_RGB); break; case MENU_DITHER: ToggleDither(win, info); break; case MENU_TEXTURE_FILTERING: ToggleTextureFiltering(win, info); break; case MENU_LIGHT_DIRECTIONAL: case MENU_LIGHT_PARALLEL_POINT: case MENU_LIGHT_POINT: case MENU_LIGHT_SPOT: { CreateLight(wparam, info); } break; } break; case WM_DESTROY: PostQuitMessage( 0 ); bQuit = TRUE; break; case WM_SIZE: { int width = LOWORD(lparam); int height = HIWORD(lparam); if (width && height) { if (!ResizeViewport(win, info, width, height)) { bQuit = TRUE; break; } active_window->bMinimized = FALSE; } else { active_window->bMinimized = TRUE; } } break; case WM_ACTIVATE: { LPDIRECT3DRMWINDEVICE windev; if (SUCCEEDED(info->dev->QueryInterface(IID_IDirect3DRMWinDevice, (void **) &windev))) { if (FAILED(windev->HandleActivate(wparam))) Msg("Failed to handle WM_ACTIVATE.\n"); windev->Release(); } else { Msg("Failed to create Windows device to handle WM_ACTIVATE.\n"); } } break; case WM_PAINT: if (info) { RECT r; PAINTSTRUCT ps; LPDIRECT3DRMWINDEVICE windev; if (GetUpdateRect(win, &r, FALSE)) { BeginPaint(win, &ps); if (SUCCEEDED(info->dev->QueryInterface(IID_IDirect3DRMWinDevice, (void **) &windev))) { if (FAILED(windev->HandlePaint(ps.hdc))) Msg("Failed to handle WM_PAINT.\n"); windev->Release(); } else { Msg("Failed to create Windows device to handle WM_PAINT.\n"); } EndPaint(win, &ps); } } else return DefWindowProc(win, msg, wparam, lparam); default: return DefWindowProc(win, msg, wparam, lparam); } return 0L; } /* * MyErrorToString * Returns a pointer to a string describing the given error code. */ char* MyErrorToString(HRESULT error) { switch(error) { case DD_OK: /* Also includes D3D_OK and D3DRM_OK */ return "No error.\0"; case DDERR_ALREADYINITIALIZED: return "This object is already initialized.\0"; case DDERR_BLTFASTCANTCLIP: return "Return if a clipper object is attached to the source surface passed into a BltFast call.\0"; case DDERR_CANNOTATTACHSURFACE: return "This surface can not be attached to the requested surface.\0"; case DDERR_CANNOTDETACHSURFACE: return "This surface can not be detached from the requested surface.\0"; case DDERR_CANTCREATEDC: return "Windows can not create any more DCs.\0"; case DDERR_CANTDUPLICATE: return "Can't duplicate primary & 3D surfaces, or surfaces that are implicitly created.\0"; case DDERR_CLIPPERISUSINGHWND: return "An attempt was made to set a cliplist for a clipper object that is already monitoring an hwnd.\0"; case DDERR_COLORKEYNOTSET: return "No src color key specified for this operation.\0"; case DDERR_CURRENTLYNOTAVAIL: return "Support is currently not available.\0"; case DDERR_DIRECTDRAWALREADYCREATED: return "A DirectDraw object representing this driver has already been created for this process.\0"; case DDERR_EXCEPTION: return "An exception was encountered while performing the requested operation.\0"; case DDERR_EXCLUSIVEMODEALREADYSET: return "An attempt was made to set the cooperative level when it was already set to exclusive.\0"; case DDERR_GENERIC: return "Generic failure.\0"; case DDERR_HEIGHTALIGN: return "Height of rectangle provided is not a multiple of reqd alignment.\0"; case DDERR_HWNDALREADYSET: return "The CooperativeLevel HWND has already been set. It can not be reset while the process has surfaces or palettes created.\0"; case DDERR_HWNDSUBCLASSED: return "HWND used by DirectDraw CooperativeLevel has been subclassed, this prevents DirectDraw from restoring state.\0"; case DDERR_IMPLICITLYCREATED: return "This surface can not be restored because it is an implicitly created surface.\0"; case DDERR_INCOMPATIBLEPRIMARY: return "Unable to match primary surface creation request with existing primary surface.\0"; case DDERR_INVALIDCAPS: return "One or more of the caps bits passed to the callback are incorrect.\0"; case DDERR_INVALIDCLIPLIST: return "DirectDraw does not support the provided cliplist.\0"; case DDERR_INVALIDDIRECTDRAWGUID: return "The GUID passed to DirectDrawCreate is not a valid DirectDraw driver identifier.\0"; case DDERR_INVALIDMODE: return "DirectDraw does not support the requested mode.\0"; case DDERR_INVALIDOBJECT: return "DirectDraw received a pointer that was an invalid DIRECTDRAW object.\0"; case DDERR_INVALIDPARAMS: return "One or more of the parameters passed to the function are incorrect.\0"; case DDERR_INVALIDPIXELFORMAT: return "The pixel format was invalid as specified.\0"; case DDERR_INVALIDPOSITION: return "Returned when the position of the overlay on the destination is no longer legal for that destination.\0"; case DDERR_INVALIDRECT: return "Rectangle provided was invalid.\0"; case DDERR_LOCKEDSURFACES: return "Operation could not be carried out because one or more surfaces are locked.\0"; case DDERR_NO3D: return "There is no 3D present.\0"; case DDERR_NOALPHAHW: return "Operation could not be carried out because there is no alpha accleration hardware present or available.\0"; case DDERR_NOBLTHW: return "No blitter hardware present.\0"; case DDERR_NOCLIPLIST: return "No cliplist available.\0"; case DDERR_NOCLIPPERATTACHED: return "No clipper object attached to surface object.\0"; case DDERR_NOCOLORCONVHW: return "Operation could not be carried out because there is no color conversion hardware present or available.\0"; case DDERR_NOCOLORKEY: return "Surface doesn't currently have a color key\0"; case DDERR_NOCOLORKEYHW: return "Operation could not be carried out because there is no hardware support of the destination color key.\0"; case DDERR_NOCOOPERATIVELEVELSET: return "Create function called without DirectDraw object method SetCooperativeLevel being called.\0"; case DDERR_NODC: return "No DC was ever created for this surface.\0"; case DDERR_NODDROPSHW: return "No DirectDraw ROP hardware.\0"; case DDERR_NODIRECTDRAWHW: return "A hardware-only DirectDraw object creation was attempted but the driver did not support any hardware.\0"; case DDERR_NOEMULATION: return "Software emulation not available.\0"; case DDERR_NOEXCLUSIVEMODE: return "Operation requires the application to have exclusive mode but the application does not have exclusive mode.\0"; case DDERR_NOFLIPHW: return "Flipping visible surfaces is not supported.\0"; case DDERR_NOGDI: return "There is no GDI present.\0"; case DDERR_NOHWND: return "Clipper notification requires an HWND or no HWND has previously been set as the CooperativeLevel HWND.\0"; case DDERR_NOMIRRORHW: return "Operation could not be carried out because there is no hardware present or available.\0"; case DDERR_NOOVERLAYDEST: return "Returned when GetOverlayPosition is called on an overlay that UpdateOverlay has never been called on to establish a destination.\0"; case DDERR_NOOVERLAYHW: return "Operation could not be carried out because there is no overlay hardware present or available.\0"; case DDERR_NOPALETTEATTACHED: return "No palette object attached to this surface.\0"; case DDERR_NOPALETTEHW: return "No hardware support for 16 or 256 color palettes.\0"; case DDERR_NORASTEROPHW: return "Operation could not be carried out because there is no appropriate raster op hardware present or available.\0"; case DDERR_NOROTATIONHW: return "Operation could not be carried out because there is no rotation hardware present or available.\0"; case DDERR_NOSTRETCHHW: return "Operation could not be carried out because there is no hardware support for stretching.\0"; case DDERR_NOT4BITCOLOR: return "DirectDrawSurface is not in 4 bit color palette and the requested operation requires 4 bit color palette.\0"; case DDERR_NOT4BITCOLORINDEX: return "DirectDrawSurface is not in 4 bit color index palette and the requested operation requires 4 bit color index palette.\0"; case DDERR_NOT8BITCOLOR: return "DirectDrawSurface is not in 8 bit color mode and the requested operation requires 8 bit color.\0"; case DDERR_NOTAOVERLAYSURFACE: return "Returned when an overlay member is called for a non-overlay surface.\0"; case DDERR_NOTEXTUREHW: return "Operation could not be carried out because there is no texture mapping hardware present or available.\0"; case DDERR_NOTFLIPPABLE: return "An attempt has been made to flip a surface that is not flippable.\0"; case DDERR_NOTFOUND: return "Requested item was not found.\0"; case DDERR_NOTLOCKED: return "Surface was not locked. An attempt to unlock a surface that was not locked at all, or by this process, has been attempted.\0"; case DDERR_NOTPALETTIZED: return "The surface being used is not a palette-based surface.\0"; case DDERR_NOVSYNCHW: return "Operation could not be carried out because there is no hardware support for vertical blank synchronized operations.\0"; case DDERR_NOZBUFFERHW: return "Operation could not be carried out because there is no hardware support for zbuffer blitting.\0"; case DDERR_NOZOVERLAYHW: return "Overlay surfaces could not be z layered based on their BltOrder because the hardware does not support z layering of overlays.\0"; case DDERR_OUTOFCAPS: return "The hardware needed for the requested operation has already been allocated.\0"; case DDERR_OUTOFMEMORY: return "DirectDraw does not have enough memory to perform the operation.\0"; case DDERR_OUTOFVIDEOMEMORY: return "DirectDraw does not have enough memory to perform the operation.\0"; case DDERR_OVERLAYCANTCLIP: return "The hardware does not support clipped overlays.\0"; case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: return "Can only have ony color key active at one time for overlays.\0"; case DDERR_OVERLAYNOTVISIBLE: return "Returned when GetOverlayPosition is called on a hidden overlay.\0"; case DDERR_PALETTEBUSY: return "Access to this palette is being refused because the palette is already locked by another thread.\0"; case DDERR_PRIMARYSURFACEALREADYEXISTS: return "This process already has created a primary surface.\0"; case DDERR_REGIONTOOSMALL: return "Region passed to Clipper::GetClipList is too small.\0"; case DDERR_SURFACEALREADYATTACHED: return "This surface is already attached to the surface it is being attached to.\0"; case DDERR_SURFACEALREADYDEPENDENT: return "This surface is already a dependency of the surface it is being made a dependency of.\0"; case DDERR_SURFACEBUSY: return "Access to this surface is being refused because the surface is already locked by another thread.\0"; case DDERR_SURFACEISOBSCURED: return "Access to surface refused because the surface is obscured.\0"; case DDERR_SURFACELOST: return "Access to this surface is being refused because the surface memory is gone. The DirectDrawSurface object representing this surface should have Restore called on it.\0"; case DDERR_SURFACENOTATTACHED: return "The requested surface is not attached.\0"; case DDERR_TOOBIGHEIGHT: return "Height requested by DirectDraw is too large.\0"; case DDERR_TOOBIGSIZE: return "Size requested by DirectDraw is too large, but the individual height and width are OK.\0"; case DDERR_TOOBIGWIDTH: return "Width requested by DirectDraw is too large.\0"; case DDERR_UNSUPPORTED: return "Action not supported.\0"; case DDERR_UNSUPPORTEDFORMAT: return "FOURCC format requested is unsupported by DirectDraw.\0"; case DDERR_UNSUPPORTEDMASK: return "Bitmask in the pixel format requested is unsupported by DirectDraw.\0"; case DDERR_VERTICALBLANKINPROGRESS: return "Vertical blank is in progress.\0"; case DDERR_WASSTILLDRAWING: return "Informs DirectDraw that the previous Blt which is transfering information to or from this Surface is incomplete.\0"; case DDERR_WRONGMODE: return "This surface can not be restored because it was created in a different mode.\0"; case DDERR_XALIGN: return "Rectangle provided was not horizontally aligned on required boundary.\0"; case D3DERR_BADMAJORVERSION: return "D3DERR_BADMAJORVERSION\0"; case D3DERR_BADMINORVERSION: return "D3DERR_BADMINORVERSION\0"; case D3DERR_EXECUTE_LOCKED: return "D3DERR_EXECUTE_LOCKED\0"; case D3DERR_EXECUTE_NOT_LOCKED: return "D3DERR_EXECUTE_NOT_LOCKED\0"; case D3DERR_EXECUTE_CREATE_FAILED: return "D3DERR_EXECUTE_CREATE_FAILED\0"; case D3DERR_EXECUTE_DESTROY_FAILED: return "D3DERR_EXECUTE_DESTROY_FAILED\0"; case D3DERR_EXECUTE_LOCK_FAILED: return "D3DERR_EXECUTE_LOCK_FAILED\0"; case D3DERR_EXECUTE_UNLOCK_FAILED: return "D3DERR_EXECUTE_UNLOCK_FAILED\0"; case D3DERR_EXECUTE_FAILED: return "D3DERR_EXECUTE_FAILED\0"; case D3DERR_EXECUTE_CLIPPED_FAILED: return "D3DERR_EXECUTE_CLIPPED_FAILED\0"; case D3DERR_TEXTURE_NO_SUPPORT: return "D3DERR_TEXTURE_NO_SUPPORT\0"; case D3DERR_TEXTURE_NOT_LOCKED: return "D3DERR_TEXTURE_NOT_LOCKED\0"; case D3DERR_TEXTURE_LOCKED: return "D3DERR_TEXTURELOCKED\0"; case D3DERR_TEXTURE_CREATE_FAILED: return "D3DERR_TEXTURE_CREATE_FAILED\0"; case D3DERR_TEXTURE_DESTROY_FAILED: return "D3DERR_TEXTURE_DESTROY_FAILED\0"; case D3DERR_TEXTURE_LOCK_FAILED: return "D3DERR_TEXTURE_LOCK_FAILED\0"; case D3DERR_TEXTURE_UNLOCK_FAILED: return "D3DERR_TEXTURE_UNLOCK_FAILED\0"; case D3DERR_TEXTURE_LOAD_FAILED: return "D3DERR_TEXTURE_LOAD_FAILED\0"; case D3DERR_MATRIX_CREATE_FAILED: return "D3DERR_MATRIX_CREATE_FAILED\0"; case D3DERR_MATRIX_DESTROY_FAILED: return "D3DERR_MATRIX_DESTROY_FAILED\0"; case D3DERR_MATRIX_SETDATA_FAILED: return "D3DERR_MATRIX_SETDATA_FAILED\0"; case D3DERR_SETVIEWPORTDATA_FAILED: return "D3DERR_SETVIEWPORTDATA_FAILED\0"; case D3DERR_MATERIAL_CREATE_FAILED: return "D3DERR_MATERIAL_CREATE_FAILED\0"; case D3DERR_MATERIAL_DESTROY_FAILED: return "D3DERR_MATERIAL_DESTROY_FAILED\0"; case D3DERR_MATERIAL_SETDATA_FAILED: return "D3DERR_MATERIAL_SETDATA_FAILED\0"; case D3DERR_LIGHT_SET_FAILED: return "D3DERR_LIGHT_SET_FAILED\0"; case D3DRMERR_BADOBJECT: return "D3DRMERR_BADOBJECT\0"; case D3DRMERR_BADTYPE: return "D3DRMERR_BADTYPE\0"; case D3DRMERR_BADALLOC: return "D3DRMERR_BADALLOC\0"; case D3DRMERR_FACEUSED: return "D3DRMERR_FACEUSED\0"; case D3DRMERR_NOTFOUND: return "D3DRMERR_NOTFOUND\0"; case D3DRMERR_NOTDONEYET: return "D3DRMERR_NOTDONEYET\0"; case D3DRMERR_FILENOTFOUND: return "The file was not found.\0"; case D3DRMERR_BADFILE: return "D3DRMERR_BADFILE\0"; case D3DRMERR_BADDEVICE: return "D3DRMERR_BADDEVICE\0"; case D3DRMERR_BADVALUE: return "D3DRMERR_BADVALUE\0"; case D3DRMERR_BADMAJORVERSION: return "D3DRMERR_BADMAJORVERSION\0"; case D3DRMERR_BADMINORVERSION: return "D3DRMERR_BADMINORVERSION\0"; case D3DRMERR_UNABLETOEXECUTE: return "D3DRMERR_UNABLETOEXECUTE\0"; default: return "Unrecognized error value.\0"; } }