void ONScripter::runEventLoop() { SDL_Event event, tmp_event; while ( SDL_WaitEvent(&event) ) { bool ret = false; // ignore continous SDL_MOUSEMOTION while (event.type == SDL_MOUSEMOTION){ #if SDL_VERSION_ATLEAST(1, 3, 0) if ( SDL_PeepEvents( &tmp_event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ) == 0 ) break; if (tmp_event.type != SDL_MOUSEMOTION) break; SDL_PeepEvents( &tmp_event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ); #else if ( SDL_PeepEvents( &tmp_event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS ) == 0 ) break; if (tmp_event.type != SDL_MOUSEMOTION) break; SDL_PeepEvents( &tmp_event, 1, SDL_GETEVENT, SDL_ALLEVENTS ); #endif event = tmp_event; } switch (event.type) { #if defined(IOS) // || defined(ANDROID) case SDL_FINGERMOTION: { SDL_Touch *touch = SDL_GetTouch(event.tfinger.touchId); tmp_event.motion.x = device_width *event.tfinger.x/touch->xres - (device_width -screen_device_width)/2; tmp_event.motion.y = device_height*event.tfinger.y/touch->yres - (device_height-screen_device_height)/2; if (mouseMoveEvent( &tmp_event.motion )) return; if (btndown_flag){ event.button.type = SDL_MOUSEBUTTONDOWN; event.button.button = SDL_BUTTON_LEFT; if (touch->num_fingers >= 2) event.button.button = SDL_BUTTON_RIGHT; event.button.x = tmp_event.motion.x; event.button.y = tmp_event.motion.y; ret = mousePressEvent( &event.button ); if (ret) return; } } break; case SDL_FINGERDOWN: { SDL_Touch *touch = SDL_GetTouch(event.tfinger.touchId); tmp_event.motion.x = device_width *event.tfinger.x/touch->xres - (device_width -screen_device_width)/2; tmp_event.motion.y = device_height*event.tfinger.y/touch->yres - (device_height-screen_device_height)/2; if (mouseMoveEvent( &tmp_event.motion )) return; } if ( btndown_flag ){ SDL_Touch *touch = SDL_GetTouch(event.tfinger.touchId); tmp_event.button.type = SDL_MOUSEBUTTONDOWN; tmp_event.button.button = SDL_BUTTON_LEFT; if (touch->num_fingers >= 2) tmp_event.button.button = SDL_BUTTON_RIGHT; tmp_event.button.x = device_width *event.tfinger.x/touch->xres - (device_width -screen_device_width)/2; tmp_event.button.y = device_height*event.tfinger.y/touch->yres - (device_height-screen_device_height)/2; ret = mousePressEvent( &tmp_event.button ); } { SDL_Touch *touch = SDL_GetTouch(event.tfinger.touchId); num_fingers = touch->num_fingers; if (num_fingers >= 3){ tmp_event.key.keysym.sym = SDLK_LCTRL; ret |= keyDownEvent( &tmp_event.key ); } } if (ret) return; break; case SDL_FINGERUP: if (num_fingers == 0) break; { SDL_Touch *touch = SDL_GetTouch(event.tfinger.touchId); tmp_event.button.type = SDL_MOUSEBUTTONUP; tmp_event.button.button = SDL_BUTTON_LEFT; if (touch->num_fingers >= 1) tmp_event.button.button = SDL_BUTTON_RIGHT; tmp_event.button.x = device_width *event.tfinger.x/touch->xres - (device_width -screen_device_width)/2; tmp_event.button.y = device_height*event.tfinger.y/touch->yres - (device_height-screen_device_height)/2; ret = mousePressEvent( &tmp_event.button ); } tmp_event.key.keysym.sym = SDLK_LCTRL; keyUpEvent( &tmp_event.key ); num_fingers = 0; if (ret) return; break; #else case SDL_MOUSEMOTION: if (mouseMoveEvent( &event.motion )) return; if (btndown_flag){ if (event.motion.state & SDL_BUTTON(SDL_BUTTON_LEFT)) tmp_event.button.button = SDL_BUTTON_LEFT; else if (event.motion.state & SDL_BUTTON(SDL_BUTTON_RIGHT)) tmp_event.button.button = SDL_BUTTON_RIGHT; else break; tmp_event.button.type = SDL_MOUSEBUTTONDOWN; tmp_event.button.x = event.motion.x; tmp_event.button.y = event.motion.y; ret = mousePressEvent( &tmp_event.button ); if (ret) return; } break; case SDL_MOUSEBUTTONDOWN: if ( !btndown_flag ) break; case SDL_MOUSEBUTTONUP: ret = mousePressEvent( &event.button ); if (ret) return; break; #endif case SDL_JOYBUTTONDOWN: event.key.type = SDL_KEYDOWN; event.key.keysym.sym = transJoystickButton(event.jbutton.button); if(event.key.keysym.sym == SDLK_UNKNOWN) break; case SDL_KEYDOWN: event.key.keysym.sym = transKey(event.key.keysym.sym); ret = keyDownEvent( &event.key ); if ( btndown_flag ) ret |= keyPressEvent( &event.key ); if (ret) return; break; case SDL_JOYBUTTONUP: event.key.type = SDL_KEYUP; event.key.keysym.sym = transJoystickButton(event.jbutton.button); if(event.key.keysym.sym == SDLK_UNKNOWN) break; case SDL_KEYUP: event.key.keysym.sym = transKey(event.key.keysym.sym); keyUpEvent( &event.key ); ret = keyPressEvent( &event.key ); if (ret) return; break; case SDL_JOYAXISMOTION: { SDL_KeyboardEvent ke = transJoystickAxis(event.jaxis); if (ke.keysym.sym != SDLK_UNKNOWN){ if (ke.type == SDL_KEYDOWN){ keyDownEvent( &ke ); if (btndown_flag) keyPressEvent( &ke ); } else if (ke.type == SDL_KEYUP){ keyUpEvent( &ke ); keyPressEvent( &ke ); } } break; } case ONS_TIMER_EVENT: timerEvent(); break; case ONS_MUSIC_EVENT: case ONS_BGMFADE_EVENT: case ONS_CDAUDIO_EVENT: case ONS_MIDI_EVENT: flushEventSub( event ); break; case ONS_CHUNK_EVENT: flushEventSub( event ); //printf("ONS_CHUNK_EVENT %d: %x %d %x\n", event.user.code, wave_sample[0], automode_flag, event_mode); if ( event.user.code != 0 || !(event_mode & WAIT_VOICE_MODE) ) break; event_mode &= ~WAIT_VOICE_MODE; case ONS_BREAK_EVENT: if (event_mode & WAIT_VOICE_MODE && wave_sample[0]){ timerEvent(); break; } if (automode_flag || autoclick_time > 0) current_button_state.button = 0; else if ( usewheel_flag ){ current_button_state.button = -5; sprintf(current_button_state.str, "TIMEOUT"); } else{ current_button_state.button = -2; sprintf(current_button_state.str, "TIMEOUT"); } if (event_mode & (WAIT_INPUT_MODE | WAIT_BUTTON_MODE) && ( clickstr_state == CLICK_WAIT || clickstr_state == CLICK_NEWPAGE ) ){ playClickVoice(); stopAnimation( clickstr_state ); } return; case SDL_ACTIVEEVENT: if ( !event.active.gain ) break; #ifdef ANDROID if (event.active.state == SDL_APPACTIVE){ screen_surface = SDL_SetVideoMode( screen_width, screen_height, screen_bpp, DEFAULT_VIDEO_SURFACE_FLAG ); repaintCommand(); break; } #endif case SDL_VIDEOEXPOSE: #ifdef USE_SDL_RENDERER SDL_RenderPresent(renderer); #else SDL_UpdateRect( screen_surface, 0, 0, screen_width, screen_height ); #endif break; case SDL_QUIT: endCommand(); break; default: break; } } }
void ONScripter::runEventLoop() { SDL_Event event, tmp_event; while ( SDL_WaitEvent(&event) ) { bool ret = false; // ignore continous SDL_MOUSEMOTION while (event.type == SDL_MOUSEMOTION){ #if SDL_VERSION_ATLEAST(1, 3, 0) if ( SDL_PeepEvents( &tmp_event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ) == 0 ) break; if (tmp_event.type != SDL_MOUSEMOTION) break; SDL_PeepEvents( &tmp_event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT ); #else if ( SDL_PeepEvents( &tmp_event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS ) == 0 ) break; if (tmp_event.type != SDL_MOUSEMOTION) break; SDL_PeepEvents( &tmp_event, 1, SDL_GETEVENT, SDL_ALLEVENTS ); #endif event = tmp_event; } switch (event.type) { case SDL_MOUSEMOTION: mouseMoveEvent( (SDL_MouseMotionEvent*)&event ); if (btndown_flag){ SDL_MouseMotionEvent *me = (SDL_MouseMotionEvent*)&event; SDL_MouseButtonEvent be; if (me->state & SDL_BUTTON(SDL_BUTTON_LEFT)) be.button = SDL_BUTTON_LEFT; else if (me->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) be.button = SDL_BUTTON_RIGHT; else break; be.type = SDL_MOUSEBUTTONDOWN; be.x = me->x; be.y = me->y; ret = mousePressEvent( &be ); if (ret) return; } break; case SDL_MOUSEBUTTONDOWN: if ( !btndown_flag ) break; case SDL_MOUSEBUTTONUP: ret = mousePressEvent( (SDL_MouseButtonEvent*)&event ); if (ret) return; break; case SDL_JOYBUTTONDOWN: event.key.type = SDL_KEYDOWN; event.key.keysym.sym = transJoystickButton(event.jbutton.button); if(event.key.keysym.sym == SDLK_UNKNOWN) break; case SDL_KEYDOWN: event.key.keysym.sym = transKey(event.key.keysym.sym); ret = keyDownEvent( (SDL_KeyboardEvent*)&event ); if ( btndown_flag ) ret |= keyPressEvent( (SDL_KeyboardEvent*)&event ); if (ret) return; break; case SDL_JOYBUTTONUP: event.key.type = SDL_KEYUP; event.key.keysym.sym = transJoystickButton(event.jbutton.button); if(event.key.keysym.sym == SDLK_UNKNOWN) break; case SDL_KEYUP: event.key.keysym.sym = transKey(event.key.keysym.sym); keyUpEvent( (SDL_KeyboardEvent*)&event ); ret = keyPressEvent( (SDL_KeyboardEvent*)&event ); if (ret) return; break; case SDL_JOYAXISMOTION: { SDL_KeyboardEvent ke = transJoystickAxis(event.jaxis); if (ke.keysym.sym != SDLK_UNKNOWN){ if (ke.type == SDL_KEYDOWN){ keyDownEvent( &ke ); if (btndown_flag) keyPressEvent( &ke ); } else if (ke.type == SDL_KEYUP){ keyUpEvent( &ke ); keyPressEvent( &ke ); } } break; } case ONS_TIMER_EVENT: timerEvent(); break; case ONS_MUSIC_EVENT: case ONS_BGMFADE_EVENT: case ONS_CDAUDIO_EVENT: case ONS_MIDI_EVENT: flushEventSub( event ); break; case ONS_CHUNK_EVENT: flushEventSub( event ); //printf("ONS_CHUNK_EVENT %d: %x %d %x\n", event.user.code, wave_sample[0], automode_flag, event_mode); if ( event.user.code != 0 || !(event_mode & WAIT_VOICE_MODE) ) break; event_mode &= ~WAIT_VOICE_MODE; case ONS_BREAK_EVENT: if (event_mode & WAIT_VOICE_MODE && wave_sample[0]){ timerEvent(); break; } if (automode_flag || autoclick_time > 0) current_button_state.button = 0; else if ( usewheel_flag ){ current_button_state.button = -5; sprintf(current_button_state.str, "TIMEOUT"); } else{ current_button_state.button = -2; sprintf(current_button_state.str, "TIMEOUT"); } if (event_mode & (WAIT_INPUT_MODE | WAIT_BUTTON_MODE) && ( clickstr_state == CLICK_WAIT || clickstr_state == CLICK_NEWPAGE ) ){ playClickVoice(); stopAnimation( clickstr_state ); } return; case SDL_ACTIVEEVENT: if ( !event.active.gain ) break; #ifdef ANDROID if (event.active.state == SDL_APPACTIVE){ screen_surface = SDL_SetVideoMode( screen_device_width, screen_device_height, screen_bpp, DEFAULT_VIDEO_SURFACE_FLAG ); repaintCommand(); break; } #endif case SDL_VIDEOEXPOSE: SDL_UpdateRect( screen_surface, 0, 0, screen_width, screen_height ); break; case SDL_QUIT: endCommand(); break; default: break; } } }
/* **************************************** * * Event loop * **************************************** */ int PonscripterLabel::eventLoop() { SDL_Event event, tmp_event; /* Note, this rate can change if the window is dragged to a new screen or the monitor settings are changed while running. We do not handle either of these cases */ Uint32 refresh_delay = getRefreshRateDelay(); Uint32 last_refresh = 0, current_time; timer_event_flag = false; #ifdef WIN32 Uint32 win_flags; #endif queueRerender(); advancePhase(); // when we're on the first of a button-waiting frame (menu, etc), we snap mouse cursor to button when // using keyboard/gamecontroller to vastly improve the experience when using not using a mouse directly bool using_buttonbased_movement = true; // true to snap to main menu when it loads first_buttonwait_mode_frame = false; // if it's the first frame of a buttonwait (menu/choice), snap to default button SDL_GetMouseState(&last_mouse_x, &last_mouse_y); while (SDL_WaitEvent(&event)) { // ignore continous SDL_MOUSEMOTION while (event.type == SDL_MOUSEMOTION) { if (SDL_PeepEvents(&tmp_event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 0) break; // improve using keyboard/gamecontroller controls if ((last_mouse_x != ( (SDL_MouseButtonEvent *) &event)->x) || (last_mouse_y != ( (SDL_MouseButtonEvent *) &event)->y)) { using_buttonbased_movement = false; last_mouse_x = ( (SDL_MouseButtonEvent *) &event)->x; last_mouse_y = ( (SDL_MouseButtonEvent *) &event)->y; } if (tmp_event.type != SDL_MOUSEMOTION) break; SDL_PeepEvents(&tmp_event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); event = tmp_event; } switch (event.type) { case SDL_MOUSEMOTION: mouseMoveEvent((SDL_MouseMotionEvent*) &event); break; case SDL_MOUSEBUTTONDOWN: current_button_state.down_x = ( (SDL_MouseButtonEvent *) &event)->x; current_button_state.down_y = ( (SDL_MouseButtonEvent *) &event)->y; current_button_state.ignore_mouseup = false; if (!btndown_flag) break; case SDL_MOUSEBUTTONUP: mousePressEvent((SDL_MouseButtonEvent*) &event); break; case SDL_MOUSEWHEEL: mouseWheelEvent(&event.wheel); break; // NOTE: we reverse KEYUP and KEYDOWN for controller presses, because otherwise it feels really slow and junky // If necessary, we can make keyPressEvent actually interpret controller keys but this works fine for now case SDL_CONTROLLERBUTTONDOWN: using_buttonbased_movement = true; event.key.type = SDL_KEYUP; // printf("Controller button press: %s\n", SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button)); event.key.keysym.sym = transControllerButton(event.cbutton.button); if (event.key.keysym.sym == SDLK_UNKNOWN) break; event.key.keysym.sym = transKey(event.key.keysym.sym); keyDownEvent((SDL_KeyboardEvent*) &event); keyPressEvent((SDL_KeyboardEvent*) &event); break; case SDL_CONTROLLERBUTTONUP: using_buttonbased_movement = true; event.key.type = SDL_KEYDOWN; // printf("Controller button release: %s\n", SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button)); event.key.keysym.sym = transControllerButton(event.cbutton.button); if (event.key.keysym.sym == SDLK_UNKNOWN) break; event.key.keysym.sym = transKey(event.key.keysym.sym); keyUpEvent((SDL_KeyboardEvent*) &event); if (btndown_flag) keyPressEvent((SDL_KeyboardEvent*) &event); break; case SDL_JOYBUTTONDOWN: using_buttonbased_movement = true; event.key.type = SDL_KEYDOWN; event.key.keysym.sym = transJoystickButton(event.jbutton.button); if (event.key.keysym.sym == SDLK_UNKNOWN) break; case SDL_KEYDOWN: if ((event.key.keysym.sym == SDLK_UP) || (event.key.keysym.sym == SDLK_DOWN) || (event.key.keysym.sym == SDLK_LEFT) || (event.key.keysym.sym == SDLK_RIGHT)) using_buttonbased_movement = true; event.key.keysym.sym = transKey(event.key.keysym.sym); keyDownEvent((SDL_KeyboardEvent*) &event); if (btndown_flag) keyPressEvent((SDL_KeyboardEvent*) &event); break; case SDL_JOYBUTTONUP: using_buttonbased_movement = true; event.key.type = SDL_KEYUP; event.key.keysym.sym = transJoystickButton(event.jbutton.button); if (event.key.keysym.sym == SDLK_UNKNOWN) break; case SDL_KEYUP: event.key.keysym.sym = transKey(event.key.keysym.sym); keyUpEvent((SDL_KeyboardEvent*) &event); keyPressEvent((SDL_KeyboardEvent*) &event); break; case SDL_JOYAXISMOTION: { SDL_KeyboardEvent ke = transJoystickAxis(event.jaxis); if (ke.keysym.sym != SDLK_UNKNOWN) { if (ke.type == SDL_KEYDOWN) { keyDownEvent(&ke); if (btndown_flag) keyPressEvent(&ke); } else if (ke.type == SDL_KEYUP) { keyUpEvent(&ke); keyPressEvent(&ke); } } break; } case ONS_SOUND_EVENT: case ONS_FADE_EVENT: case ONS_MIDI_EVENT: case ONS_MUSIC_EVENT: flushEventSub(event); break; case INTERNAL_REDRAW_EVENT: /* Handle cursor shifting for controller/keyboard button-based movement */ if (first_buttonwait_mode_frame && using_buttonbased_movement && buttons.size() > 1) { shiftCursorOnButton(0); } if (event_mode & WAIT_BUTTON_MODE) first_buttonwait_mode_frame = true; else if (first_buttonwait_mode_frame) first_buttonwait_mode_frame = false; /* Stop rerendering while minimized; wait for the restore event + queueRerender */ if(minimized_flag) { break; } current_time = SDL_GetTicks(); if((current_time - last_refresh) >= refresh_delay || last_refresh == 0) { /* It has been longer than the refresh delay since we last started a refresh. Start another */ last_refresh = current_time; rerender(); /* Refresh time since rerender does take some odd ms */ current_time = SDL_GetTicks(); } SDL_PumpEvents(); /* Remove all pending redraw events on the queue */ while(SDL_PeepEvents(&tmp_event, 1, SDL_GETEVENT, INTERNAL_REDRAW_EVENT, INTERNAL_REDRAW_EVENT) == 1) ; /* If there are any events on the queue, re-add us and let it get those events asap. * It'll then come back to us with no events and we'll just sleep until it's time to redraw again. * If there are no events, sleep right away */ if(SDL_PeepEvents(&tmp_event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 0) { if(timer_event_flag && timer_event_time <= current_time) { timer_event_flag = false; timerEvent(); } else if(last_refresh <= current_time && refresh_delay >= (current_time - last_refresh)) { SDL_Delay(std::min(refresh_delay / 3, refresh_delay - (current_time - last_refresh))); } } tmp_event.type = INTERNAL_REDRAW_EVENT; SDL_PushEvent(&tmp_event); break; case ONS_WAVE_EVENT: flushEventSub(event); //printf("ONS_WAVE_EVENT %d: %x %d %x\n", event.user.code, wave_sample[0], automode_flag, event_mode); if (event.user.code != 0 || !(event_mode & WAIT_VOICE_MODE)) break; if (remaining_time <= 0) { event_mode &= ~WAIT_VOICE_MODE; if (automode_flag) current_button_state.button = 0; else if (usewheel_flag) current_button_state.button = -5; else current_button_state.button = -2; stopAnimation(clickstr_state); advancePhase(); } break; case SDL_WINDOWEVENT: switch(event.window.event) { case SDL_WINDOWEVENT_FOCUS_LOST: break; case SDL_WINDOWEVENT_FOCUS_GAINED: /* See comment below under RESIZED */ SDL_PumpEvents(); SDL_PeepEvents(&tmp_event, 1, SDL_GETEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN); current_button_state.ignore_mouseup = true; #ifdef WIN32 win_flags = SDL_GetWindowFlags(screen); /* Work around: https://bugzilla.libsdl.org/show_bug.cgi?id=2510 * * On windows, the RESTORED event does not occur when you restore a * maximized event. The only events you get are a ton of exposes and * this one. The screen also remains black if it was maximized until * the window is "restored". */ SDL_RestoreWindow(screen); if(win_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { SDL_SetWindowFullscreen(screen, SDL_WINDOW_FULLSCREEN_DESKTOP); } else if(win_flags & SDL_WINDOW_FULLSCREEN) { SDL_SetWindowFullscreen(screen, SDL_WINDOW_FULLSCREEN); } else if(win_flags & SDL_WINDOW_MAXIMIZED) { SDL_MaximizeWindow(screen); } #endif break; case SDL_WINDOWEVENT_MAXIMIZED: case SDL_WINDOWEVENT_RESIZED: /* Due to what I suspect is an SDL bug, you get a mosuedown + * mouseup event when you maximize the window by double * clicking the titlebar in windows. These events both have * coordinates inside of the screen, and I can't see any way * to tell them apart from legitimate clicks. (it even triggers * a mouse move event). * To fix this bug, we kill any mousedown events when we maximize. * Note, we do this under RESIZED too because if you do a * "vertical maximize" (double click with the upper resize arrow) * that doesn't trigger a maximized event */ SDL_PumpEvents(); SDL_PeepEvents(&tmp_event, 1, SDL_GETEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN); current_button_state.ignore_mouseup = true; case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_EXPOSED: /* If we weren't minimized, a rerender is already queued */ if(minimized_flag) { minimized_flag = false; queueRerender(); } break; case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_HIDDEN: minimized_flag = true; break; } break; case SDL_QUIT: endCommand("end"); break; default: break; } } return -1; }