From 762b1854a82b019178dcf9c69fba20ccaf176078 Mon Sep 17 00:00:00 2001 From: Sergii Pylypenko Date: Tue, 28 Jul 2015 23:38:06 +0300 Subject: [PATCH] SDL: built-in text input keyboard with predefined layout, unfinished yet --- changeAppSettings.sh | 12 + project/java/Clipboard.java | 1 - project/java/Globals.java | 1 + project/java/MainActivity.java | 151 +++++++--- .../ballfield/AndroidAppSettings.cfg | 40 ++- .../test-opengl/AndroidAppSettings.cfg | 62 ++++- .../jni/application/test-opengl/sdl_hello.cpp | 261 +++++++++--------- project/res/xml/amiga.xml | 63 +++++ project/res/xml/c64.xml | 63 +++++ project/res/xml/qwerty.xml | 63 +++++ 10 files changed, 528 insertions(+), 189 deletions(-) create mode 100644 project/res/xml/amiga.xml create mode 100644 project/res/xml/c64.xml create mode 100644 project/res/xml/qwerty.xml diff --git a/changeAppSettings.sh b/changeAppSettings.sh index 124659d6b..cfbfb0e8d 100755 --- a/changeAppSettings.sh +++ b/changeAppSettings.sh @@ -190,6 +190,13 @@ echo >> AndroidAppSettings.cfg echo "# On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n)" >> AndroidAppSettings.cfg echo CompatibilityHacksTextInputEmulatesHwKeyboard=$CompatibilityHacksTextInputEmulatesHwKeyboard >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg +echo "# Built-in text input keyboards with custom layouts for emulators, requires CompatibilityHacksTextInputEmulatesHwKeyboard=y" >> AndroidAppSettings.cfg +echo "# 0 or empty - standard Android keyboard" >> AndroidAppSettings.cfg +echo "# 1 - Simple QWERTY keyboard, no function keys, no arrow keys" >> AndroidAppSettings.cfg +echo "# 2 - Commodore 64 keyboard" >> AndroidAppSettings.cfg +echo "# 3 - Amiga keyboard" >> AndroidAppSettings.cfg +echo TextInputKeyboard=$TextInputKeyboard >> AndroidAppSettings.cfg +echo >> AndroidAppSettings.cfg echo "# Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n)" >> AndroidAppSettings.cfg echo CompatibilityHacksPreventAudioChopping=$CompatibilityHacksPreventAudioChopping >> AndroidAppSettings.cfg echo >> AndroidAppSettings.cfg @@ -478,6 +485,10 @@ else CompatibilityHacksTextInputEmulatesHwKeyboard=false fi +if [ -z "$TextInputKeyboard" ] ; then + TextInputKeyboard=0 +fi + if [ "$CompatibilityHacksPreventAudioChopping" = "y" ] ; then CompatibilityHacksPreventAudioChopping=-DSDL_AUDIO_PREVENT_CHOPPING_WITH_DELAY=1 else @@ -794,6 +805,7 @@ $SEDI "s/public static boolean NeedGles2 = .*;/public static boolean NeedGles2 = $SEDI "s/public static boolean CompatibilityHacksVideo = .*;/public static boolean CompatibilityHacksVideo = $CompatibilityHacksForceScreenUpdate;/" project/src/Globals.java $SEDI "s/public static boolean CompatibilityHacksStaticInit = .*;/public static boolean CompatibilityHacksStaticInit = $CompatibilityHacksStaticInit;/" project/src/Globals.java $SEDI "s/public static boolean CompatibilityHacksTextInputEmulatesHwKeyboard = .*;/public static boolean CompatibilityHacksTextInputEmulatesHwKeyboard = $CompatibilityHacksTextInputEmulatesHwKeyboard;/" project/src/Globals.java +$SEDI "s/public static int TextInputKeyboard = .*;/public static int TextInputKeyboard = $TextInputKeyboard;/" project/src/Globals.java $SEDI "s/public static boolean CompatibilityHacksForceScreenUpdateMouseClick = .*;/public static boolean CompatibilityHacksForceScreenUpdateMouseClick = $CompatibilityHacksForceScreenUpdateMouseClick;/" project/src/Globals.java $SEDI "s/public static boolean HorizontalOrientation = .*;/public static boolean HorizontalOrientation = $HorizontalOrientation;/" project/src/Globals.java $SEDI "s^public static boolean KeepAspectRatioDefaultSetting = .*^public static boolean KeepAspectRatioDefaultSetting = $SdlVideoResizeKeepAspect;^" project/src/Globals.java diff --git a/project/java/Clipboard.java b/project/java/Clipboard.java index 2e6c99d40..aba483341 100644 --- a/project/java/Clipboard.java +++ b/project/java/Clipboard.java @@ -90,7 +90,6 @@ public abstract class Clipboard } public void setListener(final Context context, final Runnable listener) { - Log.i("SDL", "Cannot set clipboard listener on Android 2.3 or older"); ClipboardManager clipboard = (ClipboardManager) context.getSystemService(context.CLIPBOARD_SERVICE); clipboard.addPrimaryClipChangedListener(new OnPrimaryClipChangedListener() { diff --git a/project/java/Globals.java b/project/java/Globals.java index 8760c1ba6..526171986 100644 --- a/project/java/Globals.java +++ b/project/java/Globals.java @@ -43,6 +43,7 @@ class Globals public static boolean CompatibilityHacksForceScreenUpdateMouseClick = true; public static boolean CompatibilityHacksStaticInit = false; public static boolean CompatibilityHacksTextInputEmulatesHwKeyboard = false; + public static int TextInputKeyboard = 0; public static boolean KeepAspectRatioDefaultSetting = false; public static boolean InhibitSuspend = false; public static boolean CreateService = false; diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index 801c4fe88..a7d6e3a97 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -60,9 +60,10 @@ import java.io.OutputStream; import java.io.FileOutputStream; import java.io.File; import java.io.FileInputStream; -import java.util.zip.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import java.util.zip.CheckedInputStream; +import java.util.zip.CRC32; import java.util.Set; import android.text.SpannedString; import java.io.BufferedReader; @@ -86,7 +87,8 @@ import android.app.KeyguardManager; import android.view.ViewTreeObserver; import android.graphics.Rect; import android.view.InputDevice; - +import android.inputmethodservice.KeyboardView; +import android.inputmethodservice.Keyboard; public class MainActivity extends Activity { @@ -482,6 +484,8 @@ public class MainActivity extends Activity cloudSave.onActivityResult(request, response, data); } + private int TextInputKeyboardList[] = { 0, R.xml.qwerty, R.xml.c64, R.xml.amiga }; + public void showScreenKeyboardWithoutTextInputField() { if( !keyboardWithoutTextInputShown ) @@ -491,9 +495,78 @@ public class MainActivity extends Activity { public void run() { - _inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - _inputManager.showSoftInput(mGLView, InputMethodManager.SHOW_FORCED); - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + if (Globals.TextInputKeyboard == 0) + { + _inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + _inputManager.showSoftInput(mGLView, InputMethodManager.SHOW_FORCED); + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } + else + { + if( _screenKeyboard != null ) + return; + class BuiltInKeyboardView extends KeyboardView + { + public BuiltInKeyboardView(Context context, android.util.AttributeSet attrs) + { + super(context, attrs); + } + public boolean dispatchTouchEvent(final MotionEvent ev) + { + if( ev.getY() < getTop() ) + return false; + if( ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE ) + { + // Convert pointer coords, this will lose multitiouch data, however KeyboardView does not support multitouch anyway + MotionEvent converted = MotionEvent.obtain(ev.getDownTime(), ev.getEventTime(), ev.getAction(), ev.getX(), ev.getY() - (float)getTop(), ev.getMetaState()); + return super.dispatchTouchEvent(converted); + } + return false; + } + public boolean onKeyDown(int keyCode, final KeyEvent event) + { + return false; + } + public boolean onKeyUp(int keyCode, final KeyEvent event) + { + return false; + } + } + BuiltInKeyboardView builtinKeyboard = new BuiltInKeyboardView(MainActivity.this, null); + builtinKeyboard.setKeyboard(new Keyboard(MainActivity.this, TextInputKeyboardList[Globals.TextInputKeyboard])); + builtinKeyboard.setPreviewEnabled(false); + builtinKeyboard.setProximityCorrectionEnabled(false); + builtinKeyboard.setOnKeyboardActionListener(new KeyboardView.OnKeyboardActionListener() + { + public void onPress(int key) + { + MainActivity.this.onKeyDown(key, new KeyEvent(KeyEvent.ACTION_DOWN, key)); + } + public void onRelease(int key) + { + MainActivity.this.onKeyUp(key, new KeyEvent(KeyEvent.ACTION_UP, key)); + } + public void onText(CharSequence p1) {} + public void swipeLeft() {} + public void swipeRight() {} + public void swipeDown() {} + public void swipeUp() {} + public void onKey(int p1, int[] p2) {} + }); + /* + builtinKeyboard.addOnLayoutChangeListener(new View.OnLayoutChangeListener() + { + public void onLayoutChange (View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) + { + Log.i("SDL", "Built-in keyboard getTop " + top); + ((KeyboardView)v).setVerticalCorrection(top); + } + }); + */ + _screenKeyboard = builtinKeyboard; + FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM); + _videoLayout.addView(_screenKeyboard, layout); + } } }); } @@ -504,6 +577,11 @@ public class MainActivity extends Activity { public void run() { + if( _screenKeyboard != null ) + { + _videoLayout.removeView(_screenKeyboard); + _screenKeyboard = null; + } getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); _inputManager.hideSoftInputFromWindow(mGLView.getWindowToken(), 0); DimSystemStatusBar.get().dim(_videoLayout); @@ -573,38 +651,39 @@ public class MainActivity extends Activity return false; } }; - _screenKeyboard = new EditText(this); + EditText screenKeyboard = new EditText(this); // This code does not work /* - _screenKeyboard.setMaxLines(100); + screenKeyboard.setMaxLines(100); ViewGroup.LayoutParams layout = _screenKeyboard.getLayoutParams(); if( layout != null ) { layout.width = ViewGroup.LayoutParams.FILL_PARENT; layout.height = ViewGroup.LayoutParams.FILL_PARENT; - _screenKeyboard.setLayoutParams(layout); + screenKeyboard.setLayoutParams(layout); } - _screenKeyboard.setGravity(android.view.Gravity.BOTTOM | android.view.Gravity.LEFT); + screenKeyboard.setGravity(android.view.Gravity.BOTTOM | android.view.Gravity.LEFT); */ String hint = _screenKeyboardHintMessage; - _screenKeyboard.setHint(hint != null ? hint : getString(R.string.text_edit_click_here)); - _screenKeyboard.setText(oldText); - _screenKeyboard.setSelection(_screenKeyboard.getText().length()); - _screenKeyboard.setOnKeyListener(new simpleKeyListener(this)); - _screenKeyboard.setBackgroundColor(Color.BLACK); // Full opaque - do not show semi-transparent edit box, it's confusing - _screenKeyboard.setTextColor(Color.WHITE); // Just to be sure about gamma + screenKeyboard.setHint(hint != null ? hint : getString(R.string.text_edit_click_here)); + screenKeyboard.setText(oldText); + screenKeyboard.setSelection(screenKeyboard.getText().length()); + screenKeyboard.setOnKeyListener(new simpleKeyListener(this)); + screenKeyboard.setBackgroundColor(Color.BLACK); // Full opaque - do not show semi-transparent edit box, it's confusing + screenKeyboard.setTextColor(Color.WHITE); // Just to be sure about gamma if( isRunningOnOUYA() ) - _screenKeyboard.setPadding(100, 100, 100, 100); // Bad bad HDMI TVs all have cropped borders + screenKeyboard.setPadding(100, 100, 100, 100); // Bad bad HDMI TVs all have cropped borders + _screenKeyboard = screenKeyboard; _videoLayout.addView(_screenKeyboard); //_screenKeyboard.setKeyListener(new TextKeyListener(TextKeyListener.Capitalize.NONE, false)); - _screenKeyboard.setInputType(InputType.TYPE_CLASS_TEXT); - _screenKeyboard.setFocusableInTouchMode(true); - _screenKeyboard.setFocusable(true); - _screenKeyboard.requestFocus(); - _inputManager.showSoftInput(_screenKeyboard, InputMethodManager.SHOW_IMPLICIT); + screenKeyboard.setInputType(InputType.TYPE_CLASS_TEXT); + screenKeyboard.setFocusableInTouchMode(true); + screenKeyboard.setFocusable(true); + screenKeyboard.requestFocus(); + _inputManager.showSoftInput(screenKeyboard, InputMethodManager.SHOW_IMPLICIT); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); // Hack to try to force on-screen keyboard - final EditText keyboard = _screenKeyboard; + final EditText keyboard = screenKeyboard; keyboard.postDelayed( new Runnable() { public void run() @@ -631,12 +710,12 @@ public class MainActivity extends Activity if( keyboardWithoutTextInputShown ) showScreenKeyboardWithoutTextInputField(); - if(_screenKeyboard == null) + if(_screenKeyboard == null || ! (_screenKeyboard instanceof EditText)) return; synchronized(textInput) { - String text = _screenKeyboard.getText().toString(); + String text = ((EditText)_screenKeyboard).getText().toString(); for(int i = 0; i < text.length(); i++) { DemoRenderer.nativeTextInput( (int)text.charAt(i), (int)text.codePointAt(i) ); @@ -673,10 +752,10 @@ public class MainActivity extends Activity { public void run() { - if( _screenKeyboard != null ) + if( _screenKeyboard != null && _screenKeyboard instanceof EditText ) { String hint = _screenKeyboardHintMessage; - _screenKeyboard.setHint(hint != null ? hint : getString(R.string.text_edit_click_here)); + ((EditText)_screenKeyboard).setHint(hint != null ? hint : getString(R.string.text_edit_click_here)); } } } ); @@ -779,9 +858,9 @@ public class MainActivity extends Activity DemoGLSurfaceView.nativeMouseButtonsPressed(2, 1); return true; } - if( _screenKeyboard != null ) - _screenKeyboard.onKeyDown(keyCode, event); - else + if( _screenKeyboard != null && _screenKeyboard.onKeyDown(keyCode, event) ) + return true; + if( mGLView != null ) { if( mGLView.nativeKey( keyCode, 1, event.getUnicodeChar() ) == 0 ) @@ -807,9 +886,9 @@ public class MainActivity extends Activity DemoGLSurfaceView.nativeMouseButtonsPressed(2, 0); return true; } - if( _screenKeyboard != null ) - _screenKeyboard.onKeyUp(keyCode, event); - else + if( _screenKeyboard != null && _screenKeyboard.onKeyUp(keyCode, event) ) + return true; + if( mGLView != null ) { if( mGLView.nativeKey( keyCode, 0, event.getUnicodeChar() ) == 0 ) @@ -862,9 +941,9 @@ public class MainActivity extends Activity public boolean dispatchTouchEvent(final MotionEvent ev) { //Log.i("SDL", "dispatchTouchEvent: " + ev.getAction() + " coords " + ev.getX() + ":" + ev.getY() ); - if(_screenKeyboard != null) - _screenKeyboard.dispatchTouchEvent(ev); - else + if(_screenKeyboard != null && _screenKeyboard.dispatchTouchEvent(ev)) + return true; + if( _ad.getView() != null && // User clicked the advertisement, ignore when user moved finger from game screen to advertisement or touches screen with several fingers ((ev.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN || (ev.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) && @@ -1325,7 +1404,7 @@ public class MainActivity extends Activity public ProgressDialog loadingDialog = null; FrameLayout _videoLayout = null; - private EditText _screenKeyboard = null; + private View _screenKeyboard = null; private String _screenKeyboardHintMessage = null; static boolean keyboardWithoutTextInputShown = false; private boolean sdlInited = false; diff --git a/project/jni/application/ballfield/AndroidAppSettings.cfg b/project/jni/application/ballfield/AndroidAppSettings.cfg index b990abbcd..5ce8a6703 100644 --- a/project/jni/application/ballfield/AndroidAppSettings.cfg +++ b/project/jni/application/ballfield/AndroidAppSettings.cfg @@ -17,7 +17,7 @@ AppVersionName="1.01" # 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 +# You can specify Google Play expansion files in the form 'obb:main.12345' or 'obb:patch.12345' where 12345 is the app version, first associated with the file AppDataDownloadUrl="!!Game data is 1 Mb|ballfield3.zip" # Reset SDL config when updating application to the new version (y) / (n) @@ -80,6 +80,13 @@ CompatibilityHacksStaticInit=n # On-screen Android soft text input emulates hardware keyboard, this will only work with Hackers Keyboard app (y)/(n) CompatibilityHacksTextInputEmulatesHwKeyboard=n +# Built-in text input keyboards with custom layouts for emulators, requires CompatibilityHacksTextInputEmulatesHwKeyboard=y +# 0 - standard Android keyboard +# 1 - Simple QWERTY keyboard, no function keys, no arrow keys +# 2 - Commodore 64 keyboard +# 3 - Amiga keyboard +TextInputKeyboard=3 + # Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n) CompatibilityHacksPreventAudioChopping=n @@ -113,6 +120,9 @@ RightMouseButtonLongPress= # Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n) ShowMouseCursor=n +# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n) +ScreenFollowsMouse= + # Generate more touch events, by default SDL generates one event per one video frame, this is useful for drawing apps (y) or (n) GenerateSubframeTouchEvents=n @@ -145,6 +155,9 @@ AppUsesAccelerometer=y # Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4 AppUsesGyroscope=y +# Application uses orientation sensor (y) or (n), reported as joystick 1 axes 8-10 +AppUsesOrientationSensor= + # 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= @@ -188,10 +201,11 @@ RedefinedKeysScreenKb="0 1 2 3 4 5 6 7 8 9" RedefinedKeysScreenKbNames="0 1 2 3 4 5 6 7 8 9" # On-screen keys theme -# 0 = Ultimate Droid by Sean Stieber (green, with gamepad joystick) -# 1 = Simple Theme by Beholder (white, with gamepad joystick) +# 0 = Ultimate Droid by Sean Stieber (green, with cross joystick) +# 1 = Simple Theme by Beholder (white, with cross joystick) # 2 = Sun by Sirea (yellow, with round joystick) # 3 = Keen by Gerstrong (multicolor, with round joystick) +# 4 = Retro by Santiago Radeff (red/white, with cross joystick) TouchscreenKeysTheme=4 # Redefine gamepad keys to SDL keysyms, button order is: @@ -202,22 +216,25 @@ RedefinedKeysGamepad="0 1 2 3 4 5 6 7 8 9" 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 +# 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 SettingsMenuKeyboard.ScreenKeyboardAdvanced HiddenMenuOptions='' # 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 +# 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 SettingsMenuKeyboard.ScreenKeyboardAdvanced FirstStartMenuOptions='SettingsMenu.DummyMenu' -# Specify architectures to compile, 'all' or 'y' to compile for all architectures. -# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips -MultiABI='armeabi-v7a x86 arm64-v8a' - # Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower AppMinimumRAM=0 +# GCC version, 4.6 (default) or 4.8, CLANG is not supported yet +NDK_TOOLCHAIN_VERSION= + +# Specify architectures to compile, 'all' or 'y' to compile for all architectures. +# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips +MultiABI='armeabi-v7a' + # 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 @@ -230,7 +247,7 @@ CustomBuildScript=n AppCflags='-O2 -finline-functions' # Additional LDFLAGS for application -AppLdflags='-fuse-ld=bfd' # Hack, because NDK seems to be bugged +AppLdflags='-fuse-ld=bfd' # If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable AppOverlapsSystemHeaders= @@ -257,3 +274,6 @@ AdmobTestDeviceId= # Your AdMob banner size (BANNER/FULL_BANNER/LEADERBOARD/MEDIUM_RECTANGLE/SMART_BANNER/WIDE_SKYSCRAPER/FULL_WIDTH:Height/Width:AUTO_HEIGHT/Width:Height) AdmobBannerSize= +# Google Play Game Services application ID, required for cloud saves to work +GooglePlayGameServicesId= + diff --git a/project/jni/application/test-opengl/AndroidAppSettings.cfg b/project/jni/application/test-opengl/AndroidAppSettings.cfg index b13420bdf..bc906d544 100644 --- a/project/jni/application/test-opengl/AndroidAppSettings.cfg +++ b/project/jni/application/test-opengl/AndroidAppSettings.cfg @@ -17,7 +17,7 @@ AppVersionName="1" # 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 +# You can specify Google Play expansion files in the form 'obb:main.12345' or 'obb:patch.12345' where 12345 is the app version, first associated with the file AppDataDownloadUrl="Gamedata|data2.zip" # Reset SDL config when updating application to the new version (y) / (n) @@ -68,13 +68,24 @@ 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 +CompatibilityHacksForceScreenUpdate=n + +# Application does not call SDL_Flip() or SDL_UpdateRects() after mouse click (ScummVM and all Amiga emulators do that) - +# force screen update by moving mouse cursor a little after each click (y) or (n) +CompatibilityHacksForceScreenUpdateMouseClick=y # 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=n +CompatibilityHacksTextInputEmulatesHwKeyboard=y + +# Built-in text input keyboards with custom layouts for emulators, requires CompatibilityHacksTextInputEmulatesHwKeyboard=y +# 0 or empty - standard Android keyboard +# 1 - Simple QWERTY keyboard, no function keys, no arrow keys +# 2 - Commodore 64 keyboard +# 3 - Amiga keyboard +TextInputKeyboard=3 # Hack for broken devices: prevent audio chopping, by sleeping a bit after pushing each audio chunk (y)/(n) CompatibilityHacksPreventAudioChopping=n @@ -109,19 +120,27 @@ RightMouseButtonLongPress= # Show SDL mouse cursor, for applications that do not draw cursor at all (y) or (n) ShowMouseCursor=n +# Screen follows mouse cursor, when it's covered by soft keyboard, this works only in software video mode (y) or (n) +ScreenFollowsMouse= + # 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) +# Show on-screen dpad/joystick, that will act as arrow keys (y) or (n) AppNeedsArrowKeys=n +# On-screen dpad/joystick will appear under finger when it touches the screen (y) or (n) +# Joystick always follows finger, so moving mouse requires touching the screen with other finger +FloatingScreenJoystick= + # Application needs text input (y) or (n), enables button for text input on screen -AppNeedsTextInput=n +AppNeedsTextInput=y # Application uses joystick (y) or (n), the on-screen DPAD will be used as joystick 0 axes 0-1 +# This will disable AppNeedsArrowKeys option AppUsesJoystick=n # Application uses second on-screen joystick, as SDL joystick 0 axes 2-3 (y)/(n) @@ -136,6 +155,12 @@ AppUsesAccelerometer=n # Application uses gyroscope (y) or (n), the gyroscope will be used as joystick 1 axes 2-4 AppUsesGyroscope=n +# Application uses orientation sensor (y) or (n), reported as joystick 1 axes 8-10 +AppUsesOrientationSensor= + +# 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 @@ -176,10 +201,11 @@ RedefinedKeysScreenKb="RETURN" RedefinedKeysScreenKbNames="RETURN" # On-screen keys theme -# 0 = Ultimate Droid by Sean Stieber (green, with gamepad joystick) -# 1 = Simple Theme by Beholder (white, with gamepad joystick) +# 0 = Ultimate Droid by Sean Stieber (green, with cross joystick) +# 1 = Simple Theme by Beholder (white, with cross joystick) # 2 = Sun by Sirea (yellow, with round joystick) # 3 = Keen by Gerstrong (multicolor, with round joystick) +# 4 = Retro by Santiago Radeff (red/white, with cross joystick) TouchscreenKeysTheme=2 # Redefine gamepad keys to SDL keysyms, button order is: @@ -190,22 +216,25 @@ RedefinedKeysGamepad="RETURN" StartupMenuButtonTimeout=0 # 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 +# 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 SettingsMenuKeyboard.ScreenKeyboardAdvanced HiddenMenuOptions='' # 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 +# 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 SettingsMenuKeyboard.ScreenKeyboardAdvanced 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='n' - # Minimum amount of RAM application requires, in Mb, SDL will print warning to user if it's lower AppMinimumRAM=0 +# GCC version, 4.6 (default) or 4.8, CLANG is not supported yet +NDK_TOOLCHAIN_VERSION= + +# Specify architectures to compile, 'all' or 'y' to compile for all architectures. +# Available architectures: armeabi armeabi-v7a armeabi-v7a-hard x86 mips +MultiABI='armeabi-v7a' + # 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 @@ -218,7 +247,7 @@ CustomBuildScript=n AppCflags='-finline-functions -O2' # Additional LDFLAGS for application -AppLdflags='' +AppLdflags='-fuse-ld=bfd' # If application has headers with the same name as system headers, this option tries to fix compiler flags to make it compilable AppOverlapsSystemHeaders= @@ -242,6 +271,9 @@ 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) +# Your AdMob banner size (BANNER/FULL_BANNER/LEADERBOARD/MEDIUM_RECTANGLE/SMART_BANNER/WIDE_SKYSCRAPER/FULL_WIDTH:Height/Width:AUTO_HEIGHT/Width:Height) AdmobBannerSize= +# Google Play Game Services application ID, required for cloud saves to work +GooglePlayGameServicesId= + diff --git a/project/jni/application/test-opengl/sdl_hello.cpp b/project/jni/application/test-opengl/sdl_hello.cpp index 7bf66b28a..914654359 100644 --- a/project/jni/application/test-opengl/sdl_hello.cpp +++ b/project/jni/application/test-opengl/sdl_hello.cpp @@ -14,7 +14,7 @@ #include #endif -int screenWidth = 0; +int screenWidth = 0; int screenHeight = 0; struct Sprite { @@ -28,48 +28,48 @@ struct Sprite { bool loadTexture() { - SDL_Surface *pic; + SDL_Surface *pic; - pic = IMG_Load(imagePath.c_str()); + pic = IMG_Load(imagePath.c_str()); - if(!pic) - { - printf("Error: image %s cannot be loaded\n", imagePath.c_str()); - return false; - } - if(pic->format->BitsPerPixel != 32 && pic->format->BitsPerPixel != 24) - { - printf("Error: image %s is %dbpp - it should be either 24bpp or 32bpp, images with palette are not supported\n", imagePath.c_str(), pic->format->BitsPerPixel); - SDL_FreeSurface(pic); - return false; - } + if(!pic) + { + printf("Error: image %s cannot be loaded\n", imagePath.c_str()); + return false; + } + if(pic->format->BitsPerPixel != 32 && pic->format->BitsPerPixel != 24) + { + printf("Error: image %s is %dbpp - it should be either 24bpp or 32bpp, images with palette are not supported\n", imagePath.c_str(), pic->format->BitsPerPixel); + SDL_FreeSurface(pic); + return false; + } - GLenum glFormat = (pic->format->BitsPerPixel == 32 ? GL_RGBA : GL_RGB); - w = pic->w; - h = pic->h; - // All OpenGL textures must have size which is power of 2, such as 128, 256, 512 etc - int upload_w = powerOfTwo(w); - int upload_h = powerOfTwo(h); - texcoord_w = (float) w / (float) upload_w; - texcoord_h = (float) h / (float) upload_h; + GLenum glFormat = (pic->format->BitsPerPixel == 32 ? GL_RGBA : GL_RGB); + w = pic->w; + h = pic->h; + // All OpenGL textures must have size which is power of 2, such as 128, 256, 512 etc + int upload_w = powerOfTwo(w); + int upload_h = powerOfTwo(h); + texcoord_w = (float) w / (float) upload_w; + texcoord_h = (float) h / (float) upload_h; - glGenTextures(1, &texture); + glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindTexture(GL_TEXTURE_2D, texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, glFormat, upload_w, upload_h, 0, glFormat, GL_UNSIGNED_BYTE, NULL); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, glFormat, GL_UNSIGNED_BYTE, pic->pixels); + glTexImage2D(GL_TEXTURE_2D, 0, glFormat, upload_w, upload_h, 0, glFormat, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, glFormat, GL_UNSIGNED_BYTE, pic->pixels); - SDL_FreeSurface(pic); + SDL_FreeSurface(pic); - return true; + return true; } int powerOfTwo(int i) @@ -81,27 +81,27 @@ struct Sprite { void draw(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLfloat r = 1.0f, GLfloat g = 1.0f, GLfloat b = 1.0f, GLfloat a = 1.0f) { - if(texture == 0) - return; - // GL coordinates start at bottom-left corner, which is counter-intuitive for sprite graphics, so we have to flip Y coordinate - GLfloat textureCoordinates[] = { 0.0f, 0.0f, - 0.0f, texcoord_h, - texcoord_w, texcoord_h, - texcoord_w, 0.0f }; - GLfloat vertices[] = { x, screenHeight - y, - x, screenHeight - (y + height), - x + width, screenHeight - (y + height), - x + width, screenHeight - y }; - glColor4f(r, g, b, a); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, vertices); - glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // You may just replace all your GL_QUADS with GL_TRIANGLE_FAN and it will draw absolutely identically with same coordinates, if you have just 4 coords. - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if(texture == 0) + return; + // GL coordinates start at bottom-left corner, which is counter-intuitive for sprite graphics, so we have to flip Y coordinate + GLfloat textureCoordinates[] = { 0.0f, 0.0f, + 0.0f, texcoord_h, + texcoord_w, texcoord_h, + texcoord_w, 0.0f }; + GLfloat vertices[] = { x, screenHeight - y, + x, screenHeight - (y + height), + x + width, screenHeight - (y + height), + x + width, screenHeight - y }; + glColor4f(r, g, b, a); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // You may just replace all your GL_QUADS with GL_TRIANGLE_FAN and it will draw absolutely identically with same coordinates, if you have just 4 coords. + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void draw(GLfloat x, GLfloat y) @@ -127,106 +127,113 @@ initGL() glOrtho(0.0f, screenWidth, 0.0f, screenHeight, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glDisable(GL_DEPTH_TEST); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glDisable(GL_DEPTH_TEST); } static void clearScreen() { - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Always clear your scene before rendering, unless you're sure that you'll fill whole screen with textures/models etc + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Always clear your scene before rendering, unless you're sure that you'll fill whole screen with textures/models etc - // You have to do this each frame, because SDL messes up with your GL context when drawing on-screen keyboard, however is saves/restores your matrices - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + // You have to do this each frame, because SDL messes up with your GL context when drawing on-screen keyboard, however is saves/restores your matrices + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } static void initSDL() { - SDL_Init(SDL_INIT_VIDEO); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK); + SDL_EnableUNICODE(1); - screenWidth = SDL_GetVideoInfo()->current_w; - screenHeight = SDL_GetVideoInfo()->current_h; + screenWidth = SDL_GetVideoInfo()->current_w; + screenHeight = SDL_GetVideoInfo()->current_h; - if ( ! SDL_SetVideoMode(screenWidth, screenHeight, 24, SDL_OPENGL|SDL_DOUBLEBUF|SDL_FULLSCREEN) ) - { - fprintf(stderr, "Couldn't set GL video mode: %s\n", SDL_GetError()); - SDL_Quit(); - exit(2); - } - SDL_WM_SetCaption("test", "test"); + if ( ! SDL_SetVideoMode(screenWidth, screenHeight, 24, SDL_OPENGL|SDL_DOUBLEBUF|SDL_FULLSCREEN) ) + { + fprintf(stderr, "Couldn't set GL video mode: %s\n", SDL_GetError()); + SDL_Quit(); + exit(2); + } + SDL_WM_SetCaption("test", "test"); } int main(int argc, char *argv[]) { - initSDL(); - initGL(); + initSDL(); + initGL(); - std::vector sprites; - sprites.push_back(Sprite("test.png")); - sprites.push_back(Sprite("element0.png")); - sprites.push_back(Sprite("element1.png")); - sprites.push_back(Sprite("element2.png")); - sprites.push_back(Sprite("element3.png")); + std::vector sprites; + sprites.push_back(Sprite("test.png")); + sprites.push_back(Sprite("element0.png")); + sprites.push_back(Sprite("element1.png")); + sprites.push_back(Sprite("element2.png")); + sprites.push_back(Sprite("element3.png")); - int coords[][2] = { {0, 0}, - {200, 0}, - {300, 200}, - {400, 300} }; + int coords[][2] = { {0, 0}, + {200, 0}, + {300, 200}, + {400, 300} }; - float pulse = 1.0f, pulseChange = 0.01f; - int anim = 1; + float pulse = 1.0f, pulseChange = 0.01f; + int anim = 1; - while ( ! SDL_GetKeyState(NULL)[SDLK_ESCAPE] ) // Exit by pressing Back button - { - clearScreen(); - int mouseX = 0, mouseY = 0, buttons = 0; - buttons = SDL_GetMouseState(&mouseX, &mouseY); + while ( ! SDL_GetKeyState(NULL)[SDLK_ESCAPE] ) // Exit by pressing Back button + { + clearScreen(); + int mouseX = 0, mouseY = 0, buttons = 0; + buttons = SDL_GetMouseState(&mouseX, &mouseY); - sprites[0].draw(mouseX - sprites[0].w/2, mouseY - sprites[0].h/2, sprites[0].w, sprites[0].h, buttons ? 0 : 1, 1, 1, pulse); + sprites[0].draw(mouseX - sprites[0].w/2, mouseY - sprites[0].h/2, sprites[0].w, sprites[0].h, buttons ? 0 : 1, 1, 1, pulse); - sprites[1].draw(coords[0][0], coords[0][1]); - sprites[2].draw(coords[1][0], coords[1][1], sprites[2].w * pulse * 4, sprites[2].h * pulse * 4); - sprites[3].draw(coords[2][0], coords[2][1], sprites[3].w * pulse * 4, sprites[3].h * 2); - sprites[4].draw(coords[3][0], coords[3][1], sprites[4].w, sprites[4].h * pulse * 2); + sprites[1].draw(coords[0][0], coords[0][1]); + sprites[2].draw(coords[1][0], coords[1][1], sprites[2].w * pulse * 4, sprites[2].h * pulse * 4); + sprites[3].draw(coords[2][0], coords[2][1], sprites[3].w * pulse * 4, sprites[3].h * 2); + sprites[4].draw(coords[3][0], coords[3][1], sprites[4].w, sprites[4].h * pulse * 2); - SDL_GL_SwapBuffers(); - SDL_Event event; - while( SDL_PollEvent(&event) ) - { - if(event.type == SDL_VIDEORESIZE) - { - // Reload textures to OpenGL - initGL(); - for(int i = 0; i < sprites.size(); i++) - sprites[i].loadTexture(); - } - } + SDL_GL_SwapBuffers(); + SDL_Event event; + while( SDL_PollEvent(&event) ) + { + if(event.type == SDL_VIDEORESIZE) + { + // Reload textures to OpenGL + initGL(); + for(int i = 0; i < sprites.size(); i++) + sprites[i].loadTexture(); + } + if(event.type == SDL_KEYUP || event.type == SDL_KEYDOWN) + { + __android_log_print(ANDROID_LOG_INFO, "Hello", "SDL key event: evt %s state %s key %4d %12s scancode %4d mod %2d unicode %d", event.type == SDL_KEYUP ? "UP " : "DOWN" , event.key.state == SDL_PRESSED ? "PRESSED " : "RELEASED", (int)event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym), (int)event.key.keysym.scancode, (int)event.key.keysym.mod, (int)event.key.keysym.unicode); + if(event.key.keysym.sym == SDLK_ESCAPE) + return 0; + } + } - // Some kinda animation + // Some kinda animation - pulse += pulseChange; - if(pulse > 1.0f) - pulseChange = -0.01f; - if(pulse < 0) - pulseChange = 0.01f; + pulse += pulseChange; + if(pulse > 1.0f) + pulseChange = -0.01f; + if(pulse < 0) + pulseChange = 0.01f; - for(int i = 0; i < 4; i++) - { - coords[i][0] += anim; - coords[i][1] += anim; - } - if( coords[0][0] < 0 ) - anim = 1; - if( coords[3][1] > screenHeight ) - anim = -1; - } + for(int i = 0; i < 4; i++) + { + coords[i][0] += anim; + coords[i][1] += anim; + } + if( coords[0][0] < 0 ) + anim = 1; + if( coords[3][1] > screenHeight ) + anim = -1; + } - SDL_Quit(); - return 0; + SDL_Quit(); + return 0; } diff --git a/project/res/xml/amiga.xml b/project/res/xml/amiga.xml new file mode 100644 index 000000000..8dfdeeb0d --- /dev/null +++ b/project/res/xml/amiga.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/project/res/xml/c64.xml b/project/res/xml/c64.xml new file mode 100644 index 000000000..fbb4bae46 --- /dev/null +++ b/project/res/xml/c64.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/project/res/xml/qwerty.xml b/project/res/xml/qwerty.xml new file mode 100644 index 000000000..de8cf2d9e --- /dev/null +++ b/project/res/xml/qwerty.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +