This hack was simulating repeated key presses (EVENT_KEYDOWN, then EVENT_KEYUP) for the arrow keys like the ones a physical keyboard sends
The hack could potentially cause further issues like spamming the events queue with many unnecessary events, and sending the events too quickly for some engines to handle
(thus missing some of them). We're now making use of the allowKbdRepeats() for the Up/Down/Left/Right event actions in the gui-manager, which will handle the case of a key
being kept pressed, sending an initial EVENT_KEYDOWN event and then subsequent EVENT_KEYDOWN events with the kbdRepeat flag set, and finally a single EVENT_KEYUP in the end.
Android itself handles repeated key events similarily (instead of a kbdRepeat flag, it updates a counter for the key repeats, which we translate to a simple flag).
This (and the hack that this replaces) affect things like moving the selection in the GUI lists (like the added games list) upwards or downwards continuously
while keeping the respective arrow key from the Android virtual keyboard pressed down.
This indicates that the cause of the vanishing mouse cursors appears to
be the loss of the palette data from a CLUT8 game cursor when the GMM
cursor which is ARGB is switched in. The SetMouseCursor implementation
currently does not setup the game cursor palette so the cursor is drawn
as all transparent i.e. default palette contents.
It is possible to toggle showing the text console as an overlay on the
screen by holding the Up direction arrow on the Wiimote and pressing
Button 1. This shows messages printed out via printf() / debug() and thus
can be used as a basic mechanism for debug output.
This does not work with the current libogc GDB stub on the Wii as the
GDB network stub support only works with the BBA (Broad Band Adapter)
for the Gamecube.
zlib is used when available and falls back on gzio.
This allows performance improvements as our CRC32 and gzio
implementations are slower than base zlib.
As zlib is available when libpng is present, this is sensible to
benefit from it.
The UITextField protocol function:
"textField: shouldChangeCharactersInRange: replacementString:"
was sometimes called with empty replacementStrings on key press
releases on keyboard. That triggered a backspace keyboard char to
be sent which caused problems when trying to remap actions to
other keyboard keys. No matter which key you were pressing the
resulting key would always be the backspace key.
Only handle text input using the UITextField protocol function
when the replacement string isn't empty. Handle all deletes through
the UITextInput protocol function "deleteBackword".
This has been tested in both cases when the UITextField is empty
(but GUI text field has text) and when the UITextField has text
(which has been added using the SoftKeyboard).
It has also been tested on Apple TV where a software keyboard is
shown with a big text field.
Instead of register input based on if hardware is connected or not
register input based on backend capabilities.
Mouse support is default supported through touch events on screen
(iOS) or touch on controller (Apple TV), and through connected
mouse hardwares. Gamepad controllers are supported from iOS 14 and
later.
Register mouse and gamepad input based on above capabilities to be
able to map actions to buttons on these input devices.
Keyboard support is to be added but not in this commit.
Remove the "isConnected" methods for each input and change the same
method for game controllers to a "isSupported" function to deal
with the iOS version support.
Remove the sending of the EVENT_INPUT_CHANGED event due to the
above reasons. The overide of the isConnected property function is
also removed due to this reason. It caused problems that key
mappings were reset on connections/disconnections.
The gamepad controller dpad button vaule change handler callback,
also called for the virtual controller dpad buttons, sent events
also for buttons not being pressed or released.
E.g. when the left dpad button was pressed an event was sent,
JOYSTICK_BUTTON_DPAD_LEFT with value 1 meaning it's pressed DOWN.
However, the other dpad buttons also did send their events but with
value 0 meaning UP. This had no impact for most of the games but
"The Griffon Legend" handles the dpad events a bit different where
the character is kept moving when the button is released. It meant
that the engine was triggering movements on both the event
EVENT_CUSTOM_ENGINE_ACTION_START and EVENT_CUSTOM_ENGINE_ACTION_END.
This commit changes the dpad button input handling so it remembers
the current state for UP/DOWN and LEFT/RIGHT. This ensures that only
the button that changes state is triggering an event.
The UITapGestureRecognizer is used to identify taps with two fingers,
sending an ESC key event. The UITapGestureRecognizer will not stop
touchesBegan from being called when doing a touch with two fingers.
Touching with two fingers when _mouseClickAndDragEnabled is enabled
will send a EVENT_RBUTTONDOWN.
But if doing a double tap the UITapGestureRecognizer with two fingers
will cancel the touchesEnded from being called meaning that no event
EVENT_RBUTTONUP will be sent to the engine. In some engines, e.g.
lure, this will cause problems since the engine might wait for mouse
clicks to be released before processing other events.
Fix the scenario above by introducing a delay of sending the event
EVENT_RBUTTONDOWN. If the UITapGestureRecognizer is triggered before
this timeout it will cancel the EVENT_RBUTTONDOWN by overwriting the
_queuedInputEvent with the ESC key event.
This commit also deletes the legacy implementation handling double
tap with two fingers to trigger an ESC event.
Removed unnecessary normalization as Android already does this
Also fixed a wrong comparison in a clause for deciding to stop movement that was repeating
I optimized the NEON and Generic paths for ManagedSurface::blendBlitFrom
and the new TransparentSurface::blit. Now (on arm), the new blit function
matches the speed of the old blit function even with the added
inderections that the runtime extension detection code adds in.
Other than that, I made a benchmark for this code and you can make it
using this command:
CFLAGS="-DTEST_BLEND_SPEED" make test
I reverted wii to not use altivec anymore since it doesn't.
I also removed graphics/blit-neon.cpp from graphics/module.mk because
simply including the .cpp file in graphics/blit-alpha.cpp was a better
option because then I didn't need to instantiate every version of the
templates that I needed.
Some bluetooth keyboards also need "navigation" supported as configuration change
Tested with a new Lamtech bluetooth (BLE5) keyboard and also this is suggested here as well:
https://stackoverflow.com/a/27238892
It was wrong (other engines are allowed to do infinite recursions?) and
Future Wars still isn't working properly at all times. I've decided to
remove it (i.e. Future Wars and Operation Stealth are not supported
anymore).
Small updates in readme.txt.
exit() can be handled at user level via atexit(), there's no need to use
the critical handler routine.
Removed GEM restore from the critical handler as this uncovered its
instability while being in the critical handler.
Similar to SuperVidel's but requires an additional C2P pass.
Also, a few optimizations added like cursor is being assumed to be in
a persistent memory so we don't copy it over. And it's using a mask
instead of key.
This graphics mode is not perfect though and works reliably only with
source surfaces allocated via Surface::init() otherwise wrong memory
location is being read.
Still, can gain quite a few CPU cycles, especially on 640x480 screens.
This fixes right click and hold behavior to choose a verb action from the "verb coin" in tony tough
Previously, in direct touch mode, the action selected would refer to the previous item that was under the cursor
before the jump to the new touch point.
Some engines seems to also expect such a delay (tested with Curse of Monkey Island and Tony Tough).
Without this added delay, direct touch mode would work ok in the launcher and GMM GUI but in-game there would be issues.
In Curse of Monkey Island, early difficult selection screen, it was not possible to select the difficulty with a simple tap (direct touch mode).
And in gameplay proper, a simple tap would move the cursor to the touched position but Guybrush would walk to the last position of the cursor (before it jumped to the new one)
Tony Tough had similar issues with its menu.
Basically treats the arrow keys from the virtual keyboard in a special manner
It translates them to KEYCODE_UP(/DOWN/LEFT/RIGHT) and if held down sents consecutive KEYUP / KEYDOWN events
instead of the previous behavior of setting the kbdRepeat flag and just sending repeated KEYDOWN events and one final KEYUP.
Previous behavior would result in poor navigation on lists when the arror keys were held down. The new system works better.
In 2006, Win32PluginProvider was removed from Windows builds:
df5be19409
Instead, SdlPluginProvider became the provider used in Window builds.
Currently, no code uses Win32PluginProvider.
The two classes are small and effectively do the same thing, but
Win32PluginProvider has the advantage of using our Windows string
conversion functions for paths, just like the rest of backend code.
We've seen problems before where SDL handles encoding differently:
0ab9653556f837ced66f73de8499170dcd3079be
The change in commit 1b3c783b9e assumed
that the orientation already had been updated when the system called
viewWillTransitionToSize. This seems to be true for iOS 16 while in
iOS 15 the orientation seems to be updated a bit later.
In iOS 16, make sure that the current orientation is updated when the
function viewWillTransitionToSize is called to make sure it's updated
when the adjustViewFrameForSafeArea is called. This makes sure that the
screen size is updated correctly when forcing the orientation based on
the backend user setting.
In iOS 15 (and below), set the current orientation when the transition
animation finishes to make sure that the interface orientation has been
updated to make sure the virtual controller is connected/disconnected
properly based on the orientation.
- surface setup for optimized 4-bit C2P routine wasn't properly detected
- STFA pretends to support Falcon sampling frequencies on TT leading to
suboptimal sample mixing
- delayMillis() should check also for other events (fixes Future Wars)
but avoid doing it for SCI as its MIDI timer would call itself in a
recursive loop
- SuperVidel doesn't need to use VsetScreen() in VBL anymore
- Wetlands, Teen Agent, Shivers and Private Eye need non-aligned
surface widths
- However Wetlands and Private Eye use setCursorPalette, see
https://bugs.scummvm.org/ticket/14524
- Added warning for Phantasmagoria's 630x450, nothing can be done there
as the game also requires non-aligned surfaces and at the same time
the buffer has to be aligned on 16 bytes.
- BDF scaling disabled by default
The virtual controller layout is not updated properly on
orientation changes. Buttons can be placed outside the screen.
Make sure to set the GCControllerView properties on orientation
changes by connecting the virtual controller based on the
user settings.
On iPhones the virtual game controller buttons does not fit
within the screen borders in portrait mode. Disconnect the
virtual controller on iPhones when changing orientation to
portrait mode.
Utilize an undocumented way to find the GCControllerView by drilling
down the subviews. When found, set the GCControllerView frame size
to full screen size to make sure all buttons do fit within the
screen boundries. This is important to do on devices with safe areas
like iPhones with the sensor panel.
Set the GCControllerView alpha to the user specified value.
This can lead to race conditions.
When synchronizing virtual keyboard state, just set a variable in UI
thread.
The variable will be read in worker thread during event polling, this
will ensure that graphics code is configured at a proper time.
The overided viewWillTransitionToSize instance method did update the
current orientation when animation to the new orientation completed.
However, that made the handling of safe areas on devices having such,
e.g. iPhones with the sensor bar on top, racy. The correct orientation
was set after the adjustViewFrameForSafeArea function was called.
Set the new orientation before the animation completes.
Implement function to trigger the device to set the screen
orientation according to the configration in the backend
options tab.
The implementation to trigger the setting is different for
devices running iOS prior version 16 and version 16+.
The screen orientation update is triggered when user has
applied the setting in the backen options tab, when the GUI
launcher is loaded and when starting a game.
The orientation is only changed if going from any portrait
mode to any landscape mode and the opposite.
Based on the setting, an UIInterfaceOrientationMask property
is set to hold the allowed interface orientations. If the
setting is "Portrait" the property will be set to
UIInterfaceOrientationMaskPortrait, allowing to only change
the orientation to normal or upside down portrait modes.
If the setting is "Landscape" the UIInterfaceOrientationMask
will be set to UIInterfaceOrientationMaskLandscape allowing
the device to rotate the screen orientation only to either
right or left landscape mode. If set to "Auto" all orientations
will be allowed.
When the device orientation changes, the system calls the
instance property method supportedInterfaceOrientations on the
root view controller or the topmost modal view controller that
fills the window. If the view controller supports the new
orientation, the system rotates the window and the view
controller. The system only calls this method if the view
controller's shouldAutorotate method returns YES, which is the
default value.
The event handler is refactored to receive the internal screen
orientation value instead of the enum value of the UIKit enum
UIInterfaceOrientation. The convertion from UIInterfaceOrientation
to ScreenOrientation is done in iPhoneView class instead when
sending the new orientation value to the event handler.
This also makes the convertion aligned with the screen orientation
settings in the function setSupportedScreenOrientation.
Add options to let the user configure the screen orientation when
in games and in launcher. The option can be set per game as well
to allow for some games to start in landscape mode while others
in landscape mode.
This commit implements the options in the backend menu tab. The
code is very much similar as the one implemented in the Android
backend.
Open the iOS system keyboard automatically when starting a game and
screen orientation is portrait. If orientation changes to portrait,
open the keyboard automatically only if game is running.
The Apple TV remote sends touch events of type UITouchTypeIndirect
since it's not touches made on the screen. In iOS touchpads might
send UITouchTypeIndirect touch events as well as mouse move events.
So in iOS we want to block touches of type UITouchTypeIndirect
while in TV OS we want them to be handled.
Touchpad mode for touch events is also required for the Apple TV
remote to work properly. Make sure to disable the possibility to
disable touchpad mode in TV OS.
It's important that the main frame, displaying the OpenGL rendered
graphics, has the proper dimensions and depending on the device
orientation. It's also important that the frame is not covered by
the iOS keyboard.
This commit calculates the frame size depening on the orientation
and the keyboard status. The keyboard knows its parent view and
can resize it when the keyboard becomes visible or hidden.
There are multiple scenarios where the frame size is changed.
- When the keyboard is hidden/shown which can be automatically
change depending on the device orientation
- If the system demands the keyboard to get visible or hidden
- When rotating the device
- When suspending/resuming the application
There can also be combination of the scenarios above, e.g. if
suspending the application in landscape mode and resume it in
portrait mode.
A lot of effort has been put into testing different scenarios to
verify that the screen size becomes correct. However there might
be some scenario which has not been covered.
If not in "click-and-drag" mode, left mouse button down and up
events are sent on touches ended if the touch lasted less than
250 ms. If the touch lasted longer it was considered as a move
and no button events are sent.
This commit mimic that behaviour in touchpad mode when "click-
and-drag" mode is enabled. The left mouse button down event is
queued for 250 ms. If the touch is dragged within 250 ms it is
considered as a move and the queued mouse button down event is
cacelled. If no movement is made withing 250 ms the queued
mouse button event is processed.
Implement the same "hacky" way to switch between the 2D and 3D
iOSGraphicsManagers as the Android and SDL backends.
This commit enables 3D capable games to utilise the horse powers
in the GPU to render graohic. Older iPhones and iPads (iPhone 6,
iPad Mini v1) are able to run quite advanced games without any
stuttering if run in Release mode.
Delete the old graphic handling in the IOS7 backend which is not
used anymore after implementing iOSGraphicsManager.
The Accelerate framework is not used anymore. The OpenGLGraphics
manager handles the different color formats.
When the screen dimension changes, e.g. on rotation of the device,
the graphic manager has to be informed of the new dimension to be
able to resize the surfaces.
To quickly redraw the entire screen, Common::EVENT_SCREEN_CHANGED
event is passed to the event handler.
Previously the mouse position in the view was tracked using the
pointerPosition property. Scaling and relative mosue movements
were calculated in the view using screen properties stored in the
videoContext structure. Now when moving to iOSGraphicsManager all
that handling will be handled by the WindowedGraphicsManager,
which the iOSGraphicsManager inherit.
Rework the input code to send down pure x and y position values,
scaled according to the view content scale factor.
Remove code related to mouse movement that is no longer needed.
Implement callbacks to set up OpenGL context, destroy context, get
scale factor and screen sizes. Implement rendering of graphics drawn
by the iOS graphicsManager.
This commit will enable graphics to be shown again. Screen rotation
and mouse movements are still to be adapted.
Remove all pure virtual functions in OSystem_iOS7 since they are
implemented by ModularGraphicsBackend.
This commit will break the graphics implementation in the ios7
backend and crash due to no OpenGL context created for the
graphicsManager to use.
The ios7 backend implements the graphic handling in the backend code.
iOS supports OpenGL through the OpenGL Framework since iOS 2.0. It's
marked as deprecated but is still shipped with the SDKs for iPhoneOS
and tvOS and will hopefully be so for some time.
The ios7 backend can therefore utilize the OpenGLGraphicsManager to
handle all graphics.
Implement an iOSGraphicsManager class that can be used in the ios7
backend. The iOSGraphicsManager will require some callback functions
in the ios7 backend. createOpenGLContext() will be called to ask the
backend to create an OpenGL context in which the graphic manager can
draw. The function returns the ID of the renderbuffer which shall be
used when creating the framebuffer object this differ iOS from other
platforms). A custom RenderBufferTarget class is added to address
this.
destroyOpenGLContext() will be called to make sure that the old GLES
context is not reused. notifyContextDestroy() does call the function
OpenGLContext.reset() but that will not destroy the context.
refreshScreen() will be called to ask the backend to present the
drawn graphics on the screen. getSystemHiDPIScreenFactor() is called
to get the screen scaling factor. getScreenWidth() and
getScreenHeight() are called to get the width and height of the
surface to draw on.
This commit adds the class but the ios7 backend doesn't make use of
it quite yet. To use it require the ios7 to be a child class of the
ModularGraphicsBackend. That change requires a lot of changes which
will be targeted in separate commits.
Update docportal and github ci worker to only disable the feature
opengl_classic_game since opengl and opengl_shaders are required to
compile the OpenGLGraphicsManager.
- Atari TT support
- all video and audio is now handled via XBIOS
- reworked IKBD handling using Kbdvbase vectors, esp. Kbdvec()
- video uses proper triple buffer
- arbitrary game screen size support
- many fixes and optimizations
Implement support to set the mouse pointer speed in settings.
The mouse pointer speed is applied to both mouse input and touch
input when in touchpad-mode.
The delta values are in number of pixels on the native screen
resolution. Need to scale down the delta values based on the
game resolution. Store reminders that are added to next deltas
to mitigate "dead zones" if doing small movements.
Add input events that can be used by mouse devices, e.g. mices and
touchpads. This event sends the raw input actions and doesn't care
about different controller modes such as click-and-drag.
Make the mouse controller utilize the new mouse input events.
The current mouse events are handling events created from both touch
and mouse input. The events have lots of logic to deal with gestures
and different modes (touchpad mode, click-and-drag etc) which are not
applicable for hardware inputs.
Rename the current "mouse events" to "touch events" to clarify which
input that triggered an event. As this is the first commit in multi-
commit change, the mouse input need to use the "touch events" until
a new "mouse event" is implemented.
The Gecko USB serial adapter is no longer easy to obtain and using
the Ethernet adapter instead is supported by devkitPro/libogc.
However, when enabled, this fails to link when dynamic plugins are
enabled due to missing symbols for gdbstub_getoffsets() found in
devkitPro/libogc/libdb/debug_supp.c. To be exact, this is the
u8 __text_fstart[],__data_fstart[],__bss_fstart[] which should be
implicitly provided by the linker(?)
A monolithic static build with this enabled does succeed, but has not
yet been tested.
- "fat" version uses repacked (zip -0) archives; also separate "data"
and "themes" folders
- "slim" version doesn't use any external themes (for speed reasons)
- consolidate public #define's (just ATARI)
- cpu compiler flags are specified in the script
- allow explicit move16, SV and SV Blitter features enabled/disabled
Provide two build scripts:
1. "Fat" one targeted at 040/060 machines (possibly with SuperVidel)
This one is optimized for 68020-60 (so it's still possible to try
highres engines on 68030 machines).
2. "Slim" one targeted at 030 machines (Falcon030+DFB/CT2 or TT030)
This one is optimized for 68030 and stripped from even more features:
"fancy" (highres) themes, move16 & SuperVidel routines and most
importantly the highres engines.
There is a race condition when iOS updates the safe insets and
the view is updated on orientation changes. When rotating the
device the callback function interfaceOrientationChanged is
called. This triggers rebuildSurface to be called, which will
call updateOutputSurface, which will trigger initSurface. That
function will finally will adjust the main frame towards the
safe areas by calling the function adjustViewFrameForSafeArea.
But it seems that when adjustViewFrameForSafeArea is called the
safe insets values are not updated which will lead to wrong
offset values in the frame for touches which will make the mouse
pointer inaccurate.
The iOS system makes calls to safeAreaInsetsDidChange whenever
the safe insets values are updated. Make sure to update the frame
on these calls to get correct touch offsets.
Apple introduced the GCVirtualController in iOS 15 which is a
software emulation of a real controller. The virtual controllers
can be configurable with different inputs. See more info at:
https://developer.apple.com/documentation/gamecontroller/gcvirtualcontroller
A simple gamepad configuration with a dPad and A and B buttons
is added. The user can enable/disable the virtual game controller
swiping two fingers right to left, or through the port-specific
option dialog.
Some game engines requires the dpad to control a character. The GRIM
engine is an example of this where the user steer the character by
the arrow keys or dpad controller.
The "touchpad" mode and "click-and-drag" mode was mutual exclusive
when enabling "click-and-drag" using swipe gesture.
The difference between "touchpad" mode and "click-and-drag" mode
is how the button down/up events are sent. In touchpad mode the
button down and button up events are sent on touches ended, while
in click-and-drag the button down event is sent on touches began
and button up on touches ended.
Include the newly added ios7_options implementation to the project.
Change the file type to .mm which is Objective C++ to be able to use
the @availble mechanism.
Implement virtual functions and fix build errors in initial code.
Also add help section for the tvOS port when building for tvOS.
Add ios7_options to POTFILES to get automatic translation on the
help section.
On iOS 12 and below, the one delegate methods are called. On iOS13.2
and above if both sets are implemented only the new delegate methods
are called, which prevent getting the deprecation warning.
This reverts commit 46d6a76b8e.
The commit broke saving and restoring state when compiling with SDK 13
or above and running on iOS 12 or below. The functions to save/restore
were no longer called.
The delegate methods application:shouldRestoreApplicationState
is replaced with application:shouldRestoreSecureApplicationState
and the method application:shouldSaveApplicationState with
application:shouldSaveSecureApplicationState.
To support older versions of iOS, put them in a version check
macro.
The timeHandler was driven by calls to the pollEvent callback function.
Each time pollEvent was called the timeHandler called the TimeManager
handle function to advance in time and make sure scheduled tasks were
triggered.
This worked good for most game engines but some, e.g. the Hypno engine
was using the TimeManager to schedule tasks without calling pollEvent
since it was expecting nor handling events at the specific point in
time.
Since iOS have threads the timerHandler can be called from a separate
thread and not rely on pollEvent.
Implement timerHandler to use a Timer Dispatch Source which and make
it operate on a background thread rather than the main thread.
Read more on Dispatch Sources here:
https://developer.apple.com/library/archive/documentation/General/
Conceptual/ConcurrencyProgrammingGuide/GCDWorkQueues/GCDWorkQueues.html
Previously no log file was used as it attempted to create it in
a directory not accessible by the application. The commit also fixes
accessing the log file from the Options dialog (it needs the
sandboxed path and not the full path).
This was used in the past to make sure the code can be compiled
with old compilers that do not support using @available. But we
already dropped support for those old compilers, and in many
places already used @available without checking first that it can
be used.
The main change in to use the interface orientation and not the device
orientation. This may be different for example when locking the orientation.
This also changes the way orientation changes are detected using the
documented method. However this means dropping support for iOS 7 as this
method is only available since iOS 8, and alternative methods available in
iOS 7 have been deprecated in iOS 13.
Another change is to properly detect the interface orientation instead of
infering it from the view bounds, which was incorrect on some devices.
According to documentation getExternalFilesDir returns the absolute path to application-specific directory
May return null if shared storage is not currently available.
This will not happen for getFilesDir() which returns the internal app path (always guaranteed to be available)
ScummVM engines are not built for synchronous screen locking (i.e.
updateScreen() can't be really used for any sort of blocking updates
otherwise performance suffers).
Single buffering now means deliberate tearing as a speed optimization
and triple buffering provides a tearingless picture with slight overhead.
"make dist-generic" doesn't automatically look for files in "data"
folder. Commit be98f2a8 is somewhat related to this problem but only
for debugging purposes.
As relative "data" clashes with game's relative "data" (e.g. Full
Throttle demo), do the right thing and add it as absolute path.
and joystick deadzone. By supporting kFeatureKbdMouseSpeed and kFeatureJoystickDeadzone and registering default values
Both of these config settings (kbdmouse_speed, joystick_deadzone) factor in virtual mouse movement.
Helps handle virtual mouse pointer speed when controlled with DPAD or is too fast for the user