bool CGapList::IsComplete(uint64 gapstart, uint64 gapend) const { if (!ArgCheck(gapstart, gapend)) { return false; } // find a place to start: // first gap which ends >= our gap start ListType::const_iterator it = m_gaplist.lower_bound(gapstart); for (; it != m_gaplist.end(); ++it) { uint64 curGapStart = it->second; uint64 curGapEnd = it->first; if ( (curGapStart >= gapstart && curGapEnd <= gapend) ||(curGapStart >= gapstart && curGapStart <= gapend) ||(curGapEnd <= gapend && curGapEnd >= gapstart) ||(gapstart >= curGapStart && gapend <= curGapEnd)) { return false; } if (curGapStart > gapend) { break; } } return true; }
//=========================================================================== // windowedMode // Only adjusts the window style and size. //=========================================================================== void windowedMode(int width, int height) { // We need to have a large enough client area. RECT rect; int xoff = (GetSystemMetrics(SM_CXSCREEN) - width) / 2, yoff = (GetSystemMetrics(SM_CYSCREEN) - height) / 2; LONG style; if(ArgCheck("-nocenter")) xoff = yoff = 0; if(ArgCheckWith("-xpos", 1)) xoff = atoi(ArgNext()); if(ArgCheckWith("-ypos", 1)) yoff = atoi(ArgNext()); rect.left = xoff; rect.top = yoff; rect.right = xoff + width; rect.bottom = yoff + height; // Set window style. style = GetWindowLong(windowHandle, GWL_STYLE) | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; SetWindowLong(windowHandle, GWL_STYLE, style); AdjustWindowRect(&rect, style, FALSE); SetWindowPos(windowHandle, 0, xoff, yoff, /*rect.left, rect.top, */ rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); screenWidth = width; screenHeight = height; }
//========================================================================== // ArgCheckWith // Checks for the given parameter in the program's command line arguments // and it is followed by N other arguments. // Returns the argument number (1 to argc-1) or 0 if not present. //========================================================================== int ArgCheckWith(char *check, int num) { int i = ArgCheck(check); if(!i || i + num >= num_args) return 0; return i; }
Bool ArgListCheck(ArgList args) { Index i; CHECKL(args != NULL); for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i) { CHECKL(i < MPS_ARGS_MAX); CHECKL(ArgCheck(&args[i])); } return TRUE; }
void CGapList::AddGap(uint64 gapstart, uint64 gapend) { if (!ArgCheck(gapstart, gapend)) { return; } // AddDebugLogLineN(logPartFile, CFormat(wxT(" AddGap: %5d - %5d")) % gapstart % gapend); // mark involved part(s) as incomplete uint16 partlast = gapend / PARTSIZE; for (uint16 part = gapstart / PARTSIZE; part <= partlast; part++) { m_partsComplete[part] = incomplete; } // total gap size has to be recalculated m_totalGapSizeValid = false; // find a place to start: // first gap which ends >= our gap start - 1 // (-1 so we can join adjacent gaps) iterator it = m_gaplist.lower_bound(gapstart > 0 ? gapstart - 1 : 0); while (it != m_gaplist.end()) { iterator it2 = it++; uint64 curGapStart = it2->second; uint64 curGapEnd = it2->first; if (curGapStart >= gapstart && curGapEnd <= gapend) { // this gap is inside the new gap - delete m_gaplist.erase(it2); } else if (curGapStart >= gapstart && curGapStart <= gapend + 1) { // head of this gap is in the new gap, or this gap is // directly behind the new gap - extend limit and delete gapend = curGapEnd; m_gaplist.erase(it2); } else if (curGapEnd <= gapend && curGapEnd >= gapstart - 1) { // tail of this gap is in the new gap, or this gap is // directly before the new gap - extend limit and delete gapstart = curGapStart; m_gaplist.erase(it2); } else if (curGapStart <= gapstart && curGapEnd >= gapend) { // new gap is already inside this gap - return return; // now all cases of overlap are ruled out } else if (curGapStart > gapstart) { // this gap is the first behind the new gap -> insert before it it = it2; break; } } // for fastest insertion point to the element AFTER which we want to insert if (it != m_gaplist.begin()) { --it; } m_gaplist.insert(it, std::pair<uint64,uint64>(gapend, gapstart)); }
boolean I_InitMouse(void) { HWND hWnd; HRESULT hr; if(ArgCheck("-nomouse") || novideo) return false; hWnd = Sys_GetWindowHandle(mainWindowIdx); if(!hWnd) { Con_Error("I_InitMouse: Main window not available, cannot init mouse."); return false; } hr = IDirectInput_CreateDevice(dInput, &GUID_SysMouse, &didMouse, 0); if(FAILED(hr)) { Con_Message("I_InitMouse: Failed to create device (0x%x).\n", hr); return false; } // Set data format. hr = IDirectInputDevice_SetDataFormat(didMouse, &c_dfDIMouse2); if(FAILED(hr)) { Con_Message("I_InitMouse: Failed to set data format (0x%x).\n", hr); goto kill_mouse; } // Set behaviour. hr = IDirectInputDevice_SetCooperativeLevel(didMouse, hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE); if(FAILED(hr)) { Con_Message("I_InitMouse: Failed to set co-op level (0x%x).\n", hr); goto kill_mouse; } // Acquire the device. IDirectInputDevice_Acquire(didMouse); // Init was successful. return true; kill_mouse: I_SAFE_RELEASE(didMouse); return false; }
/** * Post Engine Initialization routine. * All game-specific actions that should take place at this time go here. */ void G_PostInit(void) { int p; char file[256]; char mapStr[6]; // Common post init routine G_CommonPostInit(); // Initialize ammo info. P_InitAmmoInfo(); // Initialize weapon info. P_InitWeaponInfo(); // Print a game mode banner with rulers. Con_FPrintf(CBLF_RULER | CBLF_WHITE | CBLF_CENTER, gamemode == retail ? "The Ultimate DOOM Startup\n" : gamemode == shareware ? "DOOM Shareware Startup\n" : gamemode == registered ? "DOOM Registered Startup\n" : gamemode == commercial ? (gamemission == GM_PLUT ? "Final DOOM: The Plutonia Experiment\n" : gamemission == GM_TNT ? "Final DOOM: TNT: Evilution\n" : "DOOM 2: Hell on Earth\n") : "Public DOOM\n"); Con_FPrintf(CBLF_RULER, ""); // Game parameters. monsterinfight = GetDefInt("AI|Infight", 0); // get skill / episode / map from parms gameskill = startskill = SM_NOITEMS; startepisode = 1; startmap = 1; autostart = false; // Game mode specific settings // Plutonia and TNT automatically turn on the full sky. if(gamemode == commercial && (gamemission == GM_PLUT || gamemission == GM_TNT)) { Con_SetInteger("rend-sky-full", 1, true); } // Command line options nomonsters = ArgCheck("-nomonsters"); respawnparm = ArgCheck("-respawn"); fastparm = ArgCheck("-fast"); devparm = ArgCheck("-devparm"); if(ArgCheck("-altdeath")) cfg.netDeathmatch = 2; else if(ArgCheck("-deathmatch")) cfg.netDeathmatch = 1; p = ArgCheck("-skill"); if(p && p < myargc - 1) { startskill = Argv(p + 1)[0] - '1'; autostart = true; } p = ArgCheck("-episode"); if(p && p < myargc - 1) { startepisode = Argv(p + 1)[0] - '0'; startmap = 1; autostart = true; } p = ArgCheck("-timer"); if(p && p < myargc - 1 && deathmatch) { int time; time = atoi(Argv(p + 1)); Con_Message("Levels will end after %d minute", time); if(time > 1) Con_Message("s"); Con_Message(".\n"); } p = ArgCheck("-warp"); if(p && p < myargc - 1) { if(gamemode == commercial) { startmap = atoi(Argv(p + 1)); autostart = true; } else if(p < myargc - 2) { startepisode = Argv(p + 1)[0] - '0'; startmap = Argv(p + 2)[0] - '0'; autostart = true; } } // turbo option p = ArgCheck("-turbo"); turboMul = 1.0f; if(p) { int scale = 200; turboparm = true; if(p < myargc - 1) scale = atoi(Argv(p + 1)); if(scale < 10) scale = 10; if(scale > 400) scale = 400; Con_Message("turbo scale: %i%%\n", scale); turboMul = scale / 100.f; } // Are we autostarting? if(autostart) { if(gamemode == commercial) Con_Message("Warp to Map %d, Skill %d\n", startmap, startskill + 1); else Con_Message("Warp to Episode %d, Map %d, Skill %d\n", startepisode, startmap, startskill + 1); } // Load a saved game? p = ArgCheck("-loadgame"); if(p && p < myargc - 1) { SV_GetSaveGameFileName(Argv(p + 1)[0] - '0', file); G_LoadGame(file); } // Check valid episode and map if((autostart || IS_NETGAME)) { if(gamemode == commercial) sprintf(mapStr,"MAP%2.2d", startmap); else sprintf(mapStr,"E%d%d",startepisode, startmap); if(!W_CheckNumForName(mapStr)) { startepisode = 1; startmap = 1; } } // Print a string showing the state of the game parameters Con_Message("Game state parameters:%s%s%s%s%s\n", nomonsters? " nomonsters" : "", respawnparm? " respawn" : "", fastparm? " fast" : "", turboparm? " turbo" : "", (cfg.netDeathmatch ==1)? " deathmatch" : (cfg.netDeathmatch ==2)? " altdeath" : ""); if(G_GetGameAction() != GA_LOADGAME) { if(autostart || IS_NETGAME) { G_DeferedInitNew(startskill, startepisode, startmap); } else { G_StartTitle(); // start up intro loop } } }
/* * Checks availability of IWAD files by name, to determine whether * registered/commercial features should be executed (notably loading * PWAD's). */ static void identifyFromData(void) { typedef struct { char **lumps; gamemode_t mode; } identify_t; char *shareware_lumps[] = { // List of lumps to detect shareware with. "e1m1", "e1m2", "e1m3", "e1m4", "e1m5", "e1m6", "e1m7", "e1m8", "e1m9", "d_e1m1", "floor4_8", "floor7_2", NULL }; char *registered_lumps[] = { // List of lumps to detect registered with. "e2m1", "e2m2", "e2m3", "e2m4", "e2m5", "e2m6", "e2m7", "e2m8", "e2m9", "e3m1", "e3m2", "e3m3", "e3m4", "e3m5", "e3m6", "e3m7", "e3m8", "e3m9", "cybre1", "cybrd8", "floor7_2", NULL }; char *retail_lumps[] = { // List of lumps to detect Ultimate Doom with. "e4m1", "e4m2", "e4m3", "e4m4", "e4m5", "e4m6", "e4m7", "e4m8", "e4m9", "m_epi4", NULL }; char *commercial_lumps[] = { // List of lumps to detect Doom II with. "map01", "map02", "map03", "map04", "map10", "map20", "map25", "map30", "vilen1", "vileo1", "vileq1", "grnrock", NULL }; char *plutonia_lumps[] = { "_deutex_", "mc5", "mc11", "mc16", "mc20", NULL }; char *tnt_lumps[] = { "cavern5", "cavern7", "stonew1", NULL }; identify_t list[] = { {commercial_lumps, commercial}, // Doom2 is easiest to detect. {retail_lumps, retail}, // Ultimate Doom is obvious. {registered_lumps, registered}, {shareware_lumps, shareware} }; int i, num = sizeof(list) / sizeof(identify_t); // First check the command line. if(ArgCheck("-sdoom")) { // Shareware DOOM. G_SetGameMode(shareware); return; } if(ArgCheck("-doom")) { // Registered DOOM. G_SetGameMode(registered); return; } if(ArgCheck("-doom2") || ArgCheck("-plutonia") || ArgCheck("-tnt")) { // DOOM 2. G_SetGameMode(commercial); gamemission = GM_DOOM2; if(ArgCheck("-plutonia")) gamemission = GM_PLUT; if(ArgCheck("-tnt")) gamemission = GM_TNT; return; } if(ArgCheck("-ultimate")) { // Retail DOOM 1: Ultimate DOOM. G_SetGameMode(retail); return; } // Now we must look at the lumps. for(i = 0; i < num; ++i) { // If all the listed lumps are found, selection is made. // All found? if(lumpsFound(list[i].lumps)) { G_SetGameMode(list[i].mode); // Check the mission packs. if(LumpsFound(plutonia_lumps)) gamemission = GM_PLUT; else if(LumpsFound(tnt_lumps)) gamemission = GM_TNT; else if(gamemode == commercial) gamemission = GM_DOOM2; else gamemission = GM_DOOM; return; } } // A detection couldn't be made. G_SetGameMode(shareware); // Assume the minimum. Con_Message("\nIdentifyVersion: DOOM version unknown.\n" "** Important data might be missing! **\n\n"); }
/** * NOTE: Window, height, etc. must be set before calling this. */ void Window::Setup(void) { uint realWidth = GetSystemMetrics(SM_CXSCREEN); uint realHeight = GetSystemMetrics(SM_CYSCREEN); int xOff, yOff; RECT rect; // Update our bitdepth if it's not yet known. if(!bits) UseDesktopBits(); DP("Window setup:"); if(isWindow) { if(width > realWidth) width = realWidth; if(height > realHeight) height = realHeight; // Center by default. xOff = (realWidth - width) / 2; yOff = (realHeight - height) / 2; // Check for modifier options. if(ArgCheck("-nocenter")) xOff = yOff = 0; if(ArgCheckWith("-xpos", 1)) xOff = atoi(ArgNext()); if(ArgCheckWith("-ypos", 1)) yOff = atoi(ArgNext()); LONG style = GetWindowLong(hwnd, GWL_STYLE) | WS_VISIBLE | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_SYSMENU | WS_MINIMIZEBOX; SetWindowLong(hwnd, GWL_STYLE, style); // Adjust the size of the window so the client area is the // right size. rect.left = rect.top = 0; rect.right = width; rect.bottom = height; AdjustWindowRect(&rect, style, FALSE); // But we also want the window's top left corner to be at // (xOff, yOff). SetWindowPos(hwnd, HWND_TOP, xOff, yOff, rect.right - rect.left, rect.bottom - rect.top, 0); DP(" Windowed mode: x=%i, y=%i, w=%i, h=%i", xOff, yOff, rect.right - rect.left, rect.bottom - rect.top); } else { // In fullscreen, the setup is much simpler. SetWindowLong(hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); SetWindowPos(hwnd, HWND_TOP, 0, 0, width, height, 0); DP(" Fullscreen mode: w=%i, h=%i", width, height); } }
//=========================================================================== // DG_Init // 'mode' is either DGL_MODE_WINDOW or DGL_MODE_FULLSCREEN. If 'bpp' is // zero, the current display color depth is used. //=========================================================================== int DG_Init(int width, int height, int bpp, int mode) { boolean fullscreen = (mode == DGL_MODE_FULLSCREEN); char *token, *extbuf; const SDL_VideoInfo *info = NULL; Con_Message("DG_Init: OpenGL.\n"); // Are we in range here? /* if(!fullscreen) { if(width > GetSystemMetrics(SM_CXSCREEN)) width = GetSystemMetrics(SM_CXSCREEN); if(height > GetSystemMetrics(SM_CYSCREEN)) height = GetSystemMetrics(SM_CYSCREEN); } */ info = SDL_GetVideoInfo(); screenBits = info->vfmt->BitsPerPixel; screenWidth = width; screenHeight = height; windowed = !fullscreen; allowCompression = true; verbose = ArgExists("-verbose"); // Set GL attributes. We want at least 5 bits per color and a 16 // bit depth buffer. Plus double buffering, of course. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); /* if(fullscreen) { if(!fullscreenMode(screenWidth, screenHeight, bpp)) { Con_Error("drOpenGL.Init: Resolution change failed (%d x %d).\n", screenWidth, screenHeight); } } else { windowedMode(screenWidth, screenHeight); } */ if(!initOpenGL()) { Con_Error("drOpenGL.Init: OpenGL init failed.\n"); } // Clear the buffers. DG_Clear(DGL_COLOR_BUFFER_BIT | DGL_DEPTH_BUFFER_BIT); token = (char *) glGetString(GL_EXTENSIONS); extbuf = malloc(strlen(token) + 1); strcpy(extbuf, token); // Check the maximum texture size. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); initExtensions(); if(firstTimeInit) { firstTimeInit = DGL_FALSE; // Print some OpenGL information (console must be initialized by now). Con_Message("OpenGL information:\n"); Con_Message(" Vendor: %s\n", glGetString(GL_VENDOR)); Con_Message(" Renderer: %s\n", glGetString(GL_RENDERER)); Con_Message(" Version: %s\n", glGetString(GL_VERSION)); Con_Message(" Extensions:\n"); // Show the list of GL extensions. token = strtok(extbuf, " "); while(token) { Con_Message(" "); // Indent. if(verbose) { // Show full names. Con_Message("%s\n", token); } else { // Two on one line, clamp to 30 characters. Con_Message("%-30.30s", token); token = strtok(NULL, " "); if(token) Con_Message(" %-30.30s", token); Con_Message("\n"); } token = strtok(NULL, " "); } Con_Message(" GLU Version: %s\n", gluGetString(GLU_VERSION)); glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits); #ifndef USE_MULTITEXTURE maxTexUnits = 1; #endif // But sir, we are simple people; two units is enough. if(maxTexUnits > 2) maxTexUnits = 2; Con_Message(" Texture units: %i\n", maxTexUnits); Con_Message(" Maximum texture size: %i\n", maxTexSize); if(extAniso) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso); Con_Message(" Maximum anisotropy: %g\n", maxAniso); } //if(!noArrays) Con_Message(" Using vertex arrays.\n"); } free(extbuf); // Decide whether vertex arrays should be done manually or with real // OpenGL calls. InitArrays(); if(ArgCheck("-dumptextures")) { dumpTextures = DGL_TRUE; Con_Message(" Dumping textures (mipmap level zero).\n"); } if(extAniso && ArgExists("-anifilter")) { useAnisotropic = DGL_TRUE; Con_Message(" Using anisotropic texture filtering.\n"); } return DGL_OK; }
void CGapList::FillGap(uint64 partstart, uint64 partend) { if (!ArgCheck(partstart, partend)) { return; } // AddDebugLogLineN(logPartFile, CFormat(wxT(" FillGap: %5d - %5d")) % partstart % partend); // mark involved part(s) to be reexamined for completeness uint16 partlast = partend / PARTSIZE; for (uint16 part = partstart / PARTSIZE; part <= partlast; part++) { m_partsComplete[part] = unknown; } // also total gap size m_totalGapSizeValid = false; // find a place to start: // first gap which ends >= our part start iterator it = m_gaplist.lower_bound(partstart); while (it != m_gaplist.end()) { iterator it2 = it++; uint64 curGapStart = it2->second; uint64 curGapEnd = it2->first; if (curGapStart >= partstart) { if (curGapEnd <= partend) { // our part fills this gap completly m_gaplist.erase(it2); } else if (curGapStart <= partend) { // lower part of this gap is in the part - shrink gap: // (this is the most common case: curGapStart == partstart && curGapEnd > partend) it2->second = partend + 1; // end of our part was in the gap: we're done break; } else { // gap starts behind our part end: we're done break; } } else { // curGapStart < partstart if (curGapEnd > partend) { // our part is completely enclosed by the gap // cut it in two, leaving our part out: // shrink the gap so it becomes the second gap it2->second = partend + 1; // insert new first gap iterator it3(it2); if (it3 != m_gaplist.begin()) { --it3; } m_gaplist.insert(it3, std::pair<uint64,uint64>(partstart - 1, curGapStart)); // we're done break; } else if (curGapEnd >= partstart) { // upper part of this gap is in the part - shrink gap: // insert shorter gap iterator it3(it2); if (it3 != m_gaplist.begin()) { --it3; } m_gaplist.insert(it3, std::pair<uint64,uint64>(partstart - 1, curGapStart)); // and delete the old one m_gaplist.erase(it2); } // else: gap is before our part start (should not happen) } } }
//========================================================================== // ArgExists // Returns true if the given parameter exists in the program's command // line arguments, false if not. //========================================================================== int ArgExists(char *check) { return ArgCheck(check) != 0; }
/** * Initialize input. * * @return @c true, if successful. */ boolean I_Init(void) { HRESULT hr; if(initIOk) return true; // Already initialized. if(ArgCheck("-nowsk")) // No Windows system keys? { // Disable Alt-Tab, Alt-Esc, Ctrl-Alt-Del. A bit of a hack... SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, 0, 0); Con_Message("Windows system keys disabled.\n"); } // We'll create the DirectInput object. The only required input device // is the keyboard. The others are optional. dInput = NULL; if(FAILED (hr = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8, &dInput)) || FAILED(hr = IDirectInput8_Initialize(dInput, app.hInstance, DIRECTINPUT_VERSION))) { Con_Message("I_Init: DirectInput 8 init failed (0x%x).\n", hr); // Try DInput3 instead. // I'm not sure if this works correctly. if(FAILED (hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput2W, &dInput)) || FAILED(hr = IDirectInput2_Initialize(dInput, app.hInstance, 0x0300))) { Con_Message ("I_Init: Failed to create DirectInput 3 object (0x%x).\n", hr); return false; } Con_Message("I_Init: Using DirectInput 3.\n"); } if(!dInput) { Con_Message("I_Init: DirectInput init failed.\n"); return false; } if(!I_InitKeyboard()) return false; // We must have a keyboard! // Acquire the keyboard. IDirectInputDevice_Acquire(didKeyb); // Create the mouse and joystick devices. It doesn't matter if the init // fails for them. I_InitMouse(); I_InitJoystick(); initIOk = true; return true; }
boolean I_InitJoystick(void) { DIDEVICEINSTANCE ddi; int i, joyProp[] = { DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1) }; const char *axisName[] = { "X", "Y", "Z", "RX", "RY", "RZ", "Slider 1", "Slider 2" }; HWND hWnd; HRESULT hr; if(ArgCheck("-nojoy")) return false; hWnd = Sys_GetWindowHandle(mainWindowIdx); if(!hWnd) { Con_Error("I_InitJoystick: Main window not available, cannot init joystick."); return false; } // ddi will contain info for the joystick device. memset(&firstJoystick, 0, sizeof(firstJoystick)); memset(&ddi, 0, sizeof(ddi)); counter = 0; // Find the joystick we want by doing an enumeration. IDirectInput_EnumDevices(dInput, DI8DEVCLASS_GAMECTRL, I_JoyEnum, &ddi, DIEDFL_ALLDEVICES); // Was the joystick we want found? if(!ddi.dwSize) { // Use the default joystick. if(!firstJoystick.dwSize) return false; // Not found. Con_Message("I_InitJoystick: joydevice = %i, out of range.\n", joydevice); // Use the first joystick that was found. memcpy(&ddi, &firstJoystick, sizeof(ddi)); } // Show some info. Con_Message("I_InitJoystick: %s\n", ddi.tszProductName); // Create the joystick device. hr = IDirectInput8_CreateDevice(dInput, &ddi.guidInstance, &didJoy, 0); if(FAILED(hr)) { Con_Message("I_InitJoystick: Failed to create device (0x%x).\n", hr); return false; } // Set data format. if(FAILED(hr = IDirectInputDevice_SetDataFormat(didJoy, &c_dfDIJoystick))) { Con_Message("I_InitJoystick: Failed to set data format (0x%x).\n", hr); goto kill_joy; } // Set behaviour. if(FAILED (hr = IDirectInputDevice_SetCooperativeLevel(didJoy, hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND))) { Con_Message("I_InitJoystick: Failed to set co-op level (0x%x: %s).\n", hr, I_ErrorMsg(hr)); goto kill_joy; } // Set properties. for(i = 0; i < sizeof(joyProp) / sizeof(joyProp[0]); i++) { if(FAILED (hr = I_SetRangeProperty(didJoy, DIPROP_RANGE, DIPH_BYOFFSET, joyProp[i], IJOY_AXISMIN, IJOY_AXISMAX))) { if(verbose) Con_Message("I_InitJoystick: Failed to set %s " "range (0x%x: %s).\n", axisName[i], hr, I_ErrorMsg(hr)); } } // Set no dead zone. if(FAILED(hr = I_SetProperty(didJoy, DIPROP_DEADZONE, DIPH_DEVICE, 0, 0))) { Con_Message("I_InitJoystick: Failed to set dead zone (0x%x: %s).\n", hr, I_ErrorMsg(hr)); } // Set absolute mode. if(FAILED (hr = I_SetProperty(didJoy, DIPROP_AXISMODE, DIPH_DEVICE, 0, DIPROPAXISMODE_ABS))) { Con_Message ("I_InitJoystick: Failed to set absolute axis mode (0x%x: %s).\n", hr, I_ErrorMsg(hr)); } // Acquire it. IDirectInputDevice_Acquire(didJoy); // Initialization was successful. return true; kill_joy: I_SAFE_RELEASE(didJoy); return false; }