diff --git a/project/jni/application/atari800/AndroidAppSettings.cfg b/project/jni/application/atari800/AndroidAppSettings.cfg old mode 100644 new mode 100755 index 3e87d2620..2cd6cde0f --- a/project/jni/application/atari800/AndroidAppSettings.cfg +++ b/project/jni/application/atari800/AndroidAppSettings.cfg @@ -1,34 +1,252 @@ # The application settings for Android libSDL port -AppSettingVersion=16 -LibSdlVersion=1.2 -AppName="Atari800" + +# Specify application name (e.x. My Application) +AppName="Atari800-SDL" + +# Specify reversed site name of application (e.x. com.mysite.myapp) AppFullName=net.sourceforge.atari800 -ScreenOrientation=h -InhibitSuspend=n -AppDataDownloadUrl="Download Atari ROM, note that it is ILLEGAL to download it without owning Atari device!|atari800-data.zip" -SdlVideoResize=y -SdlVideoResizeKeepAspect=n -NeedDepthBuffer=n -AppUsesMouse=n -AppNeedsTwoButtonMouse=n -AppNeedsArrowKeys=y -AppNeedsTextInput=y -AppUsesJoystick=n -AppHandlesJoystickSensitivity=y -AppUsesMultitouch=n -NonBlockingSwapBuffers=n -RedefinedKeys="F6 RETURN F4 F3 F1 ESCAPE F6 F3 F4 F2 F6" -AppTouchscreenKeyboardKeysAmount=6 -AppTouchscreenKeyboardKeysAmountAutoFire=2 -RedefinedKeysScreenKb="F6 F1 RETURN F4 F3 F2" -MultiABI=n -AppVersionCode=21003 -AppVersionName="2.2.0rc2.02" -CompiledLibraries="jpeg png" -CustomBuildScript=y -AppCflags='' -AppLdflags='' -AppSubdirsBuild='' -AppUseCrystaXToolchain=n -AppCmdline='-audio16' + +# Application version code (integer) +AppVersionCode=31003 + +# Application user-visible version name (string) +AppVersionName="3.1.0" + +# Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...' +# If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu +# If the URL in in the form ':dir/file.dat:http://URL/' it will be downloaded as binary BLOB to the application dir and not unzipped +# If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir - +# these files are put inside .apk package by build system +# Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS +AppDataDownloadUrl="!!Download Atari ROM, note that it is ILLEGAL to download it without owning Atari device!|atari800-data.zip^!!gui files|guichan28012015.zip" + +# Reset SDL config when updating application to the new version (y) / (n) +ResetSdlConfigForThisVersion=y +TextInputKeyboard=4 +# Delete application data files when upgrading (specify file/dir paths separated by spaces) +DeleteFilesOnUpgrade="" + +# Here you may type readme text, which will be shown during startup. Format is: +# Text in English, use \\\\n to separate lines (that's four backslashes)^de:Text in Deutsch^ru:Text in Russian^button:Button that will open some URL:http://url-to-open/ ReadmeText='^You may press "Home" now - the data will be downloaded in background' + +# libSDL version to use (1.2/1.3/2.0) +LibSdlVersion=1.2 + +# Specify screen orientation: (v)ertical/(p)ortrait or (h)orizontal/(l)andscape +ScreenOrientation=h + +# Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only +# with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32) +VideoDepthBpp=16 + +# Enable OpenGL depth buffer (needed only for 3-d applications, small speed decrease) (y) or (n) +NeedDepthBuffer=n + +# Enable OpenGL stencil buffer (needed only for 3-d applications, small speed decrease) (y) or (n) +NeedStencilBuffer=n + +# Try to use GLES 2.x context - will revert to GLES 1.X if unsupported by device +# you need this option only if you're developing 3-d app (y) or (n) +NeedGles2=n + +# Application uses software video buffer - you're calling SDL_SetVideoMode() without SDL_HWSURFACE and without SDL_OPENGL, +# this will allow small speed optimization. Enable this even when you're using SDL_HWSURFACE. (y) or (n) +SwVideoMode=y + +# Application video output will be resized to fit into native device screen (y)/(n) +SdlVideoResize=y + +# Application resizing will keep 4:3 aspect ratio, with black bars at sides (y)/(n) +SdlVideoResizeKeepAspect=n + +# Do not allow device to sleep when the application is in foreground, set this for video players or apps which use accelerometer +InhibitSuspend=y + +# Create Android service, so the app is less likely to be killed while in background +CreateService= + +# Application does not call SDL_Flip() or SDL_UpdateRects() appropriately, or draws from non-main thread - +# enabling the compatibility mode will force screen update every 100 milliseconds, which is laggy and inefficient (y) or (n) +CompatibilityHacks=n + +# Application initializes SDL audio/video inside static constructors (which is bad, you won't be able to run ndk-gdb) (y)/(n) +CompatibilityHacksStaticInit=n + +# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n) +CompatibilityHacksTextInputEmulatesHwKeyboard=y + +# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n) +CompatibilityHacksPreventAudioChopping=n + +# Hack for broken apps: application ignores audio buffer size returned by SDL (y)/(n) +CompatibilityHacksAppIgnoresAudioBufferSize=n + +# Hack for VCMI: preload additional shared libraries before aplication start +CompatibilityHacksAdditionalPreloadedSharedLibraries="" + +# Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue - +# do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n) +CompatibilityHacksSlowCompatibleEventQueue=y + +# Save and restore OpenGL state when drawing on-screen keyboard for apps that use SDL_OPENGL +CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState= + +# Application uses SDL_UpdateRects() properly, and does not draw in any region outside those rects. +# This improves drawing speed, but I know only one application that does that, and it's written by me (y)/(n) +CompatibilityHacksProperUsageOfSDL_UpdateRects= + +# Application uses mouse (y) or (n), this will show mouse emulation dialog to the user +AppUsesMouse=y + +# Application needs two-button mouse, will also enable advanced point-and-click features (y) or (n) +AppNeedsTwoButtonMouse=n + +# Right mouse button can do long-press/drag&drop action, necessary for some games (y) or (n) +# If you disable it, swiping with two fingers will send mouse wheel events +RightMouseButtonLongPress= + +# Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n) +ShowMouseCursor=n + +# Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n) +GenerateSubframeTouchEvents= + +# Force relative (laptop) mouse movement mode, useful when both on-screen keyboard and mouse are needed (y) or (n) +ForceRelativeMouseMode=n + +# Application needs arrow keys (y) or (n), will show on-screen dpad/joystick (y) or (n) +AppNeedsArrowKeys=y + +FloatingScreenJoystick=y + +# Application needs text input (y) or (n), enables button for text input on screen +AppNeedsTextInput=y + +# Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1 +AppUsesJoystick=n + +# Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n) +AppUsesSecondJoystick=n + +# Application uses third on-screen joystick, as SDL joystick 0 axes 20-21 (y)/(n) +AppUsesThirdJoystick= + +# Application uses accelerometer (y) or (n), the accelerometer will be used as joystick 1 axes 0-1 and 5-7 +AppUsesAccelerometer=n + +# Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4 +AppUsesGyroscope=n + +# Use gyroscope to move mouse cursor (y) or (n), it eats battery, and can be disabled in settings, do not use with AppUsesGyroscope setting +MoveMouseWithGyroscope= + +# Application uses multitouch (y) or (n), multitouch events are passed as SDL_JOYBALLMOTION events for the joystick 0 +AppUsesMultitouch=n + +# Application records audio (it will use any available source, such a s microphone) +# API is defined in file SDL_android.h: int SDL_ANDROID_OpenAudioRecording(SDL_AudioSpec *spec); void SDL_ANDROID_CloseAudioRecording(void); +# This option will add additional permission to Android manifest (y)/(n) +AppRecordsAudio=n + +# Application needs to access SD card. If your data files are bigger than 5 Mb, enable it. (y) / (n) +AccessSdCard= + +# Application needs Internet access. If you disable it, you'll have to bundle all your data files inside .apk (y) / (n) +AccessInternet= + +# Immersive mode - Android will hide on-screen Home/Back keys. Looks bad if you invoke Android keyboard. (y) / (n) +ImmersiveMode= + +# Application implements Android-specific routines to put to background, and will not draw anything to screen +# between SDL_ACTIVEEVENT lost / gained notifications - you should check for them +# rigth after SDL_Flip(), if (n) then SDL_Flip() will block till app in background (y) or (n) +# This option is reported to be buggy, sometimes failing to restore video state +NonBlockingSwapBuffers=n + +# Redefine common hardware keys to SDL keysyms +# BACK hardware key is available on all devices, MENU is available on pre-ICS devices, other keys may be absent +# SEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices +# Use word NO_REMAP if you want to preserve native functionality for certain key (volume keys are 3-rd and 4-th) +# Keys: TOUCHSCREEN (works only when AppUsesMouse=n), DPAD_CENTER/SEARCH, VOLUMEUP, VOLUMEDOWN, MENU, BACK, CAMERA +RedefinedKeys="F6 RETURN NO_REMAP NO_REMAP F1 F1 F6 F3 F4 F2 F6" + +# Number of virtual keyboard keys (currently 6 is maximum) +AppTouchscreenKeyboardKeysAmount=5 + +# Redefine on-screen keyboard keys to SDL keysyms - 6 keyboard keys + 4 multitouch gestures (zoom in/out and rotate left/right) +RedefinedKeysScreenKb="F6 F4 F3 F2 F5 F1" + +# Names for on-screen keyboard keys, such as Fire, Jump, Run etc, separated by spaces, they are used in SDL config menu +RedefinedKeysScreenKbNames="F6 F4 F3 F2 F5 F1" + +# On-screen keys theme +# 0 = Ultimate Droid by Sean Stieber (green, with gamepad joystick) +# 1 = Simple Theme by Beholder (white, with gamepad joystick) +# 2 = Sun by Sirea (yellow, with round joystick) +# 3 = Keen by Gerstrong (multicolor, with round joystick) +TouchscreenKeysTheme=2 + +# Redefine gamepad keys to SDL keysyms, button order is: +# A B X Y L1 R1 L2 R2 LThumb RThumb +RedefinedKeysGamepad="F6 F4 F3 F2 F5 F1" + +# How long to show startup menu button, in msec, 0 to disable startup menu +StartupMenuButtonTimeout=3000 + +# Menu items to hide from startup menu, available menu items: +# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout +HiddenMenuOptions='SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMouse.DisplaySizeConfig' + +# Menu items to show at startup - this is Java code snippet, leave empty for default +# new SettingsMenuMisc.ShowReadme(), (AppUsesMouse \&\& \! ForceRelativeMouseMode \? new SettingsMenuMouse.DisplaySizeConfig(true) : new SettingsMenu.DummyMenu()), new SettingsMenuMisc.OptionalDownloadConfig(true), new SettingsMenuMisc.GyroscopeCalibration() +# Available menu items: +# SettingsMenu.OkButton SettingsMenu.DummyMenu SettingsMenu.MainMenu SettingsMenuMisc.DownloadConfig SettingsMenuMisc.OptionalDownloadConfig SettingsMenuMisc.AudioConfig SettingsMenuMisc.VideoSettingsConfig SettingsMenuMisc.ShowReadme SettingsMenuMisc.GyroscopeCalibration SettingsMenuMisc.ResetToDefaultsConfig SettingsMenuMouse.MouseConfigMainMenu SettingsMenuMouse.DisplaySizeConfig SettingsMenuMouse.LeftClickConfig SettingsMenuMouse.RightClickConfig SettingsMenuMouse.AdditionalMouseConfig SettingsMenuMouse.JoystickMouseConfig SettingsMenuMouse.TouchPressureMeasurementTool SettingsMenuMouse.CalibrateTouchscreenMenu SettingsMenuKeyboard.KeyboardConfigMainMenu SettingsMenuKeyboard.ScreenKeyboardSizeConfig SettingsMenuKeyboard.ScreenKeyboardDrawSizeConfig SettingsMenuKeyboard.ScreenKeyboardThemeConfig SettingsMenuKeyboard.ScreenKeyboardTransparencyConfig SettingsMenuKeyboard.RemapHwKeysConfig SettingsMenuKeyboard.RemapScreenKbConfig SettingsMenuKeyboard.ScreenGesturesConfig SettingsMenuKeyboard.CustomizeScreenKbLayout +FirstStartMenuOptions='' + +# Enable multi-ABI binary, with hardware FPU support - it will also work on old devices, +# but .apk size is 2x bigger (y) / (n) / (x86) / (all) +MultiABI='armeabi-v7a' + +# Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower +AppMinimumRAM=256 + +# Optional shared libraries to compile - removing some of them will save space +# MP3 support by libMAD is encumbered by patents and libMAD is GPL-ed +# Available libraries: mad (GPL-ed!) sdl_mixer sdl_image sdl_ttf sdl_net sdl_blitpool sdl_gfx sdl_sound intl xml2 lua jpeg png ogg flac tremor vorbis freetype xerces curl theora fluidsynth lzma lzo2 mikmod openal timidity zzip bzip2 yaml-cpp python boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu avcodec avdevice avfilter avformat avresample avutil swscale swresample bzip2 +CompiledLibraries="sdl_image sdl_ttf guichan" + +# Application uses custom build script AndroidBuild.sh instead of Android.mk (y) or (n) +CustomBuildScript=y + +# Aditional CFLAGS for application +AppCflags='' + +# Additional LDFLAGS for application +AppLdflags='' + +# If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable +AppOverlapsSystemHeaders= + +# Build only following subdirs (empty will build all dirs, ignored with custom script) +AppSubdirsBuild='' + +# Exclude these files from build +AppBuildExclude='' + +# Application command line parameters, including app name as 0-th param +AppCmdline='-audio16' + +# Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens +# Minimum screen size that application supports: (s)mall / (m)edium / (l)arge +MinimumScreenSize=s + +# Your AdMob Publisher ID, (n) if you don't want advertisements +AdmobPublisherId=n + +# Your AdMob test device ID, to receive a test ad +AdmobTestDeviceId= + +# Your AdMob banner size (BANNER/IAB_BANNER/IAB_LEADERBOARD/IAB_MRECT/IAB_WIDE_SKYSCRAPER/SMART_BANNER) +AdmobBannerSize= + diff --git a/project/jni/application/atari800/AndroidBuild.sh b/project/jni/application/atari800/AndroidBuild.sh index 7c4949b67..8455f7f60 100755 --- a/project/jni/application/atari800/AndroidBuild.sh +++ b/project/jni/application/atari800/AndroidBuild.sh @@ -1,17 +1,18 @@ #!/bin/sh - LOCAL_PATH=`dirname $0` LOCAL_PATH=`cd $LOCAL_PATH && pwd` -ln -sf libsdl-1.2.so $LOCAL_PATH/../../../obj/local/armeabi/libSDL.so +JOBS=1 -if [ \! -f atari800/configure ] ; then - sh -c "cd atari800/src && ./autogen.sh" +ln -sf libsdl-1.2.so $LOCAL_PATH/../../../obj/local/$1/libSDL.so + +if [ \! -f atari800/src/configure ] ; then + env sh -c "cd atari800/src && ./autogen.sh" fi if [ \! -f atari800/src/Makefile ] ; then - ../setEnvironment.sh sh -c "cd atari800/src && ./configure --build=x86_64-unknown-linux-gnu --host=arm-linux-androideabi --target=sdl --without-x" + ../setEnvironment-$1.sh sh -c "cd atari800/src && ./configure --build=x86_64-unknown-linux-gnu --host=$2 --target=default --without-x --enable-onscreenkeyboard" fi -make -C atari800/src && mv -f atari800/src/atari800 libapplication.so +make -C atari800/src -j$JOBS && mv -f atari800/src/atari800 libapplication-$1.so diff --git a/project/jni/application/atari800/AndroidData/atari800-data.zip b/project/jni/application/atari800/AndroidData/atari800-data.zip old mode 100644 new mode 100755 index 5711c44a9..198e63089 Binary files a/project/jni/application/atari800/AndroidData/atari800-data.zip and b/project/jni/application/atari800/AndroidData/atari800-data.zip differ diff --git a/project/jni/application/atari800/AndroidData/guichan28012015.zip b/project/jni/application/atari800/AndroidData/guichan28012015.zip new file mode 100755 index 000000000..929bc8fa5 Binary files /dev/null and b/project/jni/application/atari800/AndroidData/guichan28012015.zip differ diff --git a/project/jni/application/atari800/atari800-2.2.0rc2-cvs.diff b/project/jni/application/atari800/atari800-2.2.0rc2-cvs.diff deleted file mode 100644 index 78503dfd8..000000000 --- a/project/jni/application/atari800/atari800-2.2.0rc2-cvs.diff +++ /dev/null @@ -1,71 +0,0 @@ -Only in atari800/atari800/src: config.h.in -diff -ru orig/atari800/atari800/src/config.sub atari800/atari800/src/config.sub ---- orig/atari800/atari800/src/config.sub 2006-04-08 08:07:36.000000000 -0400 -+++ atari800/atari800/src/config.sub 2011-02-03 10:28:16.000000000 -0500 -@@ -1206,7 +1206,7 @@ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ -- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ -+ | -udi* | -eabi* | -androideabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ -diff -ru orig/atari800/atari800/src/configure.ac atari800/atari800/src/configure.ac ---- orig/atari800/atari800/src/configure.ac 2010-12-07 10:16:26.000000000 -0500 -+++ atari800/atari800/src/configure.ac 2011-02-03 10:45:32.000000000 -0500 -@@ -97,7 +97,7 @@ - AC_DEFINE(DOS_DRIVES,1,[Define to enable DOS style drives support.]) - AC_DEFINE(SYSTEM_WIDE_CFG_FILE,"c:\\atari800.cfg",[Alternate system-wide config file for non-Unix OS.]) - ;; -- linux | linux-gnu) -+ linux | linux-gnu | androideabi) - a8_host="linux" - ;; - mint) -@@ -301,7 +301,7 @@ - WANT_NTSC_FILTER=yes - LIBS="$LIBS `sdl-config --libs`" - OBJS="videomode.o sdl/main.o sdl/video.o sdl/video_sw.o sdl/input.o sdl/palette.o" -- CFLAGS="$CFLAGS -ansi -pedantic -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Winline" -+ CFLAGS="$CFLAGS -O3 -pedantic -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Winline" - if [[ "$a8_host" != "beos" ]]; then - dnl BeOS has a real issue with redundant-decls - CFLAGS="$CFLAGS -Wredundant-decls" -Only in atari800/atari800/src: configure.ac~ -diff -ru orig/atari800/atari800/src/sdl/input.c atari800/atari800/src/sdl/input.c ---- orig/atari800/atari800/src/sdl/input.c 2010-12-07 10:16:26.000000000 -0500 -+++ atari800/atari800/src/sdl/input.c 2011-02-03 10:46:35.000000000 -0500 -@@ -22,9 +22,11 @@ - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -+#ifndef ANDROID - #ifdef __linux__ - #define LPTJOY 1 - #endif -+#endif - - #ifdef LPTJOY - #include -@@ -1214,6 +1216,9 @@ - int stick0, stick1; - stick0 = stick1 = INPUT_STICK_CENTRE; - -+ if( !kbhits ) -+ return; -+ - if (PLATFORM_kbd_joy_0_enabled) { - if (kbhits[KBD_STICK_0_LEFT]) - stick0 = INPUT_STICK_LEFT; -@@ -1281,6 +1286,9 @@ - int trig0, trig1, i; - trig0 = trig1 = 1; - -+ if( !kbhits ) -+ return; -+ - if (PLATFORM_kbd_joy_0_enabled) { - trig0 = kbhits[KBD_TRIG_0] ? 0 : 1; - } -Only in atari800/atari800/src/sdl: input.c~ diff --git a/project/jni/application/atari800/atari800-3.1.0-sdl-android-28012015.diff b/project/jni/application/atari800/atari800-3.1.0-sdl-android-28012015.diff new file mode 100644 index 000000000..fb6afffe8 --- /dev/null +++ b/project/jni/application/atari800/atari800-3.1.0-sdl-android-28012015.diff @@ -0,0 +1,2083 @@ +diff -Nru atari800-3.1.0/src/atari.c atari800-3.1.0-android/src/atari.c +--- atari800-3.1.0/src/atari.c 2014-03-03 11:24:13.000000000 +0200 ++++ atari800-3.1.0-android/src/atari.c 2016-08-27 20:52:01.111419183 +0300 +@@ -416,11 +416,11 @@ + } + *argc = j; + } +-#ifndef ANDROID ++//#ifndef ANDROID + got_config = CFG_LoadConfig(rtconfig_filename); +-#else +- got_config = TRUE; /* pretend we got a config file -- not needed in Android */ +-#endif ++//#else ++// got_config = TRUE; /* pretend we got a config file -- not needed in Android */ ++//#endif + + /* try to find ROM images if the configuration file is not found + or it does not specify some ROM paths (blank paths count as specified) */ +@@ -1227,7 +1227,11 @@ + #ifdef SOUND + Sound_Pause(); + #endif ++#ifdef GUICHAN_GUI ++int startgui = gui_open(); ++#else + UI_Run(); ++#endif + #ifdef SOUND + Sound_Continue(); + #endif +diff -Nru atari800-3.1.0/src/autogen.sh atari800-3.1.0-android/src/autogen.sh +--- atari800-3.1.0/src/autogen.sh 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/autogen.sh 2016-08-27 20:52:01.111419183 +0300 +@@ -0,0 +1,58 @@ ++#! /bin/sh ++# Run this to generate all the initial makefiles, etc. ++# This was lifted from the BasiliskII, and adapted slightly by ++# Milan Jurik. ++ ++DIE=0 ++ ++PROG="ARAnyM" ++ ++# Check for GNU make ++ ++test -z "$MAKE" && MAKE=make ++ ++# Check how echo works in this /bin/sh ++case `echo -n` in ++-n) _echo_n= _echo_c='\c';; ++*) _echo_n=-n _echo_c=;; ++esac ++ ++(autoconf --version) < /dev/null > /dev/null 2>&1 || { ++ echo ++ echo "You must have autoconf installed to compile $PROG." ++ echo "Download the appropriate package for your distribution," ++ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" ++ DIE=1 ++} ++ ++(aclocal --version) < /dev/null > /dev/null 2>&1 || { ++ echo ++ echo "**Error**: Missing aclocal. The version of automake" ++ echo "installed doesn't appear recent enough." ++ echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" ++ echo "(or a newer version if it is available)" ++ DIE=1 ++} ++ ++if test "$DIE" -eq 1; then ++ exit 1 ++fi ++ ++if [ -z "$*" -a -z "$NO_CONFIGURE" ]; then ++ echo "I am going to run ./configure with no arguments - if you wish " ++ echo "to pass any to it, please specify them on the $0 command line." ++fi ++ ++ACLOCAL_FLAGS="-I m4" ++aclocalinclude="$ACLOCAL_FLAGS"; \ ++(echo $_echo_n " + Running aclocal: $_echo_c"; \ ++ aclocal $aclocalinclude; \ ++ echo "done.") && \ ++(echo $_echo_n " + Running autoheader: $_echo_c"; \ ++ autoheader; \ ++ echo "done.") && \ ++(echo $_echo_n " + Running autoconf: $_echo_c"; \ ++ autoconf; \ ++ echo "done.") ++ ++echo all done +diff -Nru atari800-3.1.0/src/config.h.in atari800-3.1.0-android/src/config.h.in +--- atari800-3.1.0/src/config.h.in 2014-04-12 17:00:06.000000000 +0300 ++++ atari800-3.1.0-android/src/config.h.in 2016-08-27 21:31:09.313424966 +0300 +@@ -539,6 +539,11 @@ + /* Target: X11 with XView. */ + #undef XVIEW + ++/* Enable large inode numbers on Mac OS X 10.5. */ ++#ifndef _DARWIN_USE_64_BIT_INODE ++# define _DARWIN_USE_64_BIT_INODE 1 ++#endif ++ + /* Number of bits in a file offset, on hosts where this is settable. */ + #undef _FILE_OFFSET_BITS + +diff -Nru atari800-3.1.0/src/config.sub atari800-3.1.0-android/src/config.sub +--- atari800-3.1.0/src/config.sub 2006-04-08 15:07:36.000000000 +0300 ++++ atari800-3.1.0-android/src/config.sub 2016-08-27 20:52:01.111419183 +0300 +@@ -1206,7 +1206,7 @@ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ +- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ ++ | -udi* | -eabi* | -androideabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ +diff -Nru atari800-3.1.0/src/configure atari800-3.1.0-android/src/configure +--- atari800-3.1.0/src/configure 2014-04-12 17:00:06.000000000 +0300 ++++ atari800-3.1.0-android/src/configure 2016-08-27 22:22:50.164432577 +0300 +@@ -4594,7 +4594,7 @@ + case "$a8_target" in + default) + if [ "$a8_host" != "dos" ]; then +- CFLAGS="$CFLAGS -ansi" ++ CFLAGS="$CFLAGS -DGUICHAN_GUI" + fi + CFLAGS="$CFLAGS -pedantic -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Winline" + if [ "$a8_host" != "beos" ]; then +@@ -10939,6 +10939,7 @@ + echo + echo "Main build variables:" + echo " CC......: \"$CC\"" ++echo " CXX.....: \"$CXX\"" + echo " CFLAGS..: \"$CFLAGS\"" + echo " CPPFLAGS: \"$CPPFLAGS\"" + echo " LDFLAGS.: \"$LDFLAGS\"" +diff -Nru atari800-3.1.0/src/configure.ac atari800-3.1.0-android/src/configure.ac +--- atari800-3.1.0/src/configure.ac 2014-04-12 16:58:16.000000000 +0300 ++++ atari800-3.1.0-android/src/configure.ac 2016-08-27 20:52:01.119418863 +0300 +@@ -271,7 +271,7 @@ + default) + if [[ "$a8_host" != "dos" ]]; then + dnl In DJGPP building with zlib fails with -ansi. +- CFLAGS="$CFLAGS -ansi" ++ CFLAGS="$CFLAGS -DGUICHAN_GUI" + fi + CFLAGS="$CFLAGS -pedantic -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Winline" + if [[ "$a8_host" != "beos" ]]; then +@@ -1204,6 +1204,7 @@ + echo + echo "Main build variables:" + echo " CC......: \"$CC\"" ++echo " CXX......: \"$CXX\"" + echo " CFLAGS..: \"$CFLAGS\"" + echo " CPPFLAGS: \"$CPPFLAGS\"" + echo " LDFLAGS.: \"$LDFLAGS\"" +diff -Nru atari800-3.1.0/src/guichan/guichan-gui.cpp atari800-3.1.0-android/src/guichan/guichan-gui.cpp +--- atari800-3.1.0/src/guichan/guichan-gui.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/guichan-gui.cpp 2015-01-28 18:31:10.000000000 +0200 +@@ -0,0 +1,382 @@ ++#include ++#ifdef ANDROID ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include "sdltruetypefont.hpp" ++#include ++ ++#define PANDORA ++ ++#if defined(ANDROID) ++#include ++#endif ++ ++extern SDL_Surface* SDL_VIDEO_screen; ++int emulating; ++bool running = false; ++int rungame=0; ++bool menu_onscreen = true; ++ ++#define GUI_WIDTH 640 ++#define GUI_HEIGHT 480 ++ ++/* What is being loaded */ ++#define MENU_SELECT_FILE 1 ++#define MENU_ADD_DIR 2 ++ ++char currentDir[300]; ++char launchDir[300]; ++ ++namespace globals ++{ ++gcn::Gui* gui; ++} ++ ++namespace sdl ++{ ++// Main objects to draw graphics and get user input ++gcn::SDLGraphics* graphics; ++gcn::SDLInput* input; ++gcn::SDLImageLoader* imageLoader; ++ ++void init() ++{ ++#ifdef PANDORA ++ char layersize[20]; ++ snprintf(layersize, 20, "%dx%d", GUI_WIDTH, GUI_HEIGHT); ++ ++ char bordercut[20]; ++ snprintf(bordercut, 20, "0,0,0,0"); ++ ++#endif ++ SDL_VIDEO_screen = SDL_SetVideoMode(GUI_WIDTH, GUI_HEIGHT, 16, SDL_SWSURFACE); ++ SDL_EnableUNICODE(1); ++ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); ++ ++#ifdef PANDORA ++ SDL_ShowCursor(SDL_ENABLE); ++#endif ++ ++ imageLoader = new gcn::SDLImageLoader(); ++ gcn::Image::setImageLoader(imageLoader); ++ ++ graphics = new gcn::SDLGraphics(); ++ graphics->setTarget(SDL_VIDEO_screen); ++ ++ input = new gcn::SDLInput(); ++ ++ globals::gui = new gcn::Gui(); ++ globals::gui->setGraphics(graphics); ++ globals::gui->setInput(input); ++} ++ ++ ++void halt() ++{ ++ delete globals::gui; ++ delete imageLoader; ++ delete input; ++ delete graphics; ++} ++ ++ ++void run() ++{ ++ // The main loop ++ while(running) { ++ // Check user input ++ SDL_Event event; ++ while(SDL_PollEvent(&event)) { ++ if (event.type == SDL_QUIT) { ++ running = false; ++ break; ++ } else if (event.type == SDL_KEYDOWN) { ++ switch(event.key.keysym.sym) { ++ case SDLK_ESCAPE: ++ case SDLK_F1: ++ running = false; ++ break; ++ ++#ifndef PANDORA ++ case SDLK_f: ++ if (event.key.keysym.mod & KMOD_CTRL) { ++ // Works with X11 only ++ SDL_WM_ToggleFullScreen(SDL_VIDEO_screen); ++ } ++ break; ++#endif ++ } ++ } ++ input->pushInput(event); ++ } ++ // Now we let the Gui object perform its logic. ++ globals::gui->logic(); ++ // Now we let the Gui object draw itself. ++ globals::gui->draw(); ++ // Finally we update the screen. ++ SDL_Flip(SDL_VIDEO_screen); ++ } ++} ++ ++} ++ ++ ++namespace widgets ++{ ++extern void run_menuLoad_guichan(char *curr_path, int aLoadType); ++extern gcn::Window *window_load; ++extern gcn::Window *window_warning; ++extern gcn::Window *window_savestate; ++void show_settings(void); ++void menuSaveState_Init(void); ++void menuSaveState_Exit(void); ++void loadMenu_Init(void); ++void loadMenu_Exit(void); ++void menuMessage_Init(void); ++void menuMessage_Exit(void); ++std::string selectedFilePath; ++ ++gcn::Color baseCol; ++gcn::Color baseColLabel; ++gcn::Container* top; ++gcn::contrib::SDLTrueTypeFont* font; ++ ++// Presets ++ ++// Main buttons ++gcn::Image *background_image; ++gcn::Icon* background; ++gcn::Button* button_reset; ++gcn::Button* button_resume; ++gcn::Button* button_quit; ++gcn::Button* button_savestate; ++gcn::Container* backgrd_onscreen; ++gcn::CheckBox* checkBox_onscreen; ++ ++extern "C" { ++ void Atari800_Exit(bool); ++ int AFILE_OpenFile(const char *filename, int reboot, int diskno, int readonly); ++} ++ ++class QuitButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ running = false; ++ Atari800_Exit(false); ++ exit(0); ++ } ++}; ++QuitButtonActionListener* quitButtonActionListener; ++ ++ ++class ResetButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ run_menuLoad_guichan(currentDir, MENU_SELECT_FILE); ++ } ++}; ++ResetButtonActionListener* resetButtonActionListener; ++ ++ ++class ResumeButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ running = false; ++ } ++}; ++ResumeButtonActionListener* resumeButtonActionListener; ++ ++class StateButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ window_savestate->setVisible(true); ++ } ++}; ++StateButtonActionListener* stateButtonActionListener; ++ ++class OnscreenActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ if (actionEvent.getSource() == checkBox_onscreen) ++ if (checkBox_onscreen->isSelected()) ++ menu_onscreen=true; ++ else ++ menu_onscreen=false; ++ } ++}; ++OnscreenActionListener* onscreenActionListener; ++ ++void init() ++{ ++ baseCol.r = 192; ++ baseCol.g = 192; ++ baseCol.b = 208; ++ baseColLabel.r = baseCol.r; ++ baseColLabel.g = baseCol.g; ++ baseColLabel.b = baseCol.b; ++ baseColLabel.a = 192; ++ ++ top = new gcn::Container(); ++ top->setDimension(gcn::Rectangle(0, 0, 640, 480)); ++ top->setBaseColor(baseCol); ++ globals::gui->setTop(top); ++ ++ TTF_Init(); ++ font = new gcn::contrib::SDLTrueTypeFont("data/FreeSans.ttf", 17); ++ gcn::Widget::setGlobalFont(font); ++ ++ background_image = gcn::Image::load("data/background.jpg"); ++ background = new gcn::Icon(background_image); ++ ++ //-------------------------------------------------- ++ // Create main buttons ++ //-------------------------------------------------- ++ ++ button_quit = new gcn::Button("Quit"); ++ button_quit->setSize(90,50); ++ button_quit->setBaseColor(baseCol); ++ button_quit->setId("Quit"); ++ quitButtonActionListener = new QuitButtonActionListener(); ++ button_quit->addActionListener(quitButtonActionListener); ++ ++ button_reset = new gcn::Button("Run"); ++ button_reset->setSize(90,50); ++ button_reset->setBaseColor(baseCol); ++ button_reset->setId("Reset"); ++ resetButtonActionListener = new ResetButtonActionListener(); ++ button_reset->addActionListener(resetButtonActionListener); ++ ++ button_resume = new gcn::Button("Resume"); ++ button_resume->setSize(90,50); ++ button_resume->setBaseColor(baseCol); ++ button_resume->setId("Resume"); ++ resumeButtonActionListener = new ResumeButtonActionListener(); ++ button_resume->addActionListener(resumeButtonActionListener); ++ ++ button_savestate = new gcn::Button("SaveStates"); ++ button_savestate->setSize(100,50); ++ button_savestate->setBaseColor(baseCol); ++ button_savestate->setId("SaveStates"); ++ stateButtonActionListener = new StateButtonActionListener(); ++ button_savestate->addActionListener(stateButtonActionListener); ++ ++ checkBox_onscreen = new gcn::CheckBox("On-Screen Control"); ++ checkBox_onscreen->setPosition(4,2); ++ checkBox_onscreen->setId("onScrCtrl"); ++ checkBox_onscreen->setBaseColor(baseColLabel); ++ onscreenActionListener = new OnscreenActionListener(); ++ checkBox_onscreen->addActionListener(onscreenActionListener); ++ ++ backgrd_onscreen = new gcn::Container(); ++ backgrd_onscreen->setOpaque(true); ++ backgrd_onscreen->setBaseColor(baseColLabel); ++ backgrd_onscreen->setPosition(20, 350); ++ backgrd_onscreen->setSize(190, 27); ++ backgrd_onscreen->add(checkBox_onscreen); ++ backgrd_onscreen->setVisible(true); ++ ++ menuSaveState_Init(); ++ menuMessage_Init(); ++ loadMenu_Init(); ++ ++ //-------------------------------------------------- ++ // Place everything on main form ++ //-------------------------------------------------- ++ top->add(background, 0, 0); ++ top->add(button_reset, 210, 410); ++ top->add(button_resume, 320, 410); ++ top->add(button_quit, 430, 410); ++ top->add(button_savestate, 20, 410); ++ top->add(backgrd_onscreen); ++ top->add(window_savestate); ++ top->add(window_load, 120, 20); ++ top->add(window_warning, 170, 220); ++ ++ show_settings(); ++} ++ ++//-------------------------------------------------- ++// Initialize focus handling ++//-------------------------------------------------- ++// button_reset->setFocusable(true); ++// button_resume->setFocusable(true); ++// button_quit->setFocusable(true); ++ ++void halt() ++{ ++ menuSaveState_Exit(); ++ menuMessage_Exit(); ++ loadMenu_Exit(); ++ ++ delete button_reset; ++ delete button_resume; ++ delete button_quit; ++ delete button_savestate; ++ delete backgrd_onscreen; ++ delete checkBox_onscreen; ++ ++ delete resumeButtonActionListener; ++ delete resetButtonActionListener; ++ delete quitButtonActionListener; ++ delete stateButtonActionListener; ++ delete onscreenActionListener; ++ ++ delete background; ++ delete background_image; ++ ++ delete font; ++ delete top; ++ ++} ++ ++//----------------------------------------------- ++// Start of helper functions ++//----------------------------------------------- ++void show_settings() ++{ ++ if (menu_onscreen==true) ++ checkBox_onscreen->setSelected(true); ++ else ++ checkBox_onscreen->setSelected(false); ++} ++ ++} ++ ++extern "C" { ++ int gui_open(); ++ int VIDEOMODE_Update(); ++} ++ ++int gui_open() ++{ ++ getcwd(launchDir, 250); ++ strcpy(currentDir,"."); ++// strcmp(currentDir,launchDir); ++#ifdef ANDROID ++ SDL_ANDROID_SetScreenKeyboardShown(0); ++#endif ++ running = true; ++ ++ sdl::init(); ++ widgets::init(); ++ sdl::run(); ++ widgets::halt(); ++ sdl::halt(); ++#ifdef ANDROID ++ if (menu_onscreen) ++ SDL_ANDROID_SetScreenKeyboardShown(1); ++#endif ++ if (!VIDEOMODE_Update()) ++ return false; ++ return -1; ++} +diff -Nru atari800-3.1.0/src/guichan/menuLoad_guichan.cpp atari800-3.1.0-android/src/guichan/menuLoad_guichan.cpp +--- atari800-3.1.0/src/guichan/menuLoad_guichan.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/menuLoad_guichan.cpp 2015-01-28 18:31:32.000000000 +0200 +@@ -0,0 +1,571 @@ ++#include ++#ifdef ANDROID ++#include ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include "sdltruetypefont.hpp" ++#include "rw_config.h" ++#include ++#include ++ ++#if defined(WIN32) ++#define realpath(N,R) _fullpath((R),(N),_MAX_PATH) ++#endif ++ ++#ifndef PATH_MAX ++#define PATH_MAX 256 ++#endif ++ ++#define extterms files[q].size()>=4 && files[q].substr(files[q].size()-4) ++#define fileterms extterms!=".atr" && extterms!=".ATR" && extterms!=".Atr" && extterms!=".exe" && extterms!=".EXE" && extterms!=".Exe" && extterms!=".com" && extterms!=".COM" && extterms!=".Com" && extterms!=".cas" && extterms!=".CAS" && extterms!=".Cas" ++ ++extern bool running; ++bool confirmselection = false; ++int menuLoad_extfilter=1; ++ ++#define _XOPEN_SOURCE 500 ++#if defined(AROS) ++#include ++ ++#if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__) || defined(__amigaos__) ++// This is a random default value ... ++#define PATH_MAX 32768 ++#endif ++ ++static char *sep(char *path) ++{ ++ char *tmp, c; ++ ++ tmp = strrchr(path, '/'); ++ if(tmp) { ++ c = tmp[1]; ++ tmp[1] = 0; ++ if (chdir(path)) { ++ return NULL; ++ } ++ tmp[1] = c; ++ ++ return tmp + 1; ++ } ++ return path; ++} ++ ++char *realpath(const char *_path, char *resolved_path) ++{ ++ int fd = open(".", O_RDONLY), l; ++ char current_dir_path[PATH_MAX]; ++ char path[PATH_MAX], lnk[PATH_MAX], *tmp = (char *)""; ++ ++ if (fd < 0) { ++ return NULL; ++ } ++ getcwd(current_dir_path,PATH_MAX); ++ strncpy(path, _path, PATH_MAX); ++ ++ if (chdir(path)) { ++ if (errno == ENOTDIR) { ++#if defined(__WIN32__) || defined(__MORPHOS__) || defined(__amigaos__) ++ // No symbolic links and no readlink() ++ l = -1; ++#else ++ l = readlink(path, lnk, PATH_MAX); ++#endif ++ if (!(tmp = sep(path))) { ++ resolved_path = NULL; ++ goto abort; ++ } ++ if (l < 0) { ++ if (errno != EINVAL) { ++ resolved_path = NULL; ++ goto abort; ++ } ++ } else { ++ lnk[l] = 0; ++ if (!(tmp = sep(lnk))) { ++ resolved_path = NULL; ++ goto abort; ++ } ++ } ++ } else { ++ resolved_path = NULL; ++ goto abort; ++ } ++ } ++ ++ if(resolved_path==NULL) // if we called realpath with null as a 2nd arg ++ resolved_path = (char*) malloc( PATH_MAX ); ++ ++ if (!getcwd(resolved_path, PATH_MAX)) { ++ resolved_path = NULL; ++ goto abort; ++ } ++ ++ if(strcmp(resolved_path, "..") && *tmp) { ++ strcat(resolved_path, ".."); ++ } ++ ++ strcat(resolved_path, tmp); ++abort: ++ chdir(current_dir_path); ++ close(fd); ++ return resolved_path; ++} ++ ++#endif ++ ++/* What is being loaded, floppy/hd dir/hdf */ ++int menu_load_type; ++ ++namespace widgets ++{ ++void show_settings(void); ++static void unraise_loadMenu_guichan(); ++static void checkfilename (char *currentfilename); ++extern std::string selectedFilePath; ++ ++extern gcn::Color baseCol; ++gcn::Window *window_load; ++gcn::Button* button_ok; ++gcn::Button* button_select; ++gcn::Button* button_open; ++gcn::Button* button_cancel; ++#ifdef ANDROID ++gcn::CheckBox* checkBox_extfilter; ++#endif ++gcn::ListBox* listBox; ++gcn::ScrollArea* listBoxScrollArea; ++ ++gcn::Widget* activateAfterClose = NULL; ++ ++int lastSelectedIndex = 0; ++ ++ ++class DirListModel : public gcn::ListModel ++{ ++ std::vector dirs, files; ++ ++public: ++ DirListModel(const char * path) { ++ changeDir(path); ++ } ++ ++ int getNumberOfElements() { ++ if (menu_load_type != MENU_ADD_DIR) ++ return dirs.size() + files.size(); ++ else ++ return dirs.size(); ++ } ++ ++ std::string getElementAt(int i) { ++ if(i >= dirs.size() + files.size() || i < 0) ++ return "---"; ++ if(i < dirs.size()) ++ return dirs[i]; ++ if (menu_load_type != MENU_ADD_DIR) ++ return files[i - dirs.size()]; ++ } ++ ++ void changeDir(const char * path) { ++ dirs.clear(); ++ files.clear(); ++ DIR *dir; ++ struct dirent *dent; ++ dir = opendir(path); ++ if(dir != NULL) { ++ while((dent=readdir(dir))!=NULL) { ++ if(dent->d_type == DT_DIR) ++ dirs.push_back(dent->d_name); ++ else if (menu_load_type != MENU_ADD_DIR) ++ files.push_back(dent->d_name); ++ } ++ ++ if(dirs.size() > 0 && dirs[0] == ".") ++ dirs.erase(dirs.begin()); ++ ++ closedir(dir); ++ } ++ ++ if(dirs.size() == 0) ++ dirs.push_back(".."); ++ ++ std::sort(dirs.begin(), dirs.end()); ++ if (menu_load_type != MENU_ADD_DIR) ++ std::sort(files.begin(), files.end()); ++#ifdef ANDROID ++ if (menuLoad_extfilter==1) ++#endif ++ for (int q=0; qgetSelected(); ++ lastSelectedIndex = selected_item; ++ strcpy(filename, ""); ++ strcat(filename, currentDir); ++ strcat(filename, "/"); ++ strcat(filename, dirList.getElementAt(selected_item).c_str()); ++ confirmselection=true; ++ checkfilename(filename); ++ } ++}; ++OkButtonActionListener* okButtonActionListener; ++ ++ ++class SelectButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ int selected_item; ++ char filename[256]=""; ++ ++ selected_item = listBox->getSelected(); ++ lastSelectedIndex = selected_item; ++ strcpy(filename, ""); ++ strcat(filename, currentDir); ++ strcat(filename, "/"); ++ strcat(filename, dirList.getElementAt(selected_item).c_str()); ++ if (menu_load_type == MENU_ADD_DIR) { ++// strcpy(uae4all_hard_dir, filename); ++ } ++ unraise_loadMenu_guichan(); ++ } ++}; ++SelectButtonActionListener* selectButtonActionListener; ++ ++ ++class OpenButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ int selected_item; ++ char filename[256]=""; ++ ++ selected_item = listBox->getSelected(); ++ lastSelectedIndex = selected_item; ++ strcpy(filename, ""); ++ strcat(filename, currentDir); ++ strcat(filename, "/"); ++ strcat(filename, dirList.getElementAt(selected_item).c_str()); ++ checkfilename(filename); ++ } ++}; ++OpenButtonActionListener* openButtonActionListener; ++ ++ ++class CancelButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ unraise_loadMenu_guichan(); ++ } ++}; ++CancelButtonActionListener* cancelButtonActionListener; ++ ++ ++class ListBoxActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ confirmselection=false; ++#if defined(WIN32) || defined(ANDROID) || defined(AROS) || defined(RASPBERRY) ++ if (menu_load_type != MENU_ADD_DIR) { ++#endif ++ ++ int selected_item; ++ char filename[256]=""; ++ ++ selected_item = listBox->getSelected(); ++ lastSelectedIndex = selected_item; ++ strcpy(filename, ""); ++ strcat(filename, currentDir); ++ strcat(filename, "/"); ++ strcat(filename, dirList.getElementAt(selected_item).c_str()); ++ checkfilename(filename); ++#if defined(WIN32) || defined(ANDROID) || defined(AROS) || defined(RASPBERRY) ++ } ++#endif ++ } ++}; ++ListBoxActionListener* listBoxActionListener; ++ ++ ++class ListBoxKeyListener : public gcn::KeyListener ++{ ++public: ++ void keyPressed(gcn::KeyEvent& keyEvent) { ++ bool bHandled = false; ++ ++ Uint8 *keystate; ++ gcn::Key key = keyEvent.getKey(); ++ if (key.getValue() == gcn::Key::UP) { ++ keystate = SDL_GetKeyState(NULL); ++ if(keystate[SDLK_RSHIFT]) { ++ int selected = listBox->getSelected() - 10; ++ if(selected < 0) ++ selected = 0; ++ listBox->setSelected(selected); ++ bHandled = true; ++ } ++ } ++ if (key.getValue() == gcn::Key::DOWN) { ++ keystate = SDL_GetKeyState(NULL); ++ if(keystate[SDLK_RSHIFT]) { ++ int selected = listBox->getSelected() + 10; ++ if(selected >= dirList.getNumberOfElements()) ++ selected = dirList.getNumberOfElements() - 1; ++ listBox->setSelected(selected); ++ bHandled = true; ++ } ++ } ++ ++ if(!bHandled) ++ listBox->keyPressed(keyEvent); ++ } ++}; ++ListBoxKeyListener* listBoxKeyListener; ++ ++#ifdef ANDROID ++class ExtfilterActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ if (actionEvent.getSource() == checkBox_extfilter) { ++ if (checkBox_extfilter->isSelected()) ++ menuLoad_extfilter=1; ++ else ++ menuLoad_extfilter=0; ++ } ++ dirList=currentDir; ++ } ++}; ++ExtfilterActionListener* extfilterActionListener; ++#endif ++ ++void loadMenu_Init() ++{ ++ window_load = new gcn::Window("Load"); ++ window_load->setSize(400,370); ++ window_load->setBaseColor(baseCol); ++ ++ button_ok = new gcn::Button("Ok"); ++ button_ok->setPosition(231,318); ++ button_ok->setSize(70, 26); ++ button_ok->setBaseColor(baseCol); ++ okButtonActionListener = new OkButtonActionListener(); ++ button_ok->addActionListener(okButtonActionListener); ++ button_select = new gcn::Button("Select"); ++ button_select->setPosition(145,318); ++ button_select->setSize(70, 26); ++ button_select->setBaseColor(baseCol); ++ selectButtonActionListener = new SelectButtonActionListener(); ++ button_select->addActionListener(selectButtonActionListener); ++ button_open = new gcn::Button("Open"); ++ button_open->setPosition(231, 318); ++ button_open->setSize(70, 26); ++ button_open->setBaseColor(baseCol); ++ openButtonActionListener = new OpenButtonActionListener(); ++ button_open->addActionListener(openButtonActionListener); ++ button_cancel = new gcn::Button("Cancel"); ++ button_cancel->setPosition(316,318); ++ button_cancel->setSize(70, 26); ++ button_cancel->setBaseColor(baseCol); ++ cancelButtonActionListener = new CancelButtonActionListener(); ++ button_cancel->addActionListener(cancelButtonActionListener); ++ ++ listBox = new gcn::ListBox(&dirList); ++ listBox->setSize(650,220); ++ listBox->setBaseColor(baseCol); ++ listBox->setWrappingEnabled(true); ++ listBoxScrollArea = new gcn::ScrollArea(listBox); ++ listBoxScrollArea->setFrameSize(1); ++ listBoxScrollArea->setPosition(10,10); ++ listBoxScrollArea->setSize(376,298); ++ listBoxScrollArea->setScrollbarWidth(20); ++ listBoxScrollArea->setBaseColor(baseCol); ++ listBoxActionListener = new ListBoxActionListener(); ++ listBox->addActionListener(listBoxActionListener); ++ listBoxKeyListener = new ListBoxKeyListener(); ++ listBox->removeKeyListener(listBox); ++ listBox->addKeyListener(listBoxKeyListener); ++#ifdef ANDROID ++ checkBox_extfilter = new gcn::CheckBox("ext. filter"); ++ checkBox_extfilter->setPosition(10,320); ++ checkBox_extfilter->setId("extFilter"); ++ extfilterActionListener = new ExtfilterActionListener(); ++ checkBox_extfilter->addActionListener(extfilterActionListener); ++#endif ++ window_load->add(button_ok); ++ window_load->add(button_select); ++ window_load->add(button_open); ++ window_load->add(button_cancel); ++ window_load->add(listBoxScrollArea); ++#ifdef ANDROID ++ window_load->add(checkBox_extfilter); ++#endif ++ window_load->setVisible(false); ++} ++ ++ ++void loadMenu_Exit() ++{ ++ delete listBox; ++ delete listBoxScrollArea; ++ ++ delete button_ok; ++ delete button_select; ++ delete button_open; ++ delete button_cancel; ++#ifdef ANDROID ++ delete checkBox_extfilter; ++#endif ++ ++ delete okButtonActionListener; ++ delete selectButtonActionListener; ++ delete openButtonActionListener; ++ delete cancelButtonActionListener; ++ delete listBoxActionListener; ++ delete listBoxKeyListener; ++#ifdef ANDROID ++ delete extfilterActionListener; ++#endif ++ ++ delete window_load; ++} ++ ++ ++static void unraise_loadMenu_guichan() ++{ ++ window_load->releaseModalFocus(); ++ window_load->setVisible(false); ++ if(activateAfterClose != NULL) ++ activateAfterClose->requestFocus(); ++ activateAfterClose = NULL; ++ show_settings(); ++} ++ ++ ++static void raise_loadMenu_guichan() ++{ ++ if (menu_load_type != MENU_ADD_DIR) { ++ button_ok->setVisible(true); ++ button_select->setVisible(false); ++ button_open->setVisible(false); ++ button_ok->setId("cmdOk"); ++ button_select->setId("cmdSelect"); ++ button_open->setId("cmdOpen"); ++ button_cancel->setId("cmdCancel1"); ++ listBox->setId("dirList1"); ++ } else { ++ button_ok->setVisible(false); ++ button_select->setVisible(true); ++ button_open->setVisible(true); ++ button_ok->setId("cmdOk"); ++ button_select->setId("cmdSelect"); ++ button_open->setId("cmdOpen"); ++ button_cancel->setId("cmdCancel2"); ++ listBox->setId("dirList2"); ++ } ++#ifdef ANDROID ++ if (menuLoad_extfilter==0) ++ checkBox_extfilter->setSelected(false); ++ else if (menuLoad_extfilter==1) ++ checkBox_extfilter->setSelected(true); ++#endif ++ window_load->setVisible(true); ++ window_load->requestModalFocus(); ++ listBox->requestFocus(); ++} ++ ++ ++static int menuLoadLoop(char *curr_path) ++{ ++ char *ret = NULL; ++ char *fname = NULL; ++ DIR *dir; ++ ++ // is this a dir or a full path? ++ if ((dir = opendir(curr_path))) ++ closedir(dir); ++ else { ++ char *p; ++ for (p = curr_path + strlen(curr_path) - 1; p > curr_path && *p != '/'; p--); ++ *p = 0; ++ fname = p+1; ++ } ++ dirList = curr_path; ++ ++ if (menu_load_type == MENU_ADD_DIR) ++ window_load->setCaption(" Select HD-dir "); ++ else if (menu_load_type == MENU_SELECT_FILE) ++ window_load->setCaption(" Select File to Run "); ++ else ++ window_load->setCaption("File Manager"); ++ ++ if(lastSelectedIndex >= 0 && lastSelectedIndex < dirList.getNumberOfElements()) ++ listBox->setSelected(lastSelectedIndex); ++} ++ ++void run_menuLoad_guichan(char *curr_path, int aLoadType) ++{ ++ menu_load_type = aLoadType; ++ raise_loadMenu_guichan(); ++ int ret = menuLoadLoop(curr_path); ++} ++ ++extern "C" { ++ int AFILE_OpenFile(const char *filename, int reboot, int diskno, int readonly); ++} ++ ++void checkfilename (char *currentfilename) ++{ ++ char *ret = NULL, *fname = NULL; ++ char *ptr; ++ char actualpath [PATH_MAX]; ++ struct dirent **namelist; ++ DIR *dir; ++ ++ if ((dir = opendir(currentfilename))) { ++ dirList=currentfilename; ++ ptr = realpath(currentfilename, actualpath); ++ strcpy(currentDir, ptr); ++ closedir(dir); ++ } else { ++ if ((menu_load_type == MENU_SELECT_FILE) && confirmselection) { ++ selectedFilePath=currentfilename; ++ int err = AFILE_OpenFile(selectedFilePath.c_str(), 1, 1, 1); ++#ifdef ANDROID ++ SDL_ANDROID_SetScreenKeyboardShown(1); ++#endif ++ running = false; ++ } ++ ++ if (confirmselection) ++ unraise_loadMenu_guichan(); ++ } ++} ++} +diff -Nru atari800-3.1.0/src/guichan/menuMessage.cpp atari800-3.1.0-android/src/guichan/menuMessage.cpp +--- atari800-3.1.0/src/guichan/menuMessage.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/menuMessage.cpp 2015-01-28 18:31:40.000000000 +0200 +@@ -0,0 +1,138 @@ ++#include ++#ifdef ANDROIDSDL ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include "sdltruetypefont.hpp" ++ ++namespace widgets ++{ ++static void unraise_Message(); ++ ++extern gcn::Color baseCol; ++extern gcn::Button* button_reset; ++ ++gcn::Window *window_warning; ++gcn::Button* button_warning; ++gcn::Label* label_text; ++gcn::Label* label2_text; ++ ++gcn::Widget* activateAfterMsg = NULL; ++ ++ ++class WarningButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ unraise_Message(); ++ } ++}; ++WarningButtonActionListener* warningButtonActionListener; ++ ++ ++void menuMessage_Init() ++{ ++ button_warning = new gcn::Button(" Ok "); ++ button_warning->setPosition(115,45); ++ button_warning->setSize(70, 26); ++ button_warning->setBaseColor(baseCol); ++ warningButtonActionListener = new WarningButtonActionListener(); ++ button_warning->addActionListener(warningButtonActionListener); ++ ++ label_text = new gcn::Label(""); ++ label_text->setPosition(4, 4); ++ label_text->setSize(290, 15); ++ ++ label2_text = new gcn::Label(""); ++ label2_text->setPosition(4, 23); ++ label2_text->setSize(430, 15); ++ ++ window_warning = new gcn::Window("Warning"); ++ window_warning->add(button_warning); ++ window_warning->add(label_text); ++ window_warning->add(label2_text); ++ window_warning->setMovable(false); ++ window_warning->setSize(300,95); ++ window_warning->setBaseColor(baseCol); ++ window_warning->setVisible(false); ++} ++ ++ ++void menuMessage_Exit() ++{ ++ delete button_warning; ++ delete label_text; ++ delete label2_text; ++ ++ delete warningButtonActionListener; ++ ++ delete window_warning; ++} ++ ++ ++static void unraise_Message() ++{ ++ window_warning->releaseModalFocus(); ++ window_warning->setVisible(false); ++ if(activateAfterMsg != NULL) ++ activateAfterMsg->requestFocus(); ++ else ++ button_reset->requestFocus(); ++ activateAfterMsg = NULL; ++} ++ ++ ++void adjustSize(const char *msg2) ++{ ++ if(msg2 == "") { ++ window_warning->setPosition(210, 220); ++ window_warning->setSize(240,95); ++ button_warning->setPosition(85,45); ++ } else { ++ window_warning->setPosition(100, 220); ++ window_warning->setSize(440,95); ++ button_warning->setPosition(185,45); ++ } ++} ++ ++ ++void showInfo(const char *msg, const char *msg2 = "") ++{ ++ label_text->setCaption(msg); ++ label2_text->setCaption(msg2); ++ adjustSize(msg2); ++ window_warning->setCaption("Information"); ++ window_warning->setVisible(true); ++ window_warning->requestModalFocus(); ++ button_warning->requestFocus(); ++} ++ ++ ++void showWarning(const char *msg, const char *msg2 = "") ++{ ++ label_text->setCaption(msg); ++ label2_text->setCaption(msg2); ++ adjustSize(msg2); ++ window_warning->setCaption("Warning"); ++ window_warning->setVisible(true); ++ window_warning->requestModalFocus(); ++ button_warning->requestFocus(); ++} ++ ++ ++void show_error(const char *msg, const char *msg2 = "") ++{ ++ label_text->setCaption(msg); ++ label2_text->setCaption(msg2); ++ adjustSize(msg2); ++ window_warning->setCaption("Error"); ++ window_warning->setVisible(true); ++ window_warning->requestModalFocus(); ++ button_warning->requestFocus(); ++} ++ ++} +diff -Nru atari800-3.1.0/src/guichan/menuSaveState.cpp atari800-3.1.0-android/src/guichan/menuSaveState.cpp +--- atari800-3.1.0/src/guichan/menuSaveState.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/menuSaveState.cpp 2015-01-28 18:31:24.000000000 +0200 +@@ -0,0 +1,283 @@ ++#include ++#include ++#include ++#ifdef ANDROID ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include "sdltruetypefont.hpp" ++ ++extern "C" ++{ ++#include "statesav.h" ++} ++ ++extern bool running; ++ ++#define extterms files[q].size()>=4 && files[q].substr(files[q].size()-4) ++#define ssterms extterms!=".sav" && extterms!=".SAV" && extterms!=".Sav" ++#define ext2terms ssstring.size()>=4 && ssstring.substr(ssstring.size()-4) ++#define ss2terms ext2terms!=".sav" && ext2terms!=".SAV" && ext2terms!=".Sav" ++ ++static char savestate_filename_default[255]= { ++ '/', 't', 'm', 'p', '/', 'n', 'u', 'l', 'l', '.', 's', 'a', 'v', '\0' ++}; ++ ++char *savestate_filename=(char *)&savestate_filename_default[0]; ++ ++extern char launchDir[300]; ++ ++static void BuildBaseDir(char *filename) ++{ ++ strcpy(filename, ""); ++ strcat(filename, launchDir); ++ strcat(filename, "/savestates"); ++// strcpy(filename, prefs_get_attr ("savestate_path")); ++} ++ ++namespace widgets ++{ ++void show_settings_SaveState(void); ++void showWarning(const char *msg, const char *msg2 = ""); ++void showInfo(const char *msg, const char *msg2 = ""); ++ ++extern gcn::Color baseCol; ++extern gcn::Color baseColLabel; ++extern gcn::Container* top; ++extern gcn::contrib::SDLTrueTypeFont* font2; ++ ++// Tab Main ++gcn::Window *window_savestate; ++ ++gcn::Button* button_ss_load; ++gcn::Button* button_ss_save; ++gcn::Button* button_ss_delete; ++gcn::Button* button_ss_cancel; ++gcn::TextField* textField_ss; ++gcn::ListBox* savestatelistBox; ++gcn::ScrollArea* savestateScrollArea; ++ ++class SavestateListModel : public gcn::ListModel ++{ ++ std::vector files; ++ ++public: ++ SavestateListModel(const char * path) { ++ changeDir(path); ++ } ++ ++ int getNumberOfElements() { ++ return files.size(); ++ } ++ ++ std::string getElementAt(int i) { ++ if(i >= files.size() || i < 0) ++ return "---"; ++ return files[i]; ++ } ++ ++ void changeDir(const char * path) { ++ files.clear(); ++ DIR *dir; ++ struct dirent *dent; ++ dir = opendir(path); ++ if(dir != NULL) { ++ while((dent=readdir(dir))!=NULL) { ++ if(!(dent->d_type == DT_DIR)) ++ files.push_back(dent->d_name); ++ } ++ closedir(dir); ++ } ++ std::sort(files.begin(), files.end()); ++ for (int q=0; qgetSelected(); ++ BuildBaseDir(savestate_filename); ++ strcat(savestate_filename, "/"); ++ strcat(savestate_filename, savestateList.getElementAt(selected_item).c_str()); ++ int result; ++ result = StateSav_ReadAtariState(savestate_filename, "rb"); ++ if (result) { ++ window_savestate->setVisible(false); ++ running=false; ++ } else ++ showInfo("Savestate failed."); ++ } ++}; ++SsLoadButtonActionListener* ssloadButtonActionListener; ++ ++ ++class SsSaveButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ char filename[256]=""; ++ std::string ssstring; ++ BuildBaseDir(savestate_filename); ++ strcat(savestate_filename, "/"); ++ ssstring = textField_ss->getText().c_str(); ++ strcat(savestate_filename, textField_ss->getText().c_str()); ++ // check extension of editable name ++ if (ss2terms || ssstring.size()<5) ++ strcat(savestate_filename, ".sav"); ++ window_savestate->setVisible(false); ++ int result; ++ result = StateSav_SaveAtariState(savestate_filename, "wb", TRUE); ++ if (result) ++ showInfo("Savestate file saved."); ++ else ++ showInfo("Savestate failed."); ++// running=false; ++// save_state(savestate_filename, 0); ++// showInfo("Savestate file saved."); ++ BuildBaseDir(savestate_filename); ++ savestateList = savestate_filename; ++ ++ } ++}; ++SsSaveButtonActionListener* sssaveButtonActionListener; ++ ++class SsDeleteButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ int selected_item; ++ selected_item = savestatelistBox->getSelected(); ++ BuildBaseDir(savestate_filename); ++ strcat(savestate_filename, "/"); ++ strcat(savestate_filename, savestateList.getElementAt(selected_item).c_str()); ++ if(unlink(savestate_filename)) { ++ showWarning("Failed to delete savestate."); ++ } else { ++ BuildBaseDir(savestate_filename); ++ savestateList = savestate_filename; ++ } ++ } ++}; ++SsDeleteButtonActionListener* ssdeleteButtonActionListener; ++ ++class SsCancelButtonActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ window_savestate->setVisible(false); ++ } ++}; ++SsCancelButtonActionListener* sscancelButtonActionListener; ++ ++class SavestatelistBoxActionListener : public gcn::ActionListener ++{ ++public: ++ void action(const gcn::ActionEvent& actionEvent) { ++ int selected_item; ++ selected_item = savestatelistBox->getSelected(); ++ textField_ss->setText(savestateList.getElementAt(selected_item).c_str()); ++ } ++}; ++SavestatelistBoxActionListener* savestatelistBoxActionListener; ++ ++void menuSaveState_Init() ++{ ++ button_ss_load = new gcn::Button("Load"); ++ button_ss_load->setId("ssLoad"); ++ button_ss_load->setPosition(316,10); ++ button_ss_load->setSize(70, 26); ++ button_ss_load->setBaseColor(baseCol); ++ ssloadButtonActionListener = new SsLoadButtonActionListener(); ++ button_ss_load->addActionListener(ssloadButtonActionListener); ++ button_ss_save = new gcn::Button("Save"); ++ button_ss_save->setId("ssSave"); ++ button_ss_save->setPosition(316,65); ++ button_ss_save->setSize(70, 26); ++ button_ss_save->setBaseColor(baseCol); ++ sssaveButtonActionListener = new SsSaveButtonActionListener(); ++ button_ss_save->addActionListener(sssaveButtonActionListener); ++ button_ss_delete = new gcn::Button("Delete"); ++ button_ss_delete->setId("ssDelete"); ++ button_ss_delete->setPosition(316,120); ++ button_ss_delete->setSize(70, 26); ++ button_ss_delete->setBaseColor(baseCol); ++ ssdeleteButtonActionListener = new SsDeleteButtonActionListener(); ++ button_ss_delete->addActionListener(ssdeleteButtonActionListener); ++ button_ss_cancel = new gcn::Button("Cancel"); ++ button_ss_cancel->setId("ssCancel"); ++ button_ss_cancel->setPosition(316,175); ++ button_ss_cancel->setSize(70, 26); ++ button_ss_cancel->setBaseColor(baseCol); ++ sscancelButtonActionListener = new SsCancelButtonActionListener(); ++ button_ss_cancel->addActionListener(sscancelButtonActionListener); ++ ++ ++ textField_ss = new gcn::TextField(""); ++ textField_ss->setId("ssText"); ++ textField_ss->setPosition(10,10); ++ textField_ss->setSize(295,22); ++ textField_ss->setBaseColor(baseCol); ++ ++ savestatelistBox = new gcn::ListBox(&savestateList); ++ savestatelistBox->setId("savestateList"); ++ savestatelistBox->setSize(650,150); ++ savestatelistBox->setBaseColor(baseCol); ++ savestatelistBox->setWrappingEnabled(true); ++ savestatelistBoxActionListener = new SavestatelistBoxActionListener(); ++ savestatelistBox->addActionListener(savestatelistBoxActionListener); ++ savestateScrollArea = new gcn::ScrollArea(savestatelistBox); ++ savestateScrollArea->setFrameSize(1); ++ savestateScrollArea->setPosition(10,40); ++ savestateScrollArea->setSize(295,228); ++ savestateScrollArea->setScrollbarWidth(20); ++ savestateScrollArea->setBaseColor(baseCol); ++ ++ window_savestate = new gcn::Window("SaveState"); ++ window_savestate->setPosition(120,90); ++ window_savestate->setMovable(false); ++ window_savestate->setSize(400,300); ++ window_savestate->setBaseColor(baseCol); ++ window_savestate->setVisible(false); ++ ++ window_savestate->add(button_ss_load); ++ window_savestate->add(button_ss_save); ++ window_savestate->add(button_ss_delete); ++ window_savestate->add(button_ss_cancel); ++ window_savestate->add(textField_ss); ++ window_savestate->add(savestateScrollArea); ++} ++ ++void menuSaveState_Exit() ++{ ++ ++ delete button_ss_load; ++ delete button_ss_save; ++ delete button_ss_delete; ++ delete button_ss_cancel; ++ delete textField_ss; ++ delete savestatelistBox; ++ delete savestateScrollArea; ++ ++ delete window_savestate; ++} ++ ++void show_settings_SaveState() ++{ ++ ++} ++ ++} +diff -Nru atari800-3.1.0/src/guichan/rw_config.h atari800-3.1.0-android/src/guichan/rw_config.h +--- atari800-3.1.0/src/guichan/rw_config.h 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/rw_config.h 2014-12-10 20:56:10.000000000 +0200 +@@ -0,0 +1,6 @@ ++ ++/* What is being loaded */ ++#define MENU_SELECT_FILE 1 ++#define MENU_ADD_DIR 2 ++ ++extern char currentDir[300]; +\ Наприкінці файлу немає нового рядка +diff -Nru atari800-3.1.0/src/guichan/sdltruetypefont.cpp atari800-3.1.0-android/src/guichan/sdltruetypefont.cpp +--- atari800-3.1.0/src/guichan/sdltruetypefont.cpp 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/sdltruetypefont.cpp 2014-05-22 23:40:29.000000000 +0300 +@@ -0,0 +1,171 @@ ++/* _______ __ __ __ ______ __ __ _______ __ __ ++ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ ++ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / ++ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / ++ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / ++ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / ++ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ ++ * ++ * Copyright (c) 2004 - 2008 Olof Naessn and Per Larsson ++ * ++ * ++ * Per Larsson a.k.a finalman ++ * Olof Naessn a.k.a jansem/yakslem ++ * ++ * Visit: http://guichan.sourceforge.net ++ * ++ * License: (BSD) ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * 3. Neither the name of Guichan nor the names of its contributors may ++ * be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * For comments regarding functions please see the header file. ++ */ ++ ++#include "sdltruetypefont.hpp" ++ ++#include "guichan/exception.hpp" ++#include "guichan/image.hpp" ++#include "guichan/graphics.hpp" ++#include "guichan/sdl/sdlgraphics.hpp" ++ ++namespace gcn ++{ ++ namespace contrib ++ { ++ SDLTrueTypeFont::SDLTrueTypeFont (const std::string& filename, int size) ++ { ++ mRowSpacing = 0; ++ mGlyphSpacing = 0; ++ mAntiAlias = true; ++ mFilename = filename; ++ mFont = NULL; ++ ++ mFont = TTF_OpenFont(filename.c_str(), size); ++ ++ if (mFont == NULL) ++ { ++ throw GCN_EXCEPTION("SDLTrueTypeFont::SDLTrueTypeFont. "+std::string(TTF_GetError())); ++ } ++ } ++ ++ SDLTrueTypeFont::~SDLTrueTypeFont() ++ { ++ TTF_CloseFont(mFont); ++ } ++ ++ int SDLTrueTypeFont::getWidth(const std::string& text) const ++ { ++ int w, h; ++ TTF_SizeText(mFont, text.c_str(), &w, &h); ++ ++ return w; ++ } ++ ++ int SDLTrueTypeFont::getHeight() const ++ { ++ return TTF_FontHeight(mFont) + mRowSpacing; ++ } ++ ++ void SDLTrueTypeFont::drawString(gcn::Graphics* graphics, const std::string& text, const int x, const int y) ++ { ++ if (text == "") ++ { ++ return; ++ } ++ ++ gcn::SDLGraphics *sdlGraphics = dynamic_cast(graphics); ++ ++ if (sdlGraphics == NULL) ++ { ++ throw GCN_EXCEPTION("SDLTrueTypeFont::drawString. Graphics object not an SDL graphics object!"); ++ return; ++ } ++ ++ // This is needed for drawing the Glyph in the middle if we have spacing ++ int yoffset = getRowSpacing() / 2; ++ ++ Color col = sdlGraphics->getColor(); ++ ++ SDL_Color sdlCol; ++ sdlCol.b = col.b; ++ sdlCol.r = col.r; ++ sdlCol.g = col.g; ++ ++ SDL_Surface *textSurface; ++ if (mAntiAlias) ++ { ++ textSurface = TTF_RenderText_Blended(mFont, text.c_str(), sdlCol); ++ } ++ else ++ { ++ textSurface = TTF_RenderText_Solid(mFont, text.c_str(), sdlCol); ++ } ++ ++ SDL_Rect dst, src; ++ dst.x = x; ++ dst.y = y + yoffset; ++ src.w = textSurface->w; ++ src.h = textSurface->h; ++ src.x = 0; ++ src.y = 0; ++ ++ sdlGraphics->drawSDLSurface(textSurface, src, dst); ++ SDL_FreeSurface(textSurface); ++ } ++ ++ void SDLTrueTypeFont::setRowSpacing(int spacing) ++ { ++ mRowSpacing = spacing; ++ } ++ ++ int SDLTrueTypeFont::getRowSpacing() ++ { ++ return mRowSpacing; ++ } ++ ++ void SDLTrueTypeFont::setGlyphSpacing(int spacing) ++ { ++ mGlyphSpacing = spacing; ++ } ++ ++ int SDLTrueTypeFont::getGlyphSpacing() ++ { ++ return mGlyphSpacing; ++ } ++ ++ void SDLTrueTypeFont::setAntiAlias(bool antiAlias) ++ { ++ mAntiAlias = antiAlias; ++ } ++ ++ bool SDLTrueTypeFont::isAntiAlias() ++ { ++ return mAntiAlias; ++ } ++ } ++} ++ +diff -Nru atari800-3.1.0/src/guichan/sdltruetypefont.hpp atari800-3.1.0-android/src/guichan/sdltruetypefont.hpp +--- atari800-3.1.0/src/guichan/sdltruetypefont.hpp 1970-01-01 03:00:00.000000000 +0300 ++++ atari800-3.1.0-android/src/guichan/sdltruetypefont.hpp 2013-12-03 21:22:16.000000000 +0200 +@@ -0,0 +1,156 @@ ++/* _______ __ __ __ ______ __ __ _______ __ __ ++ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ ++ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / ++ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / ++ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / ++ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / ++ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ ++ * ++ * Copyright (c) 2004 - 2008 Olof Naessn and Per Larsson ++ * ++ * ++ * Per Larsson a.k.a finalman ++ * Olof Naessn a.k.a jansem/yakslem ++ * ++ * Visit: http://guichan.sourceforge.net ++ * ++ * License: (BSD) ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * 3. Neither the name of Guichan nor the names of its contributors may ++ * be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef GCN_CONTRIB_SDLTRUETYPEFONT_HPP ++#define GCN_CONTRIB_SDLTRUETYPEFONT_HPP ++ ++#include ++#include ++ ++#include ++ ++#include "guichan/font.hpp" ++#include "guichan/platform.hpp" ++ ++namespace gcn ++{ ++ class Graphics; ++ namespace contrib ++ { ++ ++ /** ++ * SDL True Type Font implementation of Font. It uses the SDL_ttf library ++ * to display True Type Fonts with SDL. ++ * ++ * NOTE: You must initialize the SDL_ttf library before using this ++ * class. Also, remember to call the SDL_ttf libraries quit ++ * function. ++ * ++ * @author Walluce Pinkham ++ * @author Olof Naessn ++ */ ++ class GCN_EXTENSION_DECLSPEC SDLTrueTypeFont: public Font ++ { ++ public: ++ ++ /** ++ * Constructor. ++ * ++ * @param filename the filename of the True Type Font. ++ * @param size the size the font should be in. ++ */ ++ SDLTrueTypeFont (const std::string& filename, int size); ++ ++ /** ++ * Destructor. ++ */ ++ virtual ~SDLTrueTypeFont(); ++ ++ /** ++ * Sets the spacing between rows in pixels. Default is 0 pixels. ++ * The spacing can be negative. ++ * ++ * @param spacing the spacing in pixels. ++ */ ++ virtual void setRowSpacing (int spacing); ++ ++ /** ++ * Gets the spacing between rows in pixels. ++ * ++ * @return the spacing. ++ */ ++ virtual int getRowSpacing(); ++ ++ /** ++ * Sets the spacing between letters in pixels. Default is 0 pixels. ++ * The spacing can be negative. ++ * ++ * @param spacing the spacing in pixels. ++ */ ++ virtual void setGlyphSpacing(int spacing); ++ ++ /** ++ * Gets the spacing between letters in pixels. ++ * ++ * @return the spacing. ++ */ ++ virtual int getGlyphSpacing(); ++ ++ /** ++ * Sets the use of anti aliasing.. ++ * ++ * @param antaAlias true for use of antia aliasing. ++ */ ++ virtual void setAntiAlias(bool antiAlias); ++ ++ /** ++ * Checks if anti aliasing is used. ++ * ++ * @return true if anti aliasing is used. ++ */ ++ virtual bool isAntiAlias(); ++ ++ ++ // Inherited from Font ++ ++ virtual int getWidth(const std::string& text) const; ++ ++ virtual int getHeight() const; ++ ++ virtual void drawString(Graphics* graphics, const std::string& text, int x, int y); ++ ++ protected: ++ TTF_Font *mFont; ++ ++ int mHeight; ++ int mGlyphSpacing; ++ int mRowSpacing; ++ ++ std::string mFilename; ++ bool mAntiAlias; ++ }; ++ } ++} ++ ++#endif ++ +diff -Nru atari800-3.1.0/src/Makefile.in atari800-3.1.0-android/src/Makefile.in +--- atari800-3.1.0/src/Makefile.in 2013-05-02 14:59:13.000000000 +0300 ++++ atari800-3.1.0-android/src/Makefile.in 2016-08-27 21:53:32.307310727 +0300 +@@ -1,8 +1,9 @@ + CC = @CC@ ++CXX = /home/lubomyr/android/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ + RC = windres + + DEFS = @DEFS@ +-LIBS = @LIBS@ ++LIBS = @LIBS@ -lgnustl_static + TARGET_BASE_NAME = atari800 + TARGET = $(TARGET_BASE_NAME)@EXEEXT@ + CONFIGURE_TARGET = @CONFIGURE_TARGET@ +@@ -60,6 +61,7 @@ + sio.o \ + sysrom.o \ + util.o \ ++ guichan/guichan-gui.o guichan/menuLoad_guichan.o guichan/menuMessage.o guichan/menuSaveState.o guichan/sdltruetypefont.o \ + @OBJS@ + + +@@ -75,6 +77,9 @@ + win32/%.o: win32/%.c + $(CC) -c -o $@ $(DEFS) -I. $(patsubst -pedantic,,$(patsubst -ansi,,$(CFLAGS))) $< + ++guichan/%.o: guichan/%.cpp ++ $(CXX) -c -o $@ $(DEFS) -I. $(CFLAGS) $< ++ + ide.o: ide.c ide.h ide_internal.h + $(CC) -c -o $@ $(DEFS) -I. $(CFLAGS:-ansi=) $< + +@@ -116,7 +121,7 @@ + .PHONY: android + + $(TARGET): $(OBJS) +- $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) ++ $(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) + + dep: + @if ! makedepend -Y $(DEFS) -I. ${OBJS:.o=.c} 2>/dev/null; \ +@@ -128,6 +133,7 @@ + rm -f falcon/*.o falcon/*.bak falcon/*~ + rm -f sdl/*.o sdl/*.bak sdl/*~ + rm -f win32/*.o win32/*.ro win32/*.bak win32/*~ ++ rm -f guichan/*.o guichan/*.ro guichan/*.bak guichan/*~ + rm -f javanvm/*.o javanvm/*.bak javanvm/*~ + rm -f atari_ntsc/*.o atari_ntsc/*.bak atari_ntsc/*~ + rm -rf android/libs android/obj android/bin android/gen +diff -Nru atari800-3.1.0/src/sdl/input.c atari800-3.1.0-android/src/sdl/input.c +--- atari800-3.1.0/src/sdl/input.c 2014-03-11 01:14:34.000000000 +0200 ++++ atari800-3.1.0-android/src/sdl/input.c 2016-08-27 20:52:01.127418544 +0300 +@@ -22,9 +22,11 @@ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + ++#ifndef ANDROID + #ifdef __linux__ + #define LPTJOY 1 + #endif ++#endif + + #ifdef LPTJOY + #include +@@ -1391,6 +1393,9 @@ + int stick0, stick1; + stick0 = stick1 = INPUT_STICK_CENTRE; + ++ if( !kbhits ) ++ return; ++ + if (PLATFORM_kbd_joy_0_enabled) { + if (kbhits[KBD_STICK_0_LEFT]) + stick0 &= INPUT_STICK_LEFT; +@@ -1437,6 +1442,9 @@ + int trig0, trig1; + trig0 = trig1 = 1; + ++ if( !kbhits ) ++ return; ++ + if (PLATFORM_kbd_joy_0_enabled) { + trig0 = !kbhits[KBD_TRIG_0]; + } +diff -Nru atari800-3.1.0/src/ui_basic.c atari800-3.1.0-android/src/ui_basic.c +--- atari800-3.1.0/src/ui_basic.c 2014-03-11 01:14:34.000000000 +0200 ++++ atari800-3.1.0-android/src/ui_basic.c 2016-08-27 20:52:01.127418544 +0300 +@@ -91,7 +91,7 @@ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + +-#define KB_DELAY 20 ++#define KB_DELAY 35 + #define KB_AUTOREPEAT 3 + + static int GetKeyPress(void) +diff -Nru atari800-3.1.0/src/videomode.c atari800-3.1.0-android/src/videomode.c +--- atari800-3.1.0/src/videomode.c 2013-04-23 19:57:39.000000000 +0300 ++++ atari800-3.1.0-android/src/videomode.c 2016-08-27 20:52:01.127418544 +0300 +@@ -47,6 +47,10 @@ + #include "xep80.h" + #endif + ++#if defined(ANDROID) ++#include ++#endif ++ + #if defined(XEP80_EMULATION) || defined(PBI_PROTO80) || defined(AF80) + #define COLUMN_80 1 + #else +@@ -590,8 +594,76 @@ + return TRUE; + } + ++#ifdef ANDROID ++void onscreen_position() ++{ ++ // setup position of on-screen buttons ++ int pos_x_textinput=0; ++ int pos_y_textinput=0; ++ int pos_x_dpad=4; ++ int pos_y_dpad=215; ++ int pos_x_button1=417; ++ int pos_y_button1=278; ++ int pos_x_button2=49; ++ int pos_y_button2=6; ++ int pos_x_button3=240; ++ int pos_y_button3=11; ++ int pos_x_button4=300; ++ int pos_y_button4=11; ++ int pos_x_button5=361; ++ int pos_y_button5=10; ++ int pos_x_button6=421; ++ int pos_y_button6=9; ++ // apply position of on-screen buttons ++ SDL_Rect pos_textinput, pos_dpad, pos_button1, pos_button2, pos_button3, pos_button4, pos_button5, pos_button6; ++ pos_textinput.x = pos_x_textinput*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_textinput.y = pos_y_textinput*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_textinput.h=SDL_ListModes(NULL, 0)[0]->h / (float)10; ++ pos_textinput.w=pos_textinput.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &pos_textinput); ++ pos_dpad.x = pos_x_dpad*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_dpad.y = pos_y_dpad*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_dpad.h=SDL_ListModes(NULL, 0)[0]->h / (float)2.5; ++ pos_dpad.w=pos_dpad.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &pos_dpad); ++ pos_button1.x = pos_x_button1*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_button1.y = pos_y_button1*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_button1.h=SDL_ListModes(NULL, 0)[0]->h / (float)4; ++ pos_button1.w=pos_button1.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos_button1); ++ pos_button2.x = pos_x_button2*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_button2.y = pos_y_button2*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_button2.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; ++ pos_button2.w=pos_button2.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &pos_button2); ++ pos_button3.x = pos_x_button3*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_button3.y = pos_y_button3*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_button3.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; ++ pos_button3.w=pos_button3.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &pos_button3); ++ pos_button4.x = pos_x_button4*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_button4.y = pos_y_button4*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_button4.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; ++ pos_button4.w=pos_button4.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &pos_button4); ++ pos_button5.x = pos_x_button5*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_button5.y = pos_y_button5*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_button5.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; ++ pos_button5.w=pos_button5.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &pos_button5); ++ pos_button6.x = pos_x_button6*(SDL_ListModes(NULL, 0)[0]->w/(float)480); ++ pos_button6.y = pos_y_button6*(SDL_ListModes(NULL, 0)[0]->h/(float)360); ++ pos_button6.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; ++ pos_button6.w=pos_button6.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &pos_button6); ++} ++#endif ++ + int VIDEOMODE_Update(void) + { ++#ifdef ANDROID ++ onscreen_position(); ++#endif + if (VIDEOMODE_windowed || force_windowed) + return UpdateVideoWindowed(FALSE); + else