bool SpringApp::MainEventHandler(const SDL_Event& event) { switch (event.type) { case SDL_WINDOWEVENT: { switch (event.window.event) { case SDL_WINDOWEVENT_MOVED: { SaveWindowPosition(); } break; //case SDL_WINDOWEVENT_RESIZED: //this is event is always preceded by: case SDL_WINDOWEVENT_SIZE_CHANGED: { Watchdog::ClearTimer(WDT_MAIN, true); SaveWindowPosition(); InitOpenGL(); activeController->ResizeEvent(); mouseInput->InstallWndCallback(); } break; case SDL_WINDOWEVENT_SHOWN: { // reactivate sounds and other globalRendering->active = true; if (ISound::IsInitialized()) { sound->Iconified(false); } if (globalRendering->fullScreen) { FBO::GLContextReinit(); } } break; case SDL_WINDOWEVENT_HIDDEN: { // deactivate sounds and other globalRendering->active = false; if (ISound::IsInitialized()) { sound->Iconified(true); } if (globalRendering->fullScreen) { FBO::GLContextLost(); } } break; case SDL_WINDOWEVENT_FOCUS_GAINED: { // update keydown table KeyInput::Update(0, ((keyBindings != NULL)? keyBindings->GetFakeMetaKey(): -1)); } break; case SDL_WINDOWEVENT_FOCUS_LOST: { Watchdog::ClearTimer(WDT_MAIN, true); // SDL has some bug and does not update modstate on alt+tab/minimize etc. //FIXME check if still happens with SDL2 (2013) SDL_SetModState((SDL_Keymod)(SDL_GetModState() & (KMOD_NUM | KMOD_CAPS | KMOD_MODE))); // release all keyboard keys KeyInput::ReleaseAllKeys(); // simulate mouse release to prevent hung buttons for (int i = 1; i <= NUM_BUTTONS; ++i) { if (!mouse) continue; if (!mouse->buttons[i].pressed) continue; SDL_Event event; event.type = event.button.type = SDL_MOUSEBUTTONUP; event.button.state = SDL_RELEASED; event.button.which = 0; event.button.button = i; event.button.x = -1; event.button.y = -1; SDL_PushEvent(&event); } // unlock mouse if (mouse && mouse->locked) { mouse->ToggleMiddleClickScroll(); } // and make sure to un-capture mouse if (SDL_GetWindowGrab(window)) SDL_SetWindowGrab(window, SDL_FALSE); break; } case SDL_WINDOWEVENT_CLOSE: { gu->globalQuit = true; break; } }; } break; case SDL_QUIT: { gu->globalQuit = true; } break; case SDL_TEXTEDITING: { //FIXME don't known when this is called } break; case SDL_TEXTINPUT: { if (!activeController) { break; } std::string utf8Text = event.text.text; const bool catched = eventHandler.TextInput(utf8Text); if (activeController->userWriting && !catched){ auto ac = activeController; if (ac->ignoreNextChar) { utf8Text = utf8Text.substr(Utf8NextChar(utf8Text, 0)); } ac->writingPos = Clamp<int>(ac->writingPos, 0, ac->userInput.length()); ac->userInput.insert(ac->writingPos, utf8Text); ac->writingPos += utf8Text.length(); } } break; case SDL_KEYDOWN: { KeyInput::Update(event.key.keysym.sym, ((keyBindings != NULL)? keyBindings->GetFakeMetaKey(): -1)); if (activeController) { activeController->KeyPressed(KeyInput::GetNormalizedKeySymbol(event.key.keysym.sym), event.key.repeat); } } break; case SDL_KEYUP: { KeyInput::Update(event.key.keysym.sym, ((keyBindings != NULL)? keyBindings->GetFakeMetaKey(): -1)); if (activeController) { if (activeController->ignoreNextChar) { activeController->ignoreNextChar = false; } activeController->KeyReleased(KeyInput::GetNormalizedKeySymbol(event.key.keysym.sym)); } } break; }; return false; }
static int _process_mouse_event(void) { SDLMod keymods; short shift_flags = 0; memset(&pdc_mouse_status, 0, sizeof(MOUSE_STATUS)); keymods = SDL_GetModState(); if (keymods & KMOD_SHIFT) shift_flags |= BUTTON_SHIFT; if (keymods & KMOD_CTRL) shift_flags |= BUTTON_CONTROL; if (keymods & KMOD_ALT) shift_flags |= BUTTON_ALT; if (event.type == SDL_MOUSEMOTION) { int i; pdc_mouse_status.x = event.motion.x / pdc_fwidth; pdc_mouse_status.y = event.motion.y / pdc_fheight; if (!event.motion.state || (pdc_mouse_status.x == old_mouse_status.x && pdc_mouse_status.y == old_mouse_status.y)) return -1; pdc_mouse_status.changes = PDC_MOUSE_MOVED; for (i = 0; i < 3; i++) { if (event.motion.state & SDL_BUTTON(i + 1)) { pdc_mouse_status.button[i] = BUTTON_MOVED | shift_flags; pdc_mouse_status.changes |= (1 << i); } } } else { short action = (event.button.state == SDL_PRESSED) ? BUTTON_PRESSED : BUTTON_RELEASED; Uint8 btn = event.button.button; /* handle scroll wheel */ if ((btn >= 4 && btn <= 7) && action == BUTTON_RELEASED) { pdc_mouse_status.x = pdc_mouse_status.y = -1; switch (btn) { case 4: pdc_mouse_status.changes = PDC_MOUSE_WHEEL_UP; break; case 5: pdc_mouse_status.changes = PDC_MOUSE_WHEEL_DOWN; break; case 6: pdc_mouse_status.changes = PDC_MOUSE_WHEEL_LEFT; break; case 7: pdc_mouse_status.changes = PDC_MOUSE_WHEEL_RIGHT; } SP->key_code = TRUE; return KEY_MOUSE; } if (btn < 1 || btn > 3) return -1; /* check for a click -- a press followed immediately by a release */ if (action == BUTTON_PRESSED && SP->mouse_wait) { SDL_Event rel; napms(SP->mouse_wait); if (SDL_PollEvent(&rel)) { if (rel.type == SDL_MOUSEBUTTONUP && rel.button.button == btn) action = BUTTON_CLICKED; else SDL_PushEvent(&rel); } } pdc_mouse_status.x = event.button.x / pdc_fwidth; pdc_mouse_status.y = event.button.y / pdc_fheight; btn--; pdc_mouse_status.button[btn] = action | shift_flags; pdc_mouse_status.changes = (1 << btn); } old_mouse_status = pdc_mouse_status; SP->key_code = TRUE; return KEY_MOUSE; }
void movie_player::play(int iChannel) { SDL_Event endEvent; endEvent.type = SDL_USEREVENT_MOVIE_OVER; SDL_PushEvent(&endEvent); }
static int SDL_CompatEventFilter(void *userdata, SDL_Event * event) { SDL_Event fake; switch (event->type) { case SDL_WINDOWEVENT: switch (event->window.event) { case SDL_WINDOWEVENT_EXPOSED: if (!SDL_HasEvent(SDL_VIDEOEXPOSE)) { fake.type = SDL_VIDEOEXPOSE; SDL_PushEvent(&fake); } break; case SDL_WINDOWEVENT_RESIZED: SDL_FlushEvent(SDL_VIDEORESIZE); /* We don't want to expose that the window width and height will be different if we don't get the desired fullscreen mode. */ if (SDL_VideoWindow && !(SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN)) { fake.type = SDL_VIDEORESIZE; fake.resize.w = event->window.data1; fake.resize.h = event->window.data2; SDL_PushEvent(&fake); } break; case SDL_WINDOWEVENT_MINIMIZED: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 0; fake.active.state = SDL_APPACTIVE; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_RESTORED: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 1; fake.active.state = SDL_APPACTIVE; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_ENTER: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 1; fake.active.state = SDL_APPMOUSEFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_LEAVE: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 0; fake.active.state = SDL_APPMOUSEFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_FOCUS_GAINED: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 1; fake.active.state = SDL_APPINPUTFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_FOCUS_LOST: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 0; fake.active.state = SDL_APPINPUTFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_CLOSE: fake.type = SDL_QUIT; SDL_PushEvent(&fake); break; } case SDL_KEYDOWN: case SDL_KEYUP: { Uint32 unicode = 0; if (event->key.type == SDL_KEYDOWN && event->key.keysym.sym < 256) { unicode = event->key.keysym.sym; if (unicode >= 'a' && unicode <= 'z') { int shifted = !!(event->key.keysym.mod & KMOD_SHIFT); int capslock = !!(event->key.keysym.mod & KMOD_CAPS); if ((shifted ^ capslock) != 0) { unicode = SDL_toupper(unicode); } } } if (unicode) { event->key.keysym.unicode = unicode; } break; } case SDL_TEXTINPUT: { /* FIXME: Generate an old style key repeat event if needed */ //printf("TEXTINPUT: '%s'\n", event->text.text); break; } case SDL_MOUSEMOTION: { event->motion.x -= SDL_VideoViewport.x; event->motion.y -= SDL_VideoViewport.y; break; } case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { event->button.x -= SDL_VideoViewport.x; event->button.y -= SDL_VideoViewport.y; break; } case SDL_MOUSEWHEEL: { Uint8 button; int x, y; if (event->wheel.y == 0) { break; } SDL_GetMouseState(&x, &y); if (event->wheel.y > 0) { button = SDL_BUTTON_WHEELUP; } else { button = SDL_BUTTON_WHEELDOWN; } fake.button.button = button; fake.button.x = x; fake.button.y = y; fake.button.windowID = event->wheel.windowID; fake.type = SDL_MOUSEBUTTONDOWN; fake.button.state = SDL_PRESSED; SDL_PushEvent(&fake); fake.type = SDL_MOUSEBUTTONUP; fake.button.state = SDL_RELEASED; SDL_PushEvent(&fake); break; } } return 1; }
/** * Thread method to wait for XPCOM events and notify the SDL thread. * * @returns Error code * @param thread Thread ID * @param pvUser User specific parameter, the file descriptor * of the event queue socket */ DECLCALLBACK(int) xpcomEventThread(RTTHREAD hThreadSelf, void *pvUser) { RT_NOREF(hThreadSelf); int eqFD = (intptr_t)pvUser; unsigned cErrors = 0; int rc; /* Wait with the processing till the main thread needs it. */ RTSemEventWait(g_EventSemXPCOMQueueThread, 2500); do { fd_set fdset; FD_ZERO(&fdset); FD_SET(eqFD, &fdset); int n = select(eqFD + 1, &fdset, NULL, NULL, NULL); /* are there any events to process? */ if ((n > 0) && !g_fTerminateXPCOMQueueThread) { /* * Wait until all XPCOM events are processed. 1s just for sanity. */ int iWait = 1000; /* * Don't post an event if there is a pending XPCOM event to prevent an * overflow of the SDL event queue. */ if (g_s32XPCOMEventsPending < 1) { /* * Post the event and wait for it to be processed. If we don't wait, * we'll flood the queue on SMP systems and when the main thread is busy. * In the event of a push error, we'll yield the timeslice and retry. */ SDL_Event event = {0}; event.type = SDL_USEREVENT; event.user.type = SDL_USER_EVENT_XPCOM_EVENTQUEUE; rc = SDL_PushEvent(&event); if (!rc) { /* success */ ASMAtomicIncS32(&g_s32XPCOMEventsPending); cErrors = 0; } else { /* failure */ cErrors++; if (!RTThreadYield()) RTThreadSleep(2); iWait = (cErrors >= 10) ? RT_MIN(cErrors - 8, 50) : 0; } } else Log2(("not enqueueing SDL XPCOM event (%d)\n", g_s32XPCOMEventsPending)); if (iWait) RTSemEventWait(g_EventSemXPCOMQueueThread, iWait); } } while (!g_fTerminateXPCOMQueueThread); return VINF_SUCCESS; }
int queue_picture(VideoState *is, AVFrame *pFrame, double pts) { VideoPicture *vp; //int dst_pix_fmt; AVPicture pict; /* wait until we have space for a new pic */ SDL_LockMutex(is->pictq_mutex); while(is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&!is->quit) { SDL_CondWait(is->pictq_cond, is->pictq_mutex); } SDL_UnlockMutex(is->pictq_mutex); if(is->quit) return -1; // windex is set to 0 initially vp = &is->pictq[is->pictq_windex]; /* allocate or resize the buffer! */ if(!vp->bmp ||vp->width != is->video_st->codec->width ||vp->height != is->video_st->codec->height) { SDL_Event event; vp->allocated = 0; /* we have to do it in the main thread */ event.type = FF_ALLOC_EVENT; event.user.data1 = is; SDL_PushEvent(&event); /* wait until we have a picture allocated */ SDL_LockMutex(is->pictq_mutex); while(!vp->allocated && !is->quit) { SDL_CondWait(is->pictq_cond, is->pictq_mutex); } SDL_UnlockMutex(is->pictq_mutex); if(is->quit) { return -1; } } /* We have a place to put our picture on the queue */ /* If we are skipping a frame, do we set this to null but still return vp->allocated = 1? */ if(vp->bmp) { SDL_LockYUVOverlay(vp->bmp); //dst_pix_fmt = PIX_FMT_YUV420P; /* point pict at the queue */ pict.data[0] = vp->bmp->pixels[0]; pict.data[1] = vp->bmp->pixels[2]; pict.data[2] = vp->bmp->pixels[1]; pict.linesize[0] = vp->bmp->pitches[0]; pict.linesize[1] = vp->bmp->pitches[2]; pict.linesize[2] = vp->bmp->pitches[1]; // Convert the image into YUV format that SDL uses sws_scale(is->sws_ctx,(uint8_t const * const *)pFrame->data, pFrame->linesize, 0, is->video_st->codec->height, pict.data, pict.linesize ); SDL_UnlockYUVOverlay(vp->bmp); AVPicture dstPict=pict; //avpicture_alloc(dstPict,PIX_FMT_YUV420P,640,320); if(av_picture_crop(&dstPict,&pict,AV_PIX_FMT_YUV420P10 ,104,80)==-1); printf("ss\n"); //avpicture_free(dstPict); ////截图操作 //save_frame(pict,vp->width,vp->height); vp->pts = pts; /* now we inform our display thread that we have a pic ready */ if(++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) { is->pictq_windex = 0; } SDL_LockMutex(is->pictq_mutex); is->pictq_size++; SDL_UnlockMutex(is->pictq_mutex); } return 0; }
int queue_picture(VideoState *is, AVFrame *pFrame) { VideoPicture *vp; AVPicture pict; /* wait until we have space for a new pic */ SDL_LockMutex(is->pictq_mutex); while(is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !is->quit) { SDL_CondWait(is->pictq_cond, is->pictq_mutex); } SDL_UnlockMutex(is->pictq_mutex); if(is->quit) return -1; // windex is set to 0 initially vp = &is->pictq[is->pictq_windex]; /* allocate or resize the buffer! */ if(!vp->bmp ||vp->width != is->video_st->codec->width || vp->height != is->video_st->codec->height) { SDL_Event event; vp->allocated = 0; /* we have to do it in the main thread */ event.type = FF_ALLOC_EVENT; event.user.data1 = is; SDL_PushEvent(&event); /* wait until we have a picture allocated */ SDL_LockMutex(is->pictq_mutex); while(!vp->allocated && !is->quit) { SDL_CondWait(is->pictq_cond, is->pictq_mutex); } SDL_UnlockMutex(is->pictq_mutex); if(is->quit) { return -1; } } /* We have a place to put our picture on the queue */ if(vp->bmp) { SDL_LockYUVOverlay(vp->bmp); /* point pict at the queue */ pict.data[0] = vp->bmp->pixels[0]; pict.data[1] = vp->bmp->pixels[2]; pict.data[2] = vp->bmp->pixels[1]; pict.linesize[0] = vp->bmp->pitches[0]; pict.linesize[1] = vp->bmp->pitches[2]; pict.linesize[2] = vp->bmp->pitches[1]; // Convert the image into YUV format that SDL uses sws_scale ( is->sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, is->video_st->codec->height, pict.data, pict.linesize ); SDL_UnlockYUVOverlay(vp->bmp); /* now we inform our display thread that we have a pic ready */ if(++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) { is->pictq_windex = 0; } SDL_LockMutex(is->pictq_mutex); is->pictq_size++; SDL_UnlockMutex(is->pictq_mutex); } return 0; }
static int SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; Uint32 type; Uint32 buttonstate = mouse->buttonstate; /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */ if (mouse->mouse_touch_events) { if (mouseID != SDL_TOUCH_MOUSEID && button == SDL_BUTTON_LEFT) { if (state == SDL_PRESSED) { track_mouse_down = SDL_TRUE; } else { track_mouse_down = SDL_FALSE; } if (window) { float fx = (float)mouse->x / (float)window->w; float fy = (float)mouse->y / (float)window->h; SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, track_mouse_down, fx, fy, 1.0f); } } } /* Figure out which event to perform */ switch (state) { case SDL_PRESSED: type = SDL_MOUSEBUTTONDOWN; buttonstate |= SDL_BUTTON(button); break; case SDL_RELEASED: type = SDL_MOUSEBUTTONUP; buttonstate &= ~SDL_BUTTON(button); break; default: /* Invalid state -- bail */ return 0; } /* We do this after calculating buttonstate so button presses gain focus */ if (window && state == SDL_PRESSED) { SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); } if (buttonstate == mouse->buttonstate) { /* Ignore this event, no state change */ return 0; } mouse->buttonstate = buttonstate; if (clicks < 0) { SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); if (clickstate) { if (state == SDL_PRESSED) { Uint32 now = SDL_GetTicks(); if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) || SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius || SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) { clickstate->click_count = 0; } clickstate->last_timestamp = now; clickstate->last_x = mouse->x; clickstate->last_y = mouse->y; if (clickstate->click_count < 255) { ++clickstate->click_count; } } clicks = clickstate->click_count; } else { clicks = 1; } } /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(type) == SDL_ENABLE) { SDL_Event event; event.type = type; event.button.windowID = mouse->focus ? mouse->focus->id : 0; event.button.which = mouseID; event.button.state = state; event.button.button = button; event.button.clicks = (Uint8) SDL_min(clicks, 255); event.button.x = mouse->x; event.button.y = mouse->y; posted = (SDL_PushEvent(&event) > 0); } /* We do this after dispatching event so button releases can lose focus */ if (window && state == SDL_RELEASED) { SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); } return posted; }
int SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, int data2) { int posted; if (!window) { return 0; } switch (windowevent) { case SDL_WINDOWEVENT_SHOWN: if (window->flags & SDL_WINDOW_SHOWN) { return 0; } window->flags &= ~SDL_WINDOW_HIDDEN; window->flags |= SDL_WINDOW_SHOWN; SDL_OnWindowShown(window); break; case SDL_WINDOWEVENT_HIDDEN: if (!(window->flags & SDL_WINDOW_SHOWN)) { return 0; } window->flags &= ~SDL_WINDOW_SHOWN; window->flags |= SDL_WINDOW_HIDDEN; SDL_OnWindowHidden(window); break; case SDL_WINDOWEVENT_MOVED: if (SDL_WINDOWPOS_ISUNDEFINED(data1) || SDL_WINDOWPOS_ISUNDEFINED(data2)) { return 0; } if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { window->windowed.x = data1; window->windowed.y = data2; } if (data1 == window->x && data2 == window->y) { return 0; } window->x = data1; window->y = data2; break; case SDL_WINDOWEVENT_RESIZED: if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { window->windowed.w = data1; window->windowed.h = data2; } if (data1 == window->w && data2 == window->h) { return 0; } window->w = data1; window->h = data2; SDL_OnWindowResized(window); break; case SDL_WINDOWEVENT_MINIMIZED: if (window->flags & SDL_WINDOW_MINIMIZED) { return 0; } window->flags |= SDL_WINDOW_MINIMIZED; SDL_OnWindowMinimized(window); break; case SDL_WINDOWEVENT_MAXIMIZED: if (window->flags & SDL_WINDOW_MAXIMIZED) { return 0; } window->flags |= SDL_WINDOW_MAXIMIZED; break; case SDL_WINDOWEVENT_RESTORED: if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) { return 0; } window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED); SDL_OnWindowRestored(window); break; case SDL_WINDOWEVENT_ENTER: if (window->flags & SDL_WINDOW_MOUSE_FOCUS) { return 0; } window->flags |= SDL_WINDOW_MOUSE_FOCUS; break; case SDL_WINDOWEVENT_LEAVE: if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) { return 0; } window->flags &= ~SDL_WINDOW_MOUSE_FOCUS; break; case SDL_WINDOWEVENT_FOCUS_GAINED: if (window->flags & SDL_WINDOW_INPUT_FOCUS) { return 0; } window->flags |= SDL_WINDOW_INPUT_FOCUS; SDL_OnWindowFocusGained(window); break; case SDL_WINDOWEVENT_FOCUS_LOST: if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { return 0; } window->flags &= ~SDL_WINDOW_INPUT_FOCUS; SDL_OnWindowFocusLost(window); break; } /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) { SDL_Event event; event.type = SDL_WINDOWEVENT; event.window.event = windowevent; event.window.data1 = data1; event.window.data2 = data2; event.window.windowID = window->id; /* Fixes queue overflow with resize events that aren't processed */ if (windowevent == SDL_WINDOWEVENT_RESIZED || windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) { SDL_FilterEvents(RemovePendingSizeEvents, &event); } if (windowevent == SDL_WINDOWEVENT_MOVED) { SDL_FilterEvents(RemovePendingMoveEvents, &event); } posted = (SDL_PushEvent(&event) > 0); } if (windowevent == SDL_WINDOWEVENT_CLOSE) { if ( !window->prev && !window->next ) { // This is the last window in the list so send the SDL_QUIT event SDL_SendQuit(); } } return (posted); }
int main(int argc, char* argv[]) { unsigned int width = 0; unsigned int height = 0; std::locale::global(boost::locale::generator().generate("")); boost::filesystem::path::imbue(std::locale()); if(!parseArgs(argc, argv, &width, &height)) return 0; // only show the console on Windows if HideConsole is false #ifdef WIN32 // MSVC has a "SubSystem" option, with two primary options: "WINDOWS" and "CONSOLE". // In "WINDOWS" mode, no console is automatically created for us. This is good, // because we can choose to only create the console window if the user explicitly // asks for it, preventing it from flashing open and then closing. // In "CONSOLE" mode, a console is always automatically created for us before we // enter main. In this case, we can only hide the console after the fact, which // will leave a brief flash. // TL;DR: You should compile ES under the "WINDOWS" subsystem. // I have no idea how this works with non-MSVC compilers. if(!Settings::getInstance()->getBool("HideConsole")) { // we want to show the console // if we're compiled in "CONSOLE" mode, this is already done. // if we're compiled in "WINDOWS" mode, no console is created for us automatically; // the user asked for one, so make one and then hook stdin/stdout/sterr up to it if(AllocConsole()) // should only pass in "WINDOWS" mode { freopen("CONIN$", "r", stdin); freopen("CONOUT$", "wb", stdout); freopen("CONOUT$", "wb", stderr); } }else{ // we want to hide the console // if we're compiled with the "WINDOWS" subsystem, this is already done. // if we're compiled with the "CONSOLE" subsystem, a console is already created; // it'll flash open, but we hide it nearly immediately if(GetConsoleWindow()) // should only pass in "CONSOLE" mode ShowWindow(GetConsoleWindow(), SW_HIDE); } #endif //if ~/.emulationstation doesn't exist and cannot be created, bail if(!verifyHomeFolderExists()) return 1; //start the logger Log::open(); LOG(LogInfo) << "EmulationStation - v" << PROGRAM_VERSION_STRING << ", built " << PROGRAM_BUILT_STRING; //always close the log on exit atexit(&onExit); Window window; ViewController::init(&window); window.pushGui(ViewController::get()); if(!scrape_cmdline) { if(!window.init(width, height)) { LOG(LogError) << "Window failed to initialize!"; return 1; } std::string glExts = (const char*)glGetString(GL_EXTENSIONS); LOG(LogInfo) << "Checking available OpenGL extensions..."; LOG(LogInfo) << " ARB_texture_non_power_of_two: " << (glExts.find("ARB_texture_non_power_of_two") != std::string::npos ? "ok" : "MISSING"); window.renderLoadingScreen(); } const char* errorMsg = NULL; if(!loadSystemConfigFile(&errorMsg)) { // something went terribly wrong if(errorMsg == NULL) { LOG(LogError) << "Unknown error occured while parsing system config file."; if(!scrape_cmdline) Renderer::deinit(); return 1; } // we can't handle es_systems.cfg file problems inside ES itself, so display the error message then quit window.pushGui(new GuiMsgBox(&window, errorMsg, "QUIT", [] { SDL_Event* quit = new SDL_Event(); quit->type = SDL_QUIT; SDL_PushEvent(quit); })); } //run the command line scraper then quit if(scrape_cmdline) { return run_scraper_cmdline(); } //dont generate joystick events while we're loading (hopefully fixes "automatically started emulator" bug) SDL_JoystickEventState(SDL_DISABLE); // preload what we can right away instead of waiting for the user to select it // this makes for no delays when accessing content, but a longer startup time ViewController::get()->preload(); //choose which GUI to open depending on if an input configuration already exists if(errorMsg == NULL) { if(fs::exists(InputManager::getConfigPath()) && InputManager::getInstance()->getNumConfiguredDevices() > 0) { ViewController::get()->goToStart(); }else{ window.pushGui(new GuiDetectDevice(&window, true, [] { ViewController::get()->goToStart(); })); } } //generate joystick events since we're done loading SDL_JoystickEventState(SDL_ENABLE); int lastTime = SDL_GetTicks(); bool running = true; while(running) { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_JOYHATMOTION: case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: case SDL_KEYDOWN: case SDL_KEYUP: case SDL_JOYAXISMOTION: case SDL_TEXTINPUT: case SDL_TEXTEDITING: case SDL_JOYDEVICEADDED: case SDL_JOYDEVICEREMOVED: InputManager::getInstance()->parseEvent(event, &window); break; case SDL_QUIT: running = false; break; } } if(window.isSleeping()) { lastTime = SDL_GetTicks(); SDL_Delay(1); // this doesn't need to be accurate, we're just giving up our CPU time until something wakes us up continue; } int curTime = SDL_GetTicks(); int deltaTime = curTime - lastTime; lastTime = curTime; // cap deltaTime at 1000 if(deltaTime > 1000 || deltaTime < 0) deltaTime = 1000; window.update(deltaTime); window.render(); Renderer::swapBuffers(); Log::flush(); } while(window.peekGui() != ViewController::get()) delete window.peekGui(); window.deinit(); SystemData::deleteSystems(); LOG(LogInfo) << "EmulationStation cleanly shutting down."; return 0; }
/* Check to see if we need to synthesize focus events */ static SDL_bool SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_bool inWindow = SDL_TRUE; if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) { int w, h; SDL_GetWindowSize(window, &w, &h); if (x < 0 || y < 0 || x >= w || y >= h) { inWindow = SDL_FALSE; } } /* Linux doesn't give you mouse events outside your window unless you grab the pointer. Windows doesn't give you mouse events outside your window unless you call SetCapture(). Both of these are slightly scary changes, so for now we'll punt and if the mouse leaves the window you'll lose mouse focus and reset button state. */ #ifdef SUPPORT_DRAG_OUTSIDE_WINDOW if (!inWindow && !buttonstate) { #else if (!inWindow) { #endif if (window == mouse->focus) { #ifdef DEBUG_MOUSE printf("Mouse left window, synthesizing move & focus lost event\n"); #endif SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y); SDL_SetMouseFocus(NULL); } return SDL_FALSE; } if (window != mouse->focus) { #ifdef DEBUG_MOUSE printf("Mouse entered window, synthesizing focus gain & move event\n"); #endif SDL_SetMouseFocus(window); SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y); } return SDL_TRUE; } int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y) { if (window && !relative) { SDL_Mouse *mouse = SDL_GetMouse(); if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) { return 0; } } return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y); } static int GetScaledMouseDelta(float scale, int value, float *accum) { if (scale != 1.0f) { *accum += scale * value; if (*accum >= 0.0f) { value = (int)SDL_floor(*accum); } else { value = (int)SDL_ceil(*accum); } *accum -= value; } return value; } static int SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; int xrel; int yrel; /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */ if (mouse->mouse_touch_events) { if (mouseID != SDL_TOUCH_MOUSEID && !relative && track_mouse_down) { if (window) { float fx = (float)x / (float)window->w; float fy = (float)y / (float)window->h; SDL_SendTouchMotion(SDL_MOUSE_TOUCHID, 0, fx, fy, 1.0f); } } } if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) { int center_x = 0, center_y = 0; SDL_GetWindowSize(window, ¢er_x, ¢er_y); center_x /= 2; center_y /= 2; if (x == center_x && y == center_y) { mouse->last_x = center_x; mouse->last_y = center_y; return 0; } SDL_WarpMouseInWindow(window, center_x, center_y); } if (relative) { if (mouse->relative_mode) { x = GetScaledMouseDelta(mouse->relative_speed_scale, x, &mouse->scale_accum_x); y = GetScaledMouseDelta(mouse->relative_speed_scale, y, &mouse->scale_accum_y); } else { x = GetScaledMouseDelta(mouse->normal_speed_scale, x, &mouse->scale_accum_x); y = GetScaledMouseDelta(mouse->normal_speed_scale, y, &mouse->scale_accum_y); } xrel = x; yrel = y; x = (mouse->last_x + xrel); y = (mouse->last_y + yrel); } else { xrel = x - mouse->last_x; yrel = y - mouse->last_y; } /* Drop events that don't change state */ if (!xrel && !yrel) { #ifdef DEBUG_MOUSE printf("Mouse event didn't change state - dropped!\n"); #endif return 0; } /* Ignore relative motion when first positioning the mouse */ if (!mouse->has_position) { xrel = 0; yrel = 0; mouse->has_position = SDL_TRUE; } /* Ignore relative motion positioning the first touch */ if (mouseID == SDL_TOUCH_MOUSEID && !mouse->buttonstate) { xrel = 0; yrel = 0; } /* Update internal mouse coordinates */ if (!mouse->relative_mode) { mouse->x = x; mouse->y = y; } else { mouse->x += xrel; mouse->y += yrel; } /* make sure that the pointers find themselves inside the windows, unless we have the mouse captured. */ if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) { int x_max = 0, y_max = 0; /* !!! FIXME: shouldn't this be (window) instead of (mouse->focus)? */ SDL_GetWindowSize(mouse->focus, &x_max, &y_max); --x_max; --y_max; if (mouse->x > x_max) { mouse->x = x_max; } if (mouse->x < 0) { mouse->x = 0; } if (mouse->y > y_max) { mouse->y = y_max; } if (mouse->y < 0) { mouse->y = 0; } } mouse->xdelta += xrel; mouse->ydelta += yrel; /* Move the mouse cursor, if needed */ if (mouse->cursor_shown && !mouse->relative_mode && mouse->MoveCursor && mouse->cur_cursor) { mouse->MoveCursor(mouse->cur_cursor); } /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) { SDL_Event event; event.motion.type = SDL_MOUSEMOTION; event.motion.windowID = mouse->focus ? mouse->focus->id : 0; event.motion.which = mouseID; event.motion.state = mouse->buttonstate; event.motion.x = mouse->x; event.motion.y = mouse->y; event.motion.xrel = xrel; event.motion.yrel = yrel; posted = (SDL_PushEvent(&event) > 0); } if (relative) { mouse->last_x = mouse->x; mouse->last_y = mouse->y; } else { /* Use unclamped values if we're getting events outside the window */ mouse->last_x = x; mouse->last_y = y; } return posted; }
int main(int argc, char *argv[]) { int opt; char caption[32]; regex_t reg; regmatch_t pm; int result; char picsize[32]=""; int used_s_opt = 0; int play_yuv = 0; unsigned int start_ticks = 0; Uint32 vflags; if (argc == 1) { print_usage(); return 1; } else { while((opt = getopt(argc, argv, "f:s:")) != -1) switch(opt){ case 's': if (sscanf(optarg, "%dx%d", &width, &height) != 2) { fprintf(stdout, "No geometry information provided by -s parameter.\n"); return 1; } used_s_opt = 1; break; case 'f': if (sscanf(optarg, "%d", &cfidc) != 1 || (cfidc<0 && cfidc>3)) { fprintf(stdout, "Invalid format provided by -f parameter.\n"); return 1; } break; default: print_usage(); return 1; break; } } argv += optind; argc -= optind; vfilename = argv[0]; if(!used_s_opt) { // try to find picture size from filename or path if (regcomp(®, "_[0-9]+x[0-9]+", REG_EXTENDED) != 0) return -1; result = regexec(®, vfilename, 1, &pm, REG_NOTBOL); if(result == 0){ strncpy(picsize, (vfilename + pm.rm_so + 1), (pm.rm_eo - pm.rm_so -1 )); strcat(picsize, "\0"); } if (sscanf(picsize, "%dx%d", &width, &height) != 2) { fprintf(stdout, "No geometry information found in path/filename.\nPlease use -s <width>x<height> paramter.\n"); return 1; } } // some WM can't handle small windows... if (width < 100){ zoom = 2; min_zoom = 2; } //printf("using x=%d y=%d\n", width, height); // SDL init if(SDL_Init(SDL_INIT_VIDEO) < 0){ fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); info = SDL_GetVideoInfo(); if( !info ) { fprintf(stderr, "SDL ERROR Video query failed: %s\n", SDL_GetError() ); SDL_Quit(); exit(0); } bpp = info->vfmt->BitsPerPixel; if(info->hw_available) vflags = SDL_HWSURFACE; else vflags = SDL_SWSURFACE; if( (screen = SDL_SetVideoMode(width*zoom, height*zoom, bpp, vflags)) == 0 ) { fprintf(stderr, "SDL ERROR Video mode set failed: %s\n", SDL_GetError() ); SDL_Quit(); exit(0); } // DEBUG output // printf("SDL Video mode set successfully. \nbbp: %d\nHW: %d\nWM: %d\n", // info->vfmt->BitsPerPixel, info->hw_available, info->wm_available); SDL_EnableKeyRepeat(500, 10); my_overlay = SDL_CreateYUVOverlay(width, height, SDL_YV12_OVERLAY, screen); if(!my_overlay){ //Couldn't create overlay? fprintf(stderr, "Couldn't create overlay\n"); //Output to stderr and quit exit(1); } /* should allocate memory for y_data, cr_data, cb_data here */ y_data = malloc(width * height * sizeof(Uint8)); if (cfidc > 0) { cb_data = malloc(width * height * sizeof(Uint8) / SubSizeC[cfidc]); cr_data = malloc(width * height * sizeof(Uint8) / SubSizeC[cfidc]); } fpointer = fopen(vfilename, "rb"); if (fpointer == NULL){ fprintf(stderr, "Error opening %s\n", vfilename); return 1; } // send event to display first frame event.type = SDL_KEYDOWN; event.key.keysym.sym = SDLK_RIGHT; SDL_PushEvent(&event); // main loop while (!quit){ sprintf(caption, "frame %d, zoom=%d", frame, zoom); SDL_WM_SetCaption( caption, NULL ); // wait for SDL event SDL_WaitEvent(&event); switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_SPACE: { play_yuv = 1; // play it, sam! while(play_yuv){ start_ticks = SDL_GetTicks(); sprintf(caption, "frame %d, zoom=%d", frame, zoom); SDL_WM_SetCaption( caption, NULL ); // check for next frame existing if(load_frame()){ draw_frame(); //insert delay for real time viewing if(SDL_GetTicks() - start_ticks < 40) SDL_Delay(40 - (SDL_GetTicks() - start_ticks)); frame++; } else { play_yuv = 0; } // check for any key event if(SDL_PollEvent(&event)){ if(event.type == SDL_KEYDOWN){ // stop playing play_yuv = 0; } } } break; } case SDLK_RIGHT: { // check for next frame existing if(load_frame()){ draw_frame(); frame++; } break; } case SDLK_BACKSPACE: case SDLK_LEFT: { if(frame>1){ frame--; fseek(fpointer, ((frame-1)*height*width*FrameSize2C[cfidc])/2 , SEEK_SET); //if(draw_frame()) load_frame(); draw_frame(); } break; } case SDLK_UP: { zoom++; screen = SDL_SetVideoMode(width*zoom, height*zoom, bpp, vflags); video_rect.w = width*zoom; video_rect.h = height*zoom; SDL_DisplayYUVOverlay(my_overlay, &video_rect); break; } case SDLK_DOWN: { if(zoom>min_zoom){ zoom--; screen = SDL_SetVideoMode(width*zoom, height*zoom, bpp, vflags); video_rect.w = width*zoom; video_rect.h = height*zoom; SDL_DisplayYUVOverlay(my_overlay, &video_rect); } break; } case SDLK_r: { if(frame>1){ frame=1; fseek(fpointer, 0, SEEK_SET); //if(draw_frame()) load_frame(); draw_frame(); } break; } case SDLK_g: grid = ~grid; draw_frame(); break; case SDLK_q: quit = 1; break; case SDLK_f: SDL_WM_ToggleFullScreen(screen); break; default: break; } // switch key break; case SDL_QUIT: quit = 1; break; case SDL_VIDEOEXPOSE: SDL_DisplayYUVOverlay(my_overlay, &video_rect); break; default: break; } // switch event type } // while // clean up SDL_FreeYUVOverlay(my_overlay); free(y_data); free(cb_data); free(cr_data); fclose(fpointer); if (!used_s_opt) regfree(®); return 0; }
int GP2X_Events::thread() { static int l_x = 0; static int l_y = 0; static int l_button = 0; while(m_running) { m_dx = 0; m_dy = 0; m_button = 0; // UP if(SDL_JoystickGetButton(m_joy, 0)) { m_dy = -1; } // DOWN if(SDL_JoystickGetButton(m_joy, 4)) { m_dy = 1; } // LEFT if(SDL_JoystickGetButton(m_joy, 2)) { m_dx = -1; } // RIGHT if(SDL_JoystickGetButton(m_joy, 6)) { m_dx = 1; } // UP - LEFT if(SDL_JoystickGetButton(m_joy, 1)) { m_dy = -1; m_dx = -1; } // UP - RIGHT if(SDL_JoystickGetButton(m_joy, 7)) { m_dy = -1; m_dx = 1; } // DOWN - LEFT if(SDL_JoystickGetButton(m_joy, 3)) { m_dy = 1; m_dx = -1; } // DOWN - RIGHT if(SDL_JoystickGetButton(m_joy, 5)) { m_dy = 1; m_dx = 1; } // CLICK if(SDL_JoystickGetButton(m_joy, 18)) { m_button |= SDL_BUTTON(1); } // A if(SDL_JoystickGetButton(m_joy, 12)) { m_button |= SDL_BUTTON(2); } // B if(SDL_JoystickGetButton(m_joy, 13)) { m_button |= SDL_BUTTON(3); } // X if(SDL_JoystickGetButton(m_joy, 14)) { m_button |= SDL_BUTTON(1); } m_x += m_dx * 2; m_y += m_dy * 2; if(l_x != m_x || l_y != m_y) { SDL_WarpMouse(m_x, m_y); SDL_Event event; event.type = SDL_MOUSEMOTION; event.motion.type = SDL_MOUSEMOTION; event.motion.state = (m_button & SDL_BUTTON(1)) ? SDL_PRESSED : SDL_RELEASED; event.motion.x = m_x; event.motion.y = m_y; event.motion.xrel = 0; event.motion.yrel = 0; SDL_PushEvent(&event); } if(l_button != m_button) { bool l_1 = (l_button & SDL_BUTTON(1)) == SDL_BUTTON(1); bool m_1 = (m_button & SDL_BUTTON(1)) == SDL_BUTTON(1); bool l_2 = (l_button & SDL_BUTTON(2)) == SDL_BUTTON(2); bool m_2 = (m_button & SDL_BUTTON(2)) == SDL_BUTTON(2); bool l_3 = (l_button & SDL_BUTTON(3)) == SDL_BUTTON(3); bool m_3 = (m_button & SDL_BUTTON(3)) == SDL_BUTTON(3); SDL_Event event; if(l_1 != m_1) { event.type = m_1 ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; event.button.type = event.type; event.button.button = SDL_BUTTON_LEFT; event.button.state = m_1 ? SDL_PRESSED : SDL_RELEASED; event.button.x = m_x; event.button.y = m_y; SDL_PushEvent(&event); } if(l_2 != m_2) { event.type = m_2 ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; event.button.type = event.type; event.button.button = SDL_BUTTON_MIDDLE; event.button.state = m_2 ? SDL_PRESSED : SDL_RELEASED; event.button.x = m_x; event.button.y = m_y; SDL_PushEvent(&event); } if(l_3 != m_3) { event.type = m_3 ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; event.button.type = event.type; event.button.button = SDL_BUTTON_RIGHT; event.button.state = m_3 ? SDL_PRESSED : SDL_RELEASED; event.button.x = m_x; event.button.y = m_y; SDL_PushEvent(&event); } } l_x = m_x; l_y = m_y; l_button = m_button; SDL_Delay(10); } return 0; }
void CGame::requestEndGame() { // SDLに終了要請 SDL_Event e; e.type = SDL_QUIT; SDL_PushEvent( &e ); }
static int SDL_CompatEventFilter(void *userdata, SDL_Event * event) { SDL_Event fake; switch (event->type) { case SDL_WINDOWEVENT: switch (event->window.event) { case SDL_WINDOWEVENT_EXPOSED: if (!SDL_HasEvent(SDL_VIDEOEXPOSEMASK)) { fake.type = SDL_VIDEOEXPOSE; SDL_PushEvent(&fake); } break; case SDL_WINDOWEVENT_RESIZED: SDL_PeepEvents(&fake, 1, SDL_GETEVENT, SDL_VIDEORESIZEMASK); fake.type = SDL_VIDEORESIZE; fake.resize.w = event->window.data1; fake.resize.h = event->window.data2; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_MINIMIZED: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 0; fake.active.state = SDL_APPACTIVE; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_RESTORED: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 1; fake.active.state = SDL_APPACTIVE; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_ENTER: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 1; fake.active.state = SDL_APPMOUSEFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_LEAVE: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 0; fake.active.state = SDL_APPMOUSEFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_FOCUS_GAINED: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 1; fake.active.state = SDL_APPINPUTFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_FOCUS_LOST: fake.type = SDL_ACTIVEEVENT; fake.active.gain = 0; fake.active.state = SDL_APPINPUTFOCUS; SDL_PushEvent(&fake); break; case SDL_WINDOWEVENT_CLOSE: fake.type = SDL_QUIT; SDL_PushEvent(&fake); break; } case SDL_KEYDOWN: case SDL_KEYUP: { Uint32 unicode = 0; if (event->key.type == SDL_KEYDOWN && event->key.keysym.sym < 256) { unicode = event->key.keysym.sym; if (unicode >= 'a' && unicode <= 'z') { int shifted = !!(event->key.keysym.mod & KMOD_SHIFT); int capslock = !!(event->key.keysym.mod & KMOD_CAPS); if ((shifted ^ capslock) != 0) { unicode = SDL_toupper(unicode); } } } if (unicode) { event->key.keysym.unicode = unicode; } break; } case SDL_TEXTINPUT: { /* FIXME: Generate an old style key repeat event if needed */ //printf("TEXTINPUT: '%s'\n", event->text.text); break; } case SDL_MOUSEWHEEL: { Uint8 button; int selected; int x, y; if (event->wheel.y == 0) { break; } selected = SDL_SelectMouse(event->wheel.which); SDL_GetMouseState(selected, &x, &y); SDL_SelectMouse(selected); if (event->wheel.y > 0) { button = SDL_BUTTON_WHEELUP; } else { button = SDL_BUTTON_WHEELDOWN; } fake.button.which = event->wheel.windowID; fake.button.button = button; fake.button.x = x; fake.button.y = y; fake.button.windowID = event->wheel.windowID; fake.type = SDL_MOUSEBUTTONDOWN; fake.button.state = SDL_PRESSED; SDL_PushEvent(&fake); fake.type = SDL_MOUSEBUTTONUP; fake.button.state = SDL_RELEASED; SDL_PushEvent(&fake); break; } } return 1; }
//----------------------------------------------------------------------- void Window::SendQuitEvent() { SDL_Event evnt = { SDL_QUIT }; SDL_PushEvent(&evnt); }
static bool process_event(SDL_Event *event) { struct buffered_status *status = store_status(); enum keycode ckey; /* SDL's numlock keyboard modifier handling seems to be broken on X11, * and it will only get numlock's status right on application init. We * can trust this value once, and then toggle based on user presses of * the numlock key. * * On Windows, KEYDOWN/KEYUP seem to be sent separately, to indicate * enabling or disabling of numlock. But on X11, both KEYDOWN/KEYUP are * sent for each toggle, so this must be handled differently. * * What a mess! */ if(!numlock_status_initialized) { status->numlock_status = !!(SDL_GetModState() & KMOD_NUM); numlock_status_initialized = true; } switch(event->type) { case SDL_QUIT: { // Stuff an escape status->key = IKEY_ESCAPE; status->keymap[IKEY_ESCAPE] = 1; status->keypress_time = get_ticks(); break; } #if SDL_VERSION_ATLEAST(2,0,0) case SDL_WINDOWEVENT: { switch(event->window.event) { case SDL_WINDOWEVENT_RESIZED: { resize_screen(event->window.data1, event->window.data2); break; } case SDL_WINDOWEVENT_FOCUS_LOST: { // Pause while minimized if(input.unfocus_pause) { while(1) { SDL_WaitEvent(event); if(event->type == SDL_WINDOWEVENT && event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) break; } } break; } } break; } #else // !SDL_VERSION_ATLEAST(2,0,0) case SDL_VIDEORESIZE: { resize_screen(event->resize.w, event->resize.h); break; } case SDL_ACTIVEEVENT: { if(input.unfocus_pause) { // Pause while minimized if(event->active.state & (SDL_APPACTIVE | SDL_APPINPUTFOCUS)) { // Wait for SDL_APPACTIVE with gain of 1 do { SDL_WaitEvent(event); } while((event->type != SDL_ACTIVEEVENT) || (event->active.state & ~(SDL_APPACTIVE | SDL_APPINPUTFOCUS))); } } break; } #endif // !SDL_VERSION_ATLEAST(2,0,0) case SDL_MOUSEMOTION: { SDL_Window *window = SDL_GetWindowFromID(sdl_window_id); int mx_real = event->motion.x; int my_real = event->motion.y; int mx, my, min_x, min_y, max_x, max_y; get_screen_coords(mx_real, my_real, &mx, &my, &min_x, &min_y, &max_x, &max_y); if(mx > 639) SDL_WarpMouseInWindow(window, max_x, my_real); if(mx < 0) SDL_WarpMouseInWindow(window, min_x, my_real); if(my > 349) SDL_WarpMouseInWindow(window, mx_real, max_y); if(my < 0) SDL_WarpMouseInWindow(window, mx_real, min_y); status->real_mouse_x = mx; status->real_mouse_y = my; status->mouse_x = mx / 8; status->mouse_y = my / 14; status->mouse_moved = true; break; } case SDL_MOUSEBUTTONDOWN: { status->mouse_button = event->button.button; status->mouse_repeat = event->button.button; status->mouse_button_state |= SDL_BUTTON(event->button.button); status->mouse_repeat_state = 1; status->mouse_drag_state = -1; status->mouse_time = SDL_GetTicks(); break; } case SDL_MOUSEBUTTONUP: { status->mouse_button_state &= ~SDL_BUTTON(event->button.button); status->mouse_repeat = 0; status->mouse_drag_state = 0; status->mouse_repeat_state = 0; break; } #if SDL_VERSION_ATLEAST(2,0,0) // emulate the X11-style "wheel is a button" that SDL 1.2 used case SDL_MOUSEWHEEL: { SDL_Event fake_event; fake_event.type = SDL_MOUSEBUTTONDOWN; fake_event.button.windowID = event->wheel.windowID; fake_event.button.which = event->wheel.which; fake_event.button.state = SDL_PRESSED; fake_event.button.x = 0; fake_event.button.y = 0; if(event->wheel.y < 0) fake_event.button.button = MOUSE_BUTTON_WHEELDOWN; else fake_event.button.button = MOUSE_BUTTON_WHEELUP; SDL_PushEvent(&fake_event); fake_event.type = SDL_MOUSEBUTTONUP; fake_event.button.state = SDL_RELEASED; SDL_PushEvent(&fake_event); break; } #endif // SDL_VERSION_ATLEAST(2,0,0) case SDL_KEYDOWN: { Uint16 unicode = 0; #if SDL_VERSION_ATLEAST(2,0,0) // FIXME: SDL 2.0 finally implements proper key repeat. // We should probably use it instead of our hand-rolled stuff. if(event->key.repeat) break; #endif ckey = convert_SDL_internal(event->key.keysym.sym); if(!ckey) { #if !SDL_VERSION_ATLEAST(2,0,0) if(!event->key.keysym.unicode) break; #endif ckey = IKEY_UNICODE; } #if SDL_VERSION_ATLEAST(2,0,0) // SDL 2.0 sends the raw key and translated 'text' as separate events. // There is no longer a UNICODE mode that sends both at once. // Because of the way the SDL 1.2 assumption is embedded deeply in // the MZX event queue processor, emulate the 1.2 behaviour by waiting // for a TEXTINPUT event after a KEYDOWN. if(SDL_WaitEventTimeout(event, 1)) { if(event->type == SDL_TEXTINPUT) unicode = event->text.text[0] | event->text.text[1] << 8; else SDL_PushEvent(event); } #else unicode = event->key.keysym.unicode; #endif if((ckey == IKEY_RETURN) && get_alt_status(keycode_internal) && get_ctrl_status(keycode_internal)) { toggle_fullscreen(); break; } if(ckey == IKEY_CAPSLOCK) { status->caps_status = true; } if(ckey == IKEY_NUMLOCK) { #if !SDL_VERSION_ATLEAST(2,0,0) && defined(__WIN32__) status->numlock_status = true; #endif break; } if(ckey == IKEY_F12) { dump_screen(); break; } // Ignore alt + tab if((ckey == IKEY_TAB) && get_alt_status(keycode_internal)) { break; } if(status->key_repeat && (status->key_repeat != IKEY_LSHIFT) && (status->key_repeat != IKEY_RSHIFT) && (status->key_repeat != IKEY_LALT) && (status->key_repeat != IKEY_RALT) && (status->key_repeat != IKEY_LCTRL) && (status->key_repeat != IKEY_RCTRL)) { // Stack current repeat key if it isn't shift, alt, or ctrl if(input.repeat_stack_pointer != KEY_REPEAT_STACK_SIZE) { input.key_repeat_stack[input.repeat_stack_pointer] = status->key_repeat; input.unicode_repeat_stack[input.repeat_stack_pointer] = status->unicode_repeat; input.repeat_stack_pointer++; } } key_press(status, ckey, unicode); break; } case SDL_KEYUP: { #if SDL_VERSION_ATLEAST(2,0,0) // FIXME: SDL 2.0 finally implements proper key repeat. // We should probably use it instead of our hand-rolled stuff. if(event->key.repeat) break; #endif ckey = convert_SDL_internal(event->key.keysym.sym); if(!ckey) { #if !SDL_VERSION_ATLEAST(2,0,0) if(!status->keymap[IKEY_UNICODE]) break; #endif ckey = IKEY_UNICODE; } if(ckey == IKEY_NUMLOCK) { #if !SDL_VERSION_ATLEAST(2,0,0) && defined(__WIN32__) status->numlock_status = false; #else status->numlock_status = !status->numlock_status; #endif break; } if(ckey == IKEY_CAPSLOCK) { status->caps_status = false; } status->keymap[ckey] = 0; if(status->key_repeat == ckey) { status->key_repeat = IKEY_UNKNOWN; status->unicode_repeat = 0; } status->key_release = ckey; break; } case SDL_JOYAXISMOTION: { int axis_value = event->jaxis.value; int digital_value = -1; int which = event->jaxis.which; int axis = event->jaxis.axis; Sint8 last_axis = status->axis[which][axis]; enum keycode stuffed_key; if(axis_value > 10000) digital_value = 1; else if(axis_value < -10000) digital_value = 0; if(digital_value != -1) { stuffed_key = input.joystick_axis_map[which][axis][digital_value]; if(stuffed_key) { joystick_key_press(status, stuffed_key, stuffed_key); if(last_axis == (digital_value ^ 1)) { joystick_key_release(status, input.joystick_axis_map[which][axis][last_axis]); } } } else if(last_axis != -1) { joystick_key_release(status, input.joystick_axis_map[which][axis][last_axis]); } status->axis[which][axis] = digital_value; break; } case SDL_JOYBUTTONDOWN: { int which = event->jbutton.which; int button = event->jbutton.button; enum keycode stuffed_key = input.joystick_button_map[which][button]; if(stuffed_key) joystick_key_press(status, stuffed_key, stuffed_key); break; } case SDL_JOYBUTTONUP: { int which = event->jbutton.which; int button = event->jbutton.button; enum keycode stuffed_key = input.joystick_button_map[which][button]; if(stuffed_key) joystick_key_release(status, stuffed_key); break; } case SDL_JOYHATMOTION: { int which = event->jhat.which; int dir = event->jhat.value; enum keycode key_up = input.joystick_hat_map[which][0]; enum keycode key_down = input.joystick_hat_map[which][1]; enum keycode key_left = input.joystick_hat_map[which][2]; enum keycode key_right = input.joystick_hat_map[which][3]; //if(dir & SDL_HAT_CENTERED) { joystick_key_release(status, key_up); joystick_key_release(status, key_down); joystick_key_release(status, key_left); joystick_key_release(status, key_right); } if(dir & SDL_HAT_UP) { if (key_up) joystick_key_press(status, key_up, key_up); } if(dir & SDL_HAT_DOWN) { if (key_down) joystick_key_press(status, key_down, key_down); } if(dir & SDL_HAT_LEFT) { if (key_left) joystick_key_press(status, key_left, key_left); } if(dir & SDL_HAT_RIGHT) { if (key_right) joystick_key_press(status, key_right, key_right); } break; } default: return false; } return true; }
} } static Uint32 __timer_handler(Uint32 interval, void *param) { SDL_Event event = { .user = { .type = SDL_USEREVENT, .code = (int) param, .data1 = NULL, .data2 = NULL } }; check(0 == SDL_PushEvent(&event), "SDL_PushEvent() failed.", ""); error: return interval; } /*void move_tanks(const Landscape *l, ResGetTanksTankRecord *tanks, size_t tanks_count) { assert(l && "Bad landscape pointer."); assert(tanks && "Bad tanks pointer."); for (size_t i = 0; i < tanks_count; i++) { move_tank(l, &tanks[i]); } }
int decode_thread(void *arg) { VideoState *is = (VideoState *)arg; AVFormatContext *pFormatCtx = NULL; AVPacket pkt1, *packet = &pkt1; AVDictionary *io_dict = NULL; AVIOInterruptCB callback; int video_index = -1; int audio_index = -1; int i; is->videoStream=-1; is->audioStream=-1; global_video_state = is; // will interrupt blocking functions if we quit! callback.callback = decode_interrupt_cb; callback.opaque = is; if (avio_open2(&is->io_context, is->filename, 0, &callback, &io_dict)) { fprintf(stderr, "Unable to open I/O for %s\n", is->filename); return -1; } // Open video file if(avformat_open_input(&pFormatCtx, is->filename, NULL, NULL)!=0) return -1; // Couldn't open file is->pFormatCtx = pFormatCtx; // Retrieve stream information if(avformat_find_stream_info(pFormatCtx, NULL)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error av_dump_format(pFormatCtx, 0, is->filename, 0); // Find the first video stream for(i=0; i<pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO &&video_index < 0) { video_index=i; } if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&audio_index < 0) { audio_index=i; } } if(audio_index >= 0) { stream_component_open(is, audio_index); } if(video_index >= 0) { stream_component_open(is, video_index); } if(is->videoStream < 0 || is->audioStream < 0) { fprintf(stderr, "%s: could not open codecs\n", is->filename); goto fail; } // main decode loop for(;;) { if(is->quit) { break; } // seek stuff goes here if(is->seek_req) { int stream_index= -1; int64_t seek_target = is->seek_pos; if (is->videoStream >= 0) stream_index = is->videoStream; else if(is->audioStream >= 0) stream_index = is->audioStream; if(stream_index>=0) { seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, pFormatCtx->streams[stream_index]->time_base); } if(av_seek_frame(is->pFormatCtx, stream_index, seek_target, is->seek_flags) < 0) { fprintf(stderr, "%s: error while seeking\n", is->pFormatCtx->filename); } else { if(is->audioStream >= 0) { packet_queue_flush(&is->audioq); packet_queue_put(&is->audioq, &flush_pkt); } if(is->videoStream >= 0) { packet_queue_flush(&is->videoq); packet_queue_put(&is->videoq, &flush_pkt); } } is->seek_req = 0; } if(is->audioq.size > MAX_AUDIOQ_SIZE ||is->videoq.size > MAX_VIDEOQ_SIZE) { SDL_Delay(10); continue; } if(av_read_frame(is->pFormatCtx, packet) < 0) { if(is->pFormatCtx->pb->error == 0) { SDL_Delay(100); /* no error; wait for user input */ continue; } else { break; } } // Is this a packet from the video stream? if(packet->stream_index == is->videoStream) { packet_queue_put(&is->videoq, packet); } else if(packet->stream_index == is->audioStream) { packet_queue_put(&is->audioq, packet); } else { av_free_packet(packet); } } /* all done - wait for it */ while(!is->quit) { SDL_Delay(100); } fail: { SDL_Event event; event.type = FF_QUIT_EVENT; event.user.data1 = is; SDL_PushEvent(&event); } return 0; }
/* Check to see if we need to synthesize focus events */ static SDL_bool SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate) { SDL_Mouse *mouse = SDL_GetMouse(); int w, h; SDL_bool inWindow; SDL_GetWindowSize(window, &w, &h); if (x < 0 || y < 0 || x >= w || y >= h) { inWindow = SDL_FALSE; } else { inWindow = SDL_TRUE; } /* Linux doesn't give you mouse events outside your window unless you grab the pointer. Windows doesn't give you mouse events outside your window unless you call SetCapture(). Both of these are slightly scary changes, so for now we'll punt and if the mouse leaves the window you'll lose mouse focus and reset button state. */ #ifdef SUPPORT_DRAG_OUTSIDE_WINDOW if (!inWindow && !buttonstate) { #else if (!inWindow) { #endif if (window == mouse->focus) { #ifdef DEBUG_MOUSE printf("Mouse left window, synthesizing move & focus lost event\n"); #endif SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y); SDL_SetMouseFocus(NULL); } return SDL_FALSE; } if (window != mouse->focus) { #ifdef DEBUG_MOUSE printf("Mouse entered window, synthesizing focus gain & move event\n"); #endif SDL_SetMouseFocus(window); SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y); } return SDL_TRUE; } int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y) { if (window && !relative) { SDL_Mouse *mouse = SDL_GetMouse(); if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) { return 0; } } return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y); } static int SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; int xrel; int yrel; int x_max = 0, y_max = 0; /* relative motion is calculated regarding the system cursor last position */ if (relative) { xrel = x; yrel = y; x = (mouse->last_x + x); y = (mouse->last_y + y); } else { xrel = x - mouse->last_x; yrel = y - mouse->last_y; } /* Drop events that don't change state */ if (!xrel && !yrel) { #ifdef DEBUG_MOUSE printf("Mouse event didn't change state - dropped!\n"); #endif return 0; } /* Update internal mouse coordinates */ if (mouse->relative_mode == SDL_FALSE) { mouse->x = x; mouse->y = y; } else { mouse->x += xrel; mouse->y += yrel; } SDL_GetWindowSize(mouse->focus, &x_max, &y_max); --x_max; --y_max; /* make sure that the pointers find themselves inside the windows */ if (mouse->x > x_max) { mouse->x = x_max; } if (mouse->x < 0) { mouse->x = 0; } if (mouse->y > y_max) { mouse->y = y_max; } if (mouse->y < 0) { mouse->y = 0; } mouse->xdelta += xrel; mouse->ydelta += yrel; /* Move the mouse cursor, if needed */ if (mouse->cursor_shown && !mouse->relative_mode && mouse->MoveCursor && mouse->cur_cursor) { mouse->MoveCursor(mouse->cur_cursor); } /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) { SDL_Event event; event.motion.type = SDL_MOUSEMOTION; event.motion.windowID = mouse->focus ? mouse->focus->id : 0; event.motion.which = mouseID; event.motion.state = mouse->buttonstate; event.motion.x = mouse->x; event.motion.y = mouse->y; event.motion.xrel = xrel; event.motion.yrel = yrel; posted = (SDL_PushEvent(&event) > 0); } /* Use unclamped values if we're getting events outside the window */ mouse->last_x = x; mouse->last_y = y; return posted; }
int decode_thread(void *arg) { VideoState *is = (VideoState *)arg; AVFormatContext *pFormatCtx; AVPacket pkt1, *packet = &pkt1; int video_index = -1; int audio_index = -1; int i; is->videoStream=-1; is->audioStream=-1; global_video_state = is; // will interrupt blocking functions if we quit! url_set_interrupt_cb(decode_interrupt_cb); // Open video file if(av_open_input_file(&pFormatCtx, is->filename, NULL, 0, NULL)!=0) return -1; // Couldn't open file is->pFormatCtx = pFormatCtx; // Retrieve stream information if(av_find_stream_info(pFormatCtx)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error dump_format(pFormatCtx, 0, is->filename, 0); // Find the first video stream for(i=0; i<pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && video_index < 0) { video_index=i; } if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO && audio_index < 0) { audio_index=i; } } if(audio_index >= 0) { stream_component_open(is, audio_index); } if(video_index >= 0) { stream_component_open(is, video_index); } if(is->videoStream < 0 || is->audioStream < 0) { fprintf(stderr, "%s: could not open codecs\n", is->filename); goto fail; } // main decode loop for(;;) { if(is->quit) { break; } // seek stuff goes here if(is->audioq.size > MAX_AUDIOQ_SIZE || is->videoq.size > MAX_VIDEOQ_SIZE) { SDL_Delay(10); continue; } if(av_read_frame(is->pFormatCtx, packet) < 0) { if(url_ferror(&pFormatCtx->pb) == 0) { SDL_Delay(100); /* no error; wait for user input */ continue; } else { break; } } // Is this a packet from the video stream? if(packet->stream_index == is->videoStream) { packet_queue_put(&is->videoq, packet); } else if(packet->stream_index == is->audioStream) { packet_queue_put(&is->audioq, packet); } else { av_free_packet(packet); } } /* all done - wait for it */ while(!is->quit) { SDL_Delay(100); } fail: { SDL_Event event; event.type = FF_QUIT_EVENT; event.user.data1 = is; SDL_PushEvent(&event); } return 0; }
void TranslateControllerEvent(SDL_Event *ev) { int btn; SDL_Event ev_new; int in_prompt; static const struct { SDL_Keycode sym; SDL_Scancode scan; } v_keymap[] = { { SDLK_y, SDL_SCANCODE_Y }, // Triangle { SDLK_LALT, SDL_SCANCODE_LALT }, // Circle { SDLK_RETURN, SDL_SCANCODE_RETURN }, // Cross { SDLK_SPACE, SDL_SCANCODE_SPACE }, // Square { SDLK_TAB, SDL_SCANCODE_TAB }, // L Trigger { SDLK_y, SDL_SCANCODE_Y }, // R Trigger { SDLK_DOWN, SDL_SCANCODE_DOWN }, // D-Down { SDLK_LEFT, SDL_SCANCODE_LEFT }, // D-Left { SDLK_UP, SDL_SCANCODE_UP }, // D-Up { SDLK_RIGHT, SDL_SCANCODE_RIGHT }, // D-Right { SDLK_TAB, SDL_SCANCODE_TAB }, // Select { SDLK_ESCAPE, SDL_SCANCODE_ESCAPE }, // Start }; memset(&ev_new, 0, sizeof(SDL_Event)); btn = ev->jbutton.button; in_prompt = 0; // TODO-- for now just use "y" for fire button if (in_prompt) { if (btn == 1 || btn == 10) { ev_new.key.keysym.sym = SDLK_n; ev_new.key.keysym.scancode = SDL_SCANCODE_N; } else if (btn == 2 || btn == 11) { ev_new.key.keysym.sym = SDLK_y; ev_new.key.keysym.scancode = SDL_SCANCODE_Y; } else { return; } } else { if (btn < 0 || btn > 11) return; ev_new.key.keysym.sym = v_keymap[btn].sym; ev_new.key.keysym.scancode = v_keymap[btn].scan; } if (ev->type == SDL_JOYBUTTONDOWN) { ev_new.type = ev_new.key.type = SDL_KEYDOWN; ev_new.key.state = SDL_PRESSED; } else if (ev->type == SDL_JOYBUTTONUP) { ev_new.type = ev_new.key.type = SDL_KEYUP; ev_new.key.state = SDL_RELEASED; } SDL_PushEvent(&ev_new); }
// the main game loop which will run until the game is done void game_loop() { SDL_Event event, e; SDL_TimerID timer; int last_game_update = 0; int last_particle_update = 0; int last_render = 0; int previous_level = 0; debug_print("Loading media..."); load_media(); // check if we want to show score increments game.show_score_increments = atoi(config_getValue("show_score_increments")); // setup input input_init(); // create & show menu ui_menuInit(); ui_toggleMenuVisible(); SDL_SetEventFilter(ui_handleEvents); // loop forever debug_print("Entering main game loop..."); while (1) { // see if its time to trigger an update (make sure we're not paused either) if (!game.paused && SDL_GetTicks() - last_game_update > game_getGameUpdateFreq()) { last_game_update = SDL_GetTicks(); // remember time of last update game_update(); } if (game.show_score_increments) { // at the moment we just have the one particle set // see if its time to trigger a particle update if (SDL_GetTicks() - last_particle_update > PARTICLE_UPDATE_INTERVAL) { last_particle_update = SDL_GetTicks(); particle_update(); } } // check for any events waiting while (SDL_PollEvent(&event)) { switch(event.type) { // key presses are handled in input.c case SDL_KEYDOWN: input_onKeyDown(event.key.keysym.sym); break; case LEFT_KEY: tetromino_moveLeft(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveRight(current_tetromino); } break; case RIGHT_KEY: tetromino_moveRight(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveLeft(current_tetromino); } break; case DOWN_KEY: // uses the key repeat interval to accelerate the tetromino down tetromino_moveDown(current_tetromino); if (grid_checkCollision(grid, current_tetromino)) { tetromino_moveUp(current_tetromino); } break; case UP_KEY: // rotate to a new position tetromino_setNextPosition(current_tetromino); tetromino_setShape(current_tetromino, current_tetromino->type, current_tetromino->position); // make sure the new position doesn't cause any collisions // if it does, reverse the rotation if (grid_checkCollision(grid, current_tetromino)) { tetromino_setPrevPosition(current_tetromino); tetromino_setShape(current_tetromino, current_tetromino->type, current_tetromino->position); } break; case SPACE_KEY: tetromino_moveDown(current_tetromino); // move the tetromino down until it causes a collision while (!grid_checkCollision(grid, current_tetromino)) { tetromino_moveDown(current_tetromino); } // once we have a collision, move it back into place tetromino_moveUp(current_tetromino); break; case PAUSE_KEY: debug_print("Pausing game"); game.paused = !game.paused; // stop the game timer if (game.paused) { SDL_RemoveTimer(timer); timer = NULL; } else { // start it again timer = SDL_AddTimer(1000, game_updateTime, NULL); } break; case ESCAPE_KEY: // pause game updates debug_print("Escape key pressed."); // toggle paused game state if we're in game if (grid && current_tetromino) { game.paused = !game.paused; if (game.paused) { // stop couting time played SDL_RemoveTimer(timer); timer = NULL; } // starting timer again, only if we're still in a game else if (grid && current_tetromino) { timer = SDL_AddTimer(1000, game_updateTime, NULL); } } // show or hide the menu if (grid && current_tetromino) { ui_toggleMenuVisible(); } // enable ui message pump if its visible if (ui_isMenuVisible()) { // if we're in game, show in-game menu if (grid && current_tetromino) { ui_menuPageSetCurrentById(MENU_IN_GAME); } // otherwise show main menu else { ui_menuPageSetCurrentById(MENU_MAIN); } SDL_SetEventFilter(ui_handleEvents); } break; case GAME_START_NEW: // set some game variables game.level = 0; game.score = 0; game.lines = 0; game.paused = 0; // time variables game.hours = 0; game.minutes = 0; game.seconds = 0; // create the grid grid = grid_createNew(GRID_WIDTH, GRID_HEIGHT); // create the first tetromino current_tetromino = tetromino_createNew(); current_tetromino->x = 0; current_tetromino->y = 0; // update time SDL_Init(SDL_INIT_TIMER); if (timer) { SDL_RemoveTimer(timer); timer = NULL; } ui_toggleMenuVisible(); timer = SDL_AddTimer(1000, game_updateTime, NULL); game.paused = 0; break; case GAME_END: // called by either the menu or game over scenario // destroy timer, grid and tetromino SDL_RemoveTimer(timer); timer = NULL; grid_destroy(grid); grid = NULL; tetromino_destroy(current_tetromino); current_tetromino = NULL; // show menu if it isn't already visible ui_menuPageSetCurrentById(MENU_MAIN); if (!ui_isMenuVisible()) { SDL_SetEventFilter(ui_handleEvents); ui_toggleMenuVisible(); } break; case TETROMINO_CREATE: // assumes that the old one has already been discarded current_tetromino = tetromino_createNew(); current_tetromino->x = 0; current_tetromino->y = 0; // check if we have an immediate collision (game over) if (grid_checkCollision(grid, current_tetromino)) { SDL_RemoveTimer(timer); timer = NULL; e.type = GAME_END; SDL_PushEvent(&e); } break; case GRID_REMOVE_LINE: if (game.show_score_increments) { // animated score increment game_showScoreIncrement(event.user.code, (game.level + 1) * 10); } grid_removeLine(grid, event.user.code); // increment number of complete lines game.lines += 1; // +10 per block and x10 per level game.score += (game.level + 1) * 10 * GRID_WIDTH; // increment the game level every 10 lines previous_level = game.level; game.level = game.lines / 10; if (previous_level != game.level) { game_showLevelIncrement(); } break; case GAME_QUIT: SDL_RemoveTimer(timer); // stop gameplay timer timer = NULL; game_shutdown(); break; // unhandled events are ignored default: break; } } // update the display // without this delay gfx card tries to commit suicide by melting if (SDL_GetTicks() - last_render > 3) { display_update(); last_render= SDL_GetTicks(); } } }
void TranslateTouchEvent(SDL_Event *ev) { SDL_Event ev_new; memset(&ev_new, 0, sizeof(SDL_Event)); float w = 960.0F; //screen width float m = 760.0F; //midpoint between rows float h = 544.0F; //screen height float fingerx = ev->tfinger.x; float fingery = ev->tfinger.y; if (vid_is_ui_stretched) // adjusts for stretched screen, for expressions of the form (c/w) { w *= 0.75F ; // (4/3) / (16/9) fingerx += 0.166667F; // (1/6), compensates for 4:3 mode being centered on the vita's screen, as opposed to left flushed } if (ev->tfinger.touchId == 0) { // front touch if (fingerx > 660.0F / w && fingerx < 860.0F / w) //column containing elevator buttons { if (fingery > 50.0F / h && fingery <= 140.0F / h) //9,10 50-140 { if (fingerx < m/w ) { ev_new.key.keysym.sym = SDLK_9; ev_new.key.keysym.scancode = SDL_SCANCODE_9; } else { ev_new.key.keysym.sym = SDLK_0; ev_new.key.keysym.scancode = SDL_SCANCODE_0; } } //7,8 140-194 if (fingery > 140.0F / h && fingery <= 194.0F / h) { if (fingerx < m/w ) { ev_new.key.keysym.sym = SDLK_7; ev_new.key.keysym.scancode = SDL_SCANCODE_7; } else { ev_new.key.keysym.sym = SDLK_8; ev_new.key.keysym.scancode = SDL_SCANCODE_8; } } //5,6 194-249 if (fingery > 194.0F / h && fingery <= 249.0F / h) { if (fingerx < m/w ) { ev_new.key.keysym.sym = SDLK_5; ev_new.key.keysym.scancode = SDL_SCANCODE_5; } else { ev_new.key.keysym.sym = SDLK_6; ev_new.key.keysym.scancode = SDL_SCANCODE_6; } } //3,4 249-303 if (fingery > 249.0F / h && fingery <= 303.0F / h) { if (fingerx < m/w ) { ev_new.key.keysym.sym = SDLK_3; ev_new.key.keysym.scancode = SDL_SCANCODE_3; } else { ev_new.key.keysym.sym = SDLK_4; ev_new.key.keysym.scancode = SDL_SCANCODE_4; } } //1,2 303-410 if (fingery > 303.0F / h && fingery <= 410.0F / h) { if (fingerx < m/w ) { ev_new.key.keysym.sym = SDLK_1; ev_new.key.keysym.scancode = SDL_SCANCODE_1; } else { ev_new.key.keysym.sym = SDLK_2; ev_new.key.keysym.scancode = SDL_SCANCODE_2; } } } else //outside of the column { ev_new.key.keysym.sym = SDLK_BACKQUOTE; ev_new.key.keysym.scancode = SDL_SCANCODE_GRAVE; } } else { // back touch if (fingerx > 480.0F / w) { ev_new.key.keysym.sym = SDLK_EQUALS; ev_new.key.keysym.scancode = SDL_SCANCODE_EQUALS; } else { ev_new.key.keysym.sym = SDLK_MINUS; ev_new.key.keysym.scancode = SDL_SCANCODE_MINUS; } } if (ev->type == SDL_FINGERDOWN) { ev_new.type = ev_new.key.type = SDL_KEYDOWN; ev_new.key.state = SDL_PRESSED; } else if (ev->type == SDL_FINGERUP) { ev_new.type = ev_new.key.type = SDL_KEYUP; ev_new.key.state = SDL_RELEASED; } SDL_PushEvent(&ev_new); }
int SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure) { int index = SDL_GetMouseIndexId(id); SDL_Mouse *mouse = SDL_GetMouse(index); int posted; int xrel; int yrel; int x_max = 0, y_max = 0; if (!mouse || mouse->flush_motion) { return 0; } /* if the mouse is out of proximity we don't to want to have any motion from it */ if (mouse->proximity == SDL_FALSE) { mouse->last_x = x; mouse->last_y = y; return 0; } /* the relative motion is calculated regarding the system cursor last position */ if (relative) { xrel = x; yrel = y; x = (mouse->last_x + x); y = (mouse->last_y + y); } else { xrel = x - mouse->last_x; yrel = y - mouse->last_y; } /* Drop events that don't change state */ if (!xrel && !yrel) { #if 0 printf("Mouse event didn't change state - dropped!\n"); #endif return 0; } /* Update internal mouse coordinates */ if (mouse->relative_mode == SDL_FALSE) { mouse->x = x; mouse->y = y; } else { mouse->x += xrel; mouse->y += yrel; } SDL_GetWindowSize(mouse->focus, &x_max, &y_max); /* make sure that the pointers find themselves inside the windows */ /* only check if mouse->xmax is set ! */ if (x_max && mouse->x > x_max) { mouse->x = x_max; } else if (mouse->x < 0) { mouse->x = 0; } if (y_max && mouse->y > y_max) { mouse->y = y_max; } else if (mouse->y < 0) { mouse->y = 0; } mouse->xdelta += xrel; mouse->ydelta += yrel; mouse->pressure = pressure; /* Move the mouse cursor, if needed */ if (mouse->cursor_shown && !mouse->relative_mode && mouse->MoveCursor && mouse->cur_cursor) { mouse->MoveCursor(mouse->cur_cursor); } /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE && mouse->proximity == SDL_TRUE) { SDL_Event event; event.motion.type = SDL_MOUSEMOTION; event.motion.which = (Uint8) index; event.motion.state = mouse->buttonstate; event.motion.x = mouse->x; event.motion.y = mouse->y; event.motion.z = mouse->z; event.motion.pressure = mouse->pressure; event.motion.pressure_max = mouse->pressure_max; event.motion.pressure_min = mouse->pressure_min; event.motion.rotation = 0; event.motion.tilt_x = 0; event.motion.tilt_y = 0; event.motion.cursor = mouse->current_end; event.motion.xrel = xrel; event.motion.yrel = yrel; event.motion.windowID = mouse->focus ? mouse->focus->id : 0; posted = (SDL_PushEvent(&event) > 0); } mouse->last_x = mouse->x; mouse->last_y = mouse->y; return posted; }
int SDLEventManager::sendEvent(SDL_Event* e) { // simply push what ever is passed (assume non null) return SDL_PushEvent(e); }
void* viewport_loop(void *ptr) { viewport_t *viewport = (viewport_t *)ptr; SDL_Event event; //printf("viewport_loop 1\n"); while(!viewport->done) { int result = !SDL_WaitEvent(&event); //printf("viewport_loop 2\n"); if(result) viewport->done = 1; switch(event.type) { case SDL_KEYDOWN: { viewport->key_pressed = event.key.keysym; keypress_event(viewport); break; } case SDL_MOUSEMOTION: { SDL_Event compress_event; while(SDL_PollEvent(&compress_event)) { if(compress_event.type != SDL_MOUSEMOTION) { SDL_PushEvent(&compress_event); break; } event = compress_event; } SDL_MouseMotionEvent *mouse_event = (SDL_MouseMotionEvent*)&event; viewport->cursor_x = mouse_event->x; viewport->cursor_y = mouse_event->y; cursor_motion(viewport); break; } case SDL_MOUSEBUTTONDOWN: { SDL_MouseButtonEvent *mouse_event = (SDL_MouseButtonEvent*)&event; viewport->which_button = mouse_event->button - 1; viewport->button_down = 1; button_press(viewport); break; } case SDL_MOUSEBUTTONUP: viewport->button_down = 0; break; case SDL_QUIT: viewport->done = 1; break; } } }
void HandleSignal(int signal, siginfo_t* siginfo, void* pctx) { if (signal == SIGINT) { // ctrl+c = kill LOG("caught SIGINT, aborting"); #ifndef HEADLESS // first try a clean exit SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event); #endif // abort after 5sec boost::thread(boost::bind(&ForcedExitAfterFiveSecs)); boost::thread(boost::bind(&ForcedExitAfterTenSecs)); return; } // Turn off signal handling for this signal temporarily in order to disable recursive events (e.g. SIGSEGV) reentrances++; if (reentrances >= 2) { sigaction_t& sa = GetSigAction(NULL); sigaction(signal, &sa, NULL); } ucontext_t* uctx = reinterpret_cast<ucontext_t*> (pctx); logSinkHandler.SetSinking(false); std::string error = strsignal(signal); // append the signal name (it seems there is no OS function to map signum to signame :<) if (signal == SIGSEGV) { error += " (SIGSEGV)"; } else if (signal == SIGILL) { error += " (SIGILL)"; } else if (signal == SIGPIPE) { error += " (SIGPIPE)"; } else if (signal == SIGIO) { error += " (SIGIO)"; } else if (signal == SIGABRT) { error += " (SIGABRT)"; } else if (signal == SIGFPE) { error += " (SIGFPE)"; } else if (signal == SIGBUS) { error += " (SIGBUS)"; } LOG_L(L_ERROR, "%s in spring %s", error.c_str(), (SpringVersion::GetFull()).c_str()); const bool nonFatalSignal = false; const bool fatalSignal = (signal == SIGSEGV) || (signal == SIGILL) || (signal == SIGPIPE) || (signal == SIGFPE) || // causes a endless loop, and process never gets far the causing cmd :< (signal == SIGABRT) || // same (signal == SIGBUS); bool keepRunning = false; bool aiCrash = false; if (fatalSignal) keepRunning = false; if (nonFatalSignal) keepRunning = true; // print stacktrace PrepareStacktrace(); HaltedStacktrace(error, siginfo, uctx); CleanupStacktrace(); // try to clean up if (keepRunning) { bool cleanupOk = true; // try to cleanup AIs if (aiCrash) { cleanupOk = false; /*if (!containedAIInterfaceSo.empty()) { //LOG_L(L_ERROR, "Trying to kill AI Interface library only ...\n"); // TODO //cleanupOk = true; } else if (!containedSkirmishAISo.empty()) { //LOG_L(L_ERROR, "Trying to kill Skirmish AI library only ...\n"); // TODO //cleanupOk = true; }*/ } if (cleanupOk) { logSinkHandler.SetSinking(true); } else { keepRunning = false; } } // exit app if we catched a critical one if (!keepRunning) { // don't handle any further signals when exiting Remove(); std::ostringstream buf; buf << "Spring has crashed:\n" << error << ".\n\n" << "A stacktrace has been written to:\n" << " " << logOutput.GetFilePath(); ErrorMessageBox(buf.str(), "Spring crashed", MBF_OK | MBF_CRASH); // this also calls exit() } // Re-enable signal handling for this signal // FIXME: reentrances should be implemented using boost::thread_specific_ptr if (reentrances >= 2) { sigaction_t& sa = GetSigAction(&HandleSignal); sigaction(signal, &sa, NULL); } reentrances--; }
int queue_picture(VideoState *is, AVFrame *pFrame, double pts) { VideoPicture *vp; //int dst_pix_fmt; AVPicture pict; /* wait until we have space for a new pic */ SDL_LockMutex(is->pictq_mutex); while(is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !is->quit) { SDL_CondWait(is->pictq_cond, is->pictq_mutex); } SDL_UnlockMutex(is->pictq_mutex); if(is->quit) return -1; // windex is set to 0 initially vp = &is->pictq[is->pictq_windex]; /* allocate or resize the buffer! */ if(!vp->bmp || vp->width != is->video_st->codec->width || vp->height != is->video_st->codec->height) { SDL_Event event; vp->allocated = 0; /* we have to do it in the main thread */ event.type = FF_ALLOC_EVENT; event.user.data1 = is; SDL_PushEvent(&event); /* wait until we have a picture allocated */ SDL_LockMutex(is->pictq_mutex); while(!vp->allocated && !is->quit) { SDL_CondWait(is->pictq_cond, is->pictq_mutex); } SDL_UnlockMutex(is->pictq_mutex); if(is->quit) { return -1; } } /* We have a place to put our picture on the queue */ /* If we are skipping a frame, do we set this to null but still return vp->allocated = 1? */ static struct SwsContext *img_convert_ctx; if (img_convert_ctx == NULL) { img_convert_ctx = sws_getContext(is->video_st->codec->width, is->video_st->codec->height, is->video_st->codec->pix_fmt, is->video_st->codec->width, is->video_st->codec->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); if (img_convert_ctx == NULL) { fprintf(stderr, "Cannot initialize the conversion context\n"); exit(1); } } if(vp->bmp) { SDL_LockYUVOverlay(vp->bmp); //dst_pix_fmt = PIX_FMT_YUV420P; /* point pict at the queue */ pict.data[0] = vp->bmp->pixels[0]; pict.data[1] = vp->bmp->pixels[2]; pict.data[2] = vp->bmp->pixels[1]; pict.linesize[0] = vp->bmp->pitches[0]; pict.linesize[1] = vp->bmp->pitches[2]; pict.linesize[2] = vp->bmp->pitches[1]; // Convert the image into YUV format that SDL uses /*img_convert(&pict, dst_pix_fmt, (AVPicture *)pFrame, is->video_st->codec->pix_fmt, is->video_st->codec->width, is->video_st->codec->height);*/ sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, is->video_st->codec->height, pict.data, pict.linesize); SDL_UnlockYUVOverlay(vp->bmp); vp->pts = pts; /* now we inform our display thread that we have a pic ready */ if(++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) { is->pictq_windex = 0; } SDL_LockMutex(is->pictq_mutex); is->pictq_size++; SDL_UnlockMutex(is->pictq_mutex); } return 0; }
static void audio_music_over_callback() { SDL_Event e; e.type = SDL_USEREVENT_MUSIC_OVER; SDL_PushEvent(&e); }