Skip to content

Commit

Permalink
Handle the SDL events strictly in turn (#8912)
Browse files Browse the repository at this point in the history
  • Loading branch information
oleg-derevenetz committed Jul 14, 2024
1 parent 0058a10 commit 50d1181
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 96 deletions.
194 changes: 101 additions & 93 deletions src/engine/localevent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,16 +331,22 @@ namespace EventProcessing

static void initTouchpad()
{
const int touchNumber = SDL_GetNumTouchDevices();
if ( touchNumber > 0 ) {
fheroes2::cursor().enableSoftwareEmulation( true );
#if SDL_VERSION_ATLEAST( 2, 0, 10 )
const SDL_bool value = SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
if ( value != SDL_TRUE ) {
ERROR_LOG( "Failed to set SDL_HINT_TOUCH_MOUSE_EVENTS." )
}
if ( SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" ) != SDL_TRUE ) {
ERROR_LOG( "Failed to set the " SDL_HINT_MOUSE_TOUCH_EVENTS " hint." )
}
#endif
#if SDL_VERSION_ATLEAST( 2, 0, 6 )
if ( SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" ) != SDL_TRUE ) {
ERROR_LOG( "Failed to set the " SDL_HINT_TOUCH_MOUSE_EVENTS " hint." )
}
#endif

if ( SDL_GetNumTouchDevices() <= 0 ) {
return;
}

fheroes2::cursor().enableSoftwareEmulation( true );
}

void initController()
Expand Down Expand Up @@ -387,99 +393,101 @@ namespace EventProcessing
updateDisplay = false;

SDL_Event event;
if ( !SDL_PollEvent( &event ) ) {
// There are no new events, just carry on
return true;
}

while ( SDL_PollEvent( &event ) ) {
switch ( event.type ) {
case SDL_WINDOWEVENT:
if ( event.window.event == SDL_WINDOWEVENT_CLOSE ) {
// A special case since we need to exit the loop.
if ( allowExit ) {
// Try to perform clear exit to catch all memory leaks, for example.
return false;
}
break;
}
if ( onWindowEvent( event.window ) ) {
updateDisplay = true;
}
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
onKeyboardEvent( eventHandler, event.key );
break;
case SDL_MOUSEMOTION:
onMouseMotionEvent( eventHandler, event.motion );
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
onMouseButtonEvent( eventHandler, event.button );
break;
case SDL_MOUSEWHEEL:
onMouseWheelEvent( eventHandler, event.wheel );
break;
case SDL_CONTROLLERDEVICEREMOVED:
onControllerRemovedEvent( event.jdevice );
break;
case SDL_CONTROLLERDEVICEADDED:
onControllerAddedEvent( event.jdevice );
break;
case SDL_JOYAXISMOTION:
case SDL_JOYBALLMOTION:
case SDL_JOYHATMOTION:
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
case SDL_JOYDEVICEADDED:
case SDL_JOYDEVICEREMOVED:
case SDL_CONTROLLERDEVICEREMAPPED:
// SDL requires joystick events to be enabled in order to handle controller events.
// This is because the controller related code depends on the joystick related code.
// See SDL_gamecontroller.c within SDL source code for implementation details.
break;
case SDL_CONTROLLERAXISMOTION:
onControllerAxisEvent( eventHandler, event.caxis );
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
onControllerButtonEvent( eventHandler, event.cbutton );
break;
case SDL_FINGERDOWN:
case SDL_FINGERUP:
case SDL_FINGERMOTION:
onTouchEvent( eventHandler, event.tfinger );
break;
case SDL_RENDER_TARGETS_RESET:
// We need to just update the screen. This event usually happens when we switch between fullscreen and windowed modes.
updateDisplay = true;
break;
case SDL_RENDER_DEVICE_RESET:
onRenderDeviceResetEvent();
updateDisplay = true;
break;
case SDL_TEXTINPUT:
// Keyboard events on Android should be processed here. Use event.text.text to extract text input.
break;
case SDL_TEXTEDITING:
// An event when a user pressed a button on a keyboard. Not all buttons are supported. This event should be used mainly on Android devices.
break;
case SDL_QUIT:
// Each new event should be processed separately in turn
switch ( event.type ) {
case SDL_WINDOWEVENT:
if ( event.window.event == SDL_WINDOWEVENT_CLOSE ) {
if ( allowExit ) {
// Try to perform clear exit to catch all memory leaks, for example.
return false;
}
break;
case SDL_APP_LOWMEMORY:
// According to SDL this event can only happen on Android or iOS.
// We need to deallocate some memory but we need to be careful not to deallocate images that are in use at the moment.
// As of now we have no logic for this so we at least log this event.
DEBUG_LOG( DBG_ENGINE, DBG_WARN, "OS indicates low memory. Release some resources." )
break;
default:
// If this assertion blows up then we included an event type but we didn't add logic for it.
assert( eventTypeStatus.count( event.type ) == 0 );

// This is a new event type which we do not handle. It might have been added in a newer version of SDL.
break;
}
if ( onWindowEvent( event.window ) ) {
updateDisplay = true;
}
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
onKeyboardEvent( eventHandler, event.key );
break;
case SDL_MOUSEMOTION:
onMouseMotionEvent( eventHandler, event.motion );
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
onMouseButtonEvent( eventHandler, event.button );
break;
case SDL_MOUSEWHEEL:
onMouseWheelEvent( eventHandler, event.wheel );
break;
case SDL_CONTROLLERDEVICEREMOVED:
onControllerRemovedEvent( event.jdevice );
break;
case SDL_CONTROLLERDEVICEADDED:
onControllerAddedEvent( event.jdevice );
break;
case SDL_JOYAXISMOTION:
case SDL_JOYBALLMOTION:
case SDL_JOYHATMOTION:
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
case SDL_JOYDEVICEADDED:
case SDL_JOYDEVICEREMOVED:
case SDL_CONTROLLERDEVICEREMAPPED:
// SDL requires joystick events to be enabled in order to handle controller events.
// This is because the controller related code depends on the joystick related code.
// See SDL_gamecontroller.c within SDL source code for implementation details.
break;
case SDL_CONTROLLERAXISMOTION:
onControllerAxisEvent( eventHandler, event.caxis );
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
onControllerButtonEvent( eventHandler, event.cbutton );
break;
case SDL_FINGERDOWN:
case SDL_FINGERUP:
case SDL_FINGERMOTION:
onTouchEvent( eventHandler, event.tfinger );
break;
case SDL_RENDER_TARGETS_RESET:
// We need to just update the screen. This event usually happens when we switch between fullscreen and windowed modes.
updateDisplay = true;
break;
case SDL_RENDER_DEVICE_RESET:
onRenderDeviceResetEvent();
updateDisplay = true;
break;
case SDL_TEXTINPUT:
// Keyboard events on Android should be processed here. Use event.text.text to extract text input.
break;
case SDL_TEXTEDITING:
// An event when a user pressed a button on a keyboard. Not all buttons are supported. This event should be used mainly on Android devices.
break;
case SDL_QUIT:
if ( allowExit ) {
// Try to perform clear exit to catch all memory leaks, for example.
return false;
}
break;
case SDL_APP_LOWMEMORY:
// According to SDL this event can only happen on Android or iOS.
// We need to deallocate some memory but we need to be careful not to deallocate images that are in use at the moment.
// As of now we have no logic for this so we at least log this event.
DEBUG_LOG( DBG_ENGINE, DBG_WARN, "OS indicates low memory. Release some resources." )
break;
default:
// If this assertion blows up then we included an event type but we didn't add logic for it.
assert( eventTypeStatus.count( event.type ) == 0 );

// This is a new event type which we do not handle. It might have been added in a newer version of SDL.
break;
}

return true;
Expand Down
6 changes: 3 additions & 3 deletions src/engine/screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ namespace
#if defined( ANDROID )
// Same as ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
if ( SDL_SetHint( SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight" ) == SDL_FALSE ) {
ERROR_LOG( "Failed to set a hint for screen orientation." )
ERROR_LOG( "Failed to set the " SDL_HINT_ORIENTATIONS " hint." )
}
#endif

Expand Down Expand Up @@ -1291,13 +1291,13 @@ namespace
}

if ( SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, ( isNearestScaling() ? "nearest" : "linear" ) ) == SDL_FALSE ) {
ERROR_LOG( "Failed to set a linear scale hint for rendering." )
ERROR_LOG( "Failed to set the " SDL_HINT_RENDER_SCALE_QUALITY " hint." )
}

// Setting this hint prevents the window to regain focus after losing it in fullscreen mode.
// It also fixes issues when SDL_UpdateTexture() calls fail because of refocusing.
if ( SDL_SetHint( SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0" ) == SDL_FALSE ) {
ERROR_LOG( "Failed to set a linear scale hint for rendering." )
ERROR_LOG( "Failed to set the " SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS " hint." )
}

returnCode = SDL_RenderSetLogicalSize( _renderer, width_, height_ );
Expand Down

0 comments on commit 50d1181

Please sign in to comment.