Example #1
0
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;
}
Example #2
0
//===========================================================================
// 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;
}
Example #3
0
//==========================================================================
// 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;
}
Example #4
0
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;
}
Example #5
0
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));
}
Example #6
0
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;
}
Example #7
0
/**
 * 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
        }
    }
}
Example #8
0
/*
 * 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");
}
Example #9
0
/**
 * 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);
    }
}
Example #10
0
//===========================================================================
// 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;
}
Example #11
0
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)
		}
	}
}
Example #12
0
//==========================================================================
// 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;
}
Example #13
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;
}
Example #14
0
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;
}