// // I_InitMouseDriver // // Instantiates the proper concrete MouseInput object based on the // mouse_driver cvar and stores a pointer to the object in mouse_input. // void I_InitMouseDriver() { I_ShutdownMouseDriver(); // ignore SDL mouse input for now... The mouse driver will change this if needed I_SetSDLIgnoreMouseEvents(); if (nomouse) return; // try to initialize the user's preferred mouse driver MouseDriverInfo_t* info = I_FindMouseDriverInfo(mouse_driver_id); if (info) { if (info->create != NULL) mouse_input = info->create(); if (mouse_input != NULL) Printf(PRINT_HIGH, "I_InitMouseDriver: Initializing %s input.\n", info->name); else Printf(PRINT_HIGH, "I_InitMouseDriver: Unable to initalize %s input.\n", info->name); } // fall back on SDLMouse if the preferred driver failed to initialize if (mouse_input == NULL) { mouse_input = SDLMouse::create(); if (mouse_input != NULL) Printf(PRINT_HIGH, "I_InitMouseDriver: Initializing SDL Mouse input as a fallback.\n"); else Printf(PRINT_HIGH, "I_InitMouseDriver: Unable to initialize SDL Mouse input as a fallback.\n"); } I_FlushInput(); I_ResumeMouse(); }
// // I_InitFocus // // Sets the initial value of window_focused. // static void I_InitFocus() { window_focused = I_CheckFocusState(); if (window_focused) { SDL_WM_GrabInput(SDL_GRAB_ON); I_ResumeMouse(); } else { SDL_WM_GrabInput(SDL_GRAB_OFF); I_PauseMouse(); } }
bool SDLVideo::SetMode(int width, int height, int bits, bool fullscreen) { Uint32 flags = (vid_vsync ? SDL_HWSURFACE | SDL_DOUBLEBUF : SDL_SWSURFACE); if (fullscreen && !vidModeList.empty()) flags |= SDL_FULLSCREEN; else flags |= SDL_RESIZABLE; if (fullscreen && bits == 8) flags |= SDL_HWPALETTE; // TODO: check for multicore flags |= SDL_ASYNCBLIT; // [SL] SDL_SetVideoMode reinitializes DirectInput if DirectX is being used. // This interferes with RawWin32Mouse's input handlers so we need to // disable them prior to reinitalizing DirectInput... I_PauseMouse(); int sbits = bits; #ifdef _WIN32 // fullscreen directx requires a 32-bit mode to fix broken palette // [Russell] - Use for gdi as well, fixes d2 map02 water if (fullscreen) sbits = 32; #endif #ifdef SDL_GL_SWAP_CONTROL SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vid_vsync); #endif if (!(sdlScreen = SDL_SetVideoMode(width, height, sbits, flags))) return false; // [SL] ...and re-enable RawWin32Mouse's input handlers after // DirectInput is reinitalized. I_ResumeMouse(); screenw = width; screenh = height; screenbits = bits; return true; }
// // I_UpdateInputGrabbing // // Determines if SDL should grab the mouse based on the game window having // focus and the status of the menu and console. // static void I_UpdateInputGrabbing() { #ifndef GCONSOLE bool can_grab = false; bool grabbed = SDL_WM_GrabInput(SDL_GRAB_QUERY); if (!window_focused) can_grab = false; else if (vid_fullscreen) can_grab = true; else if (nomouse) can_grab = false; else if (configuring_controls) can_grab = true; else if (menuactive || ConsoleState == c_down || paused) can_grab = false; else if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && !demoplayback) can_grab = true; // force I_ResumeMouse or I_PauseMouse if toggling between fullscreen/windowed static float prev_vid_fullscreen = vid_fullscreen; if (vid_fullscreen != prev_vid_fullscreen) grabbed = !can_grab; prev_vid_fullscreen = vid_fullscreen; // check if the window focus changed (or menu/console status changed) if (can_grab && !grabbed) { SDL_WM_GrabInput(SDL_GRAB_ON); I_ResumeMouse(); I_FlushInput(); } else if (grabbed && !can_grab) { SDL_WM_GrabInput(SDL_GRAB_OFF); I_PauseMouse(); } #endif }
// // I_GetEvent // void I_GetEvent (void) { event_t event; event_t mouseevent = {ev_mouse, 0, 0, 0}; static int mbuttons = 0; int sendmouseevent = 0; SDL_Event ev; if (!havefocus) I_PauseMouse(); else { I_ResumeMouse(); } while(SDL_PollEvent(&ev)) { event.data1 = event.data2 = event.data3 = 0; switch(ev.type) { case SDL_QUIT: AddCommandString("menu_quit"); break; // Resizable window mode resolutions case SDL_VIDEORESIZE: { if (!vid_fullscreen) { char Command[64]; mousegrabbed = false; snprintf(Command, sizeof(Command), "vid_setmode %d %d", ev.resize.w, ev.resize.h); AddCommandString(Command); vid_defwidth.Set((float)ev.resize.w); vid_defheight.Set((float)ev.resize.h); } } break; case SDL_ACTIVEEVENT: // need to update our focus state UpdateFocus(); break; case SDL_KEYDOWN: event.type = ev_keydown; event.data1 = ev.key.keysym.sym; if(event.data1 >= SDLK_KP0 && event.data1 <= SDLK_KP9) event.data2 = event.data3 = '0' + (event.data1 - SDLK_KP0); else if(event.data1 == SDLK_KP_PERIOD) event.data2 = event.data3 = '.'; else if(event.data1 == SDLK_KP_DIVIDE) event.data2 = event.data3 = '/'; else if(event.data1 == SDLK_KP_ENTER) event.data2 = event.data3 = '\r'; else if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; #ifdef _XBOX // Fix for ENTER key on Xbox if(event.data1 == SDLK_RETURN) event.data2 = event.data3 = '\r'; #endif #ifdef WIN32 //HeX9109: Alt+F4 for cheats! Thanks Spleen if(event.data1 == SDLK_F4 && SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) AddCommandString("menu_quit"); // SoM: Ignore the tab portion of alt-tab presses if(event.data1 == SDLK_TAB && SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) event.data1 = event.data2 = event.data3 = 0; else #endif D_PostEvent(&event); break; case SDL_KEYUP: event.type = ev_keyup; event.data1 = ev.key.keysym.sym; if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; D_PostEvent(&event); break; case SDL_MOUSEMOTION: if(flushmouse) { flushmouse = false; break; } if (!havefocus) break; // denis - ignore artificially inserted events (see SDL_WarpMouse below) if(ev.motion.x == screen->width/2 && ev.motion.y == screen->height/2) { break; } mouseevent.data2 += AccelerateMouse(ev.motion.xrel); mouseevent.data3 -= AccelerateMouse(ev.motion.yrel); sendmouseevent = 1; break; case SDL_MOUSEBUTTONDOWN: if(nomouse || !havefocus) break; event.type = ev_keydown; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons |= 1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons |= 2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons |= 4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; case SDL_MOUSEBUTTONUP: if(nomouse || !havefocus) break; event.type = ev_keyup; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons &= ~1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons &= ~2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons &= ~4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; case SDL_JOYBUTTONDOWN: if(ev.jbutton.which == joy_active) { event.type = ev_keydown; event.data1 = ev.jbutton.button + KEY_JOY1; event.data2 = event.data1; D_PostEvent(&event); break; } case SDL_JOYBUTTONUP: if(ev.jbutton.which == joy_active) { event.type = ev_keyup; event.data1 = ev.jbutton.button + KEY_JOY1; event.data2 = event.data1; D_PostEvent(&event); break; } case SDL_JOYAXISMOTION: if(ev.jaxis.which == joy_active) { event.type = ev_joystick; event.data1 = 0; event.data2 = ev.jaxis.axis; if( (ev.jaxis.value < JOY_DEADZONE) && (ev.jaxis.value > -JOY_DEADZONE) ) event.data3 = 0; else event.data3 = ev.jaxis.value; D_PostEvent(&event); break; } case SDL_JOYHATMOTION: if(ev.jhat.which == joy_active) { // Each of these need to be tested because more than one can be pressed and a // unique event is needed for each if(ev.jhat.value & SDL_HAT_UP) RegisterJoystickEvent(&ev, SDL_HAT_UP); if(ev.jhat.value & SDL_HAT_RIGHT) RegisterJoystickEvent(&ev, SDL_HAT_RIGHT); if(ev.jhat.value & SDL_HAT_DOWN) RegisterJoystickEvent(&ev, SDL_HAT_DOWN); if(ev.jhat.value & SDL_HAT_LEFT) RegisterJoystickEvent(&ev, SDL_HAT_LEFT); break; } }; } if(!nomouse) { if(sendmouseevent) { mouseevent.data1 = mbuttons; D_PostEvent(&mouseevent); } if(mousegrabbed && screen) { SDL_WarpMouse(screen->width/ 2, screen->height / 2); } } if(use_joystick) UpdateJoystickEvents(); }
// // I_GetEvent // void I_GetEvent (void) { event_t event; event_t mouseevent = {ev_mouse, 0, 0, 0}; static int mbuttons = 0; int sendmouseevent = 0; SDL_Event ev; if (!(SDL_GetAppState()&SDL_APPINPUTFOCUS) && havefocus) { havefocus = false; UngrabMouse(); SetCursorState(true); } else if((SDL_GetAppState()&SDL_APPINPUTFOCUS) && !havefocus) { havefocus = true; if(!mousepaused) I_ResumeMouse(); } while(SDL_PollEvent(&ev)) { event.data1 = event.data2 = event.data3 = 0; switch(ev.type) { case SDL_QUIT: AddCommandString("quit"); break; case SDL_KEYDOWN: event.type = ev_keydown; event.data1 = ev.key.keysym.sym; if(event.data1 >= SDLK_KP0 && event.data1 <= SDLK_KP9) event.data2 = event.data3 = '0' + (event.data1 - SDLK_KP0); else if(event.data1 == SDLK_KP_PERIOD) event.data2 = event.data3 = '.'; else if(event.data1 == SDLK_KP_DIVIDE) event.data2 = event.data3 = '/'; else if(event.data1 == SDLK_KP_ENTER) event.data2 = event.data3 = '\r'; else if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; #ifdef WIN32 // SoM: Ignore the tab portion of alt-tab presses if(event.data1 == SDLK_TAB && SDL_GetModState() & (KMOD_LALT | KMOD_RALT)) event.data1 = event.data2 = event.data3 = 0; else #endif D_PostEvent(&event); break; case SDL_KEYUP: event.type = ev_keyup; event.data1 = ev.key.keysym.sym; if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) event.data2 = event.data3 = ev.key.keysym.unicode; else event.data2 = event.data3 = 0; D_PostEvent(&event); break; case SDL_MOUSEMOTION: if(flushmouse) { flushmouse = false; break; } // denis - ignore artificially inserted events (see SDL_WarpMouse below) if(ev.motion.x == screen->width/2 && ev.motion.y == screen->height/2) { break; } mouseevent.data2 += AccelerateMouse(ev.motion.xrel); mouseevent.data3 -= AccelerateMouse(ev.motion.yrel); sendmouseevent = 1; break; case SDL_MOUSEBUTTONDOWN: if(nomouse) break; event.type = ev_keydown; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons |= 1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons |= 2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons |= 4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; case SDL_MOUSEBUTTONUP: if(nomouse) break; event.type = ev_keyup; if(ev.button.button == SDL_BUTTON_LEFT) { event.data1 = KEY_MOUSE1; mbuttons &= ~1; } else if(ev.button.button == SDL_BUTTON_RIGHT) { event.data1 = KEY_MOUSE2; mbuttons &= ~2; } else if(ev.button.button == SDL_BUTTON_MIDDLE) { event.data1 = KEY_MOUSE3; mbuttons &= ~4; } else if(ev.button.button == SDL_BUTTON_WHEELUP) event.data1 = KEY_MWHEELUP; else if(ev.button.button == SDL_BUTTON_WHEELDOWN) event.data1 = KEY_MWHEELDOWN; D_PostEvent(&event); break; }; } if(!nomouse) { if(sendmouseevent) { mouseevent.data1 = mbuttons; D_PostEvent(&mouseevent); } if(mousegrabbed && screen) { SDL_WarpMouse(screen->width/ 2, screen->height / 2); } } }
// // SDLMouse::SDLMouse // SDLMouse::SDLMouse() : mActive(false) { I_ResumeMouse(); }
// // ISDL12Window::setMode // // Sets the window size to the specified size and frees the existing primary // surface before instantiating a new primary surface. This function performs // no sanity checks on the desired video mode. // // NOTE: If a hardware surface is obtained or the surface's screen pitch // will create cache thrashing (tested by pitch & 511 == 0), a SDL software // surface will be created and used for drawing video frames. This software // surface is then blitted to the screen at the end of the frame, prior to // calling SDL_Flip. // bool ISDL12Window::setMode(uint16_t video_width, uint16_t video_height, uint8_t video_bpp, bool video_fullscreen, bool vsync) { uint32_t flags = 0; if (vsync) flags |= SDL_HWSURFACE | SDL_DOUBLEBUF; else flags |= SDL_SWSURFACE; if (video_fullscreen) flags |= SDL_FULLSCREEN; else flags |= SDL_RESIZABLE; if (video_fullscreen && video_bpp == 8) flags |= SDL_HWPALETTE; // TODO: check for multicore flags |= SDL_ASYNCBLIT; //if (video_fullscreen) // flags = ((flags & (~SDL_SWSURFACE)) | SDL_HWSURFACE); #ifdef SDL_GL_SWAP_CONTROL SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync); #endif // [SL] SDL_SetVideoMode reinitializes DirectInput if DirectX is being used. // This interferes with RawWin32Mouse's input handlers so we need to // disable them prior to reinitalizing DirectInput... I_PauseMouse(); SDL_Surface* sdl_surface = SDL_SetVideoMode(video_width, video_height, video_bpp, flags); if (sdl_surface == NULL) { I_FatalError("I_SetVideoMode: unable to set video mode %ux%ux%u (%s): %s\n", video_width, video_height, video_bpp, video_fullscreen ? "fullscreen" : "windowed", SDL_GetError()); return false; } assert(sdl_surface == SDL_GetVideoSurface()); // [SL] ...and re-enable RawWin32Mouse's input handlers after // DirectInput is reinitalized. I_ResumeMouse(); PixelFormat format; I_BuildPixelFormatFromSDLSurface(sdl_surface, &format); // just in case SDL couldn't set the exact video mode we asked for... mWidth = sdl_surface->w; mHeight = sdl_surface->h; mBitsPerPixel = format.getBitsPerPixel(); mIsFullScreen = (sdl_surface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN; mUseVSync = vsync; if (SDL_MUSTLOCK(sdl_surface)) SDL_LockSurface(sdl_surface); // lock prior to accessing pixel format delete mSurfaceManager; bool got_hardware_surface = (sdl_surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE; bool create_software_surface = (sdl_surface->pitch & 511) == 0 || // pitch is a multiple of 512 (thrashes the cache) got_hardware_surface; // drawing directly to hardware surfaces is slower if (create_software_surface) mSurfaceManager = new ISDL12SoftwareWindowSurfaceManager(mWidth, mHeight, &format); else mSurfaceManager = new ISDL12DirectWindowSurfaceManager(mWidth, mHeight, &format); assert(mSurfaceManager != NULL); assert(getPrimarySurface() != NULL); if (SDL_MUSTLOCK(sdl_surface)) SDL_UnlockSurface(sdl_surface); mVideoMode = IVideoMode(mWidth, mHeight, mBitsPerPixel, mIsFullScreen); assert(mWidth >= 0 && mWidth <= MAXWIDTH); assert(mHeight >= 0 && mHeight <= MAXHEIGHT); assert(mBitsPerPixel == 8 || mBitsPerPixel == 32); // Tell argb_t the pixel format if (format.getBitsPerPixel() == 32) argb_t::setChannels(format.getAPos(), format.getRPos(), format.getGPos(), format.getBPos()); else argb_t::setChannels(3, 2, 1, 0); // [SL] SDL can create SDL_VIDEORESIZE events in response to SDL_SetVideoMode // and we need to filter those out. mIgnoreResize = true; return true; }