diff --git a/project/jni/application/uqm-hd/AndroidAppSettings.cfg b/project/jni/application/uqm-hd/AndroidAppSettings.cfg index 46b0668f7..68cdd2080 100644 --- a/project/jni/application/uqm-hd/AndroidAppSettings.cfg +++ b/project/jni/application/uqm-hd/AndroidAppSettings.cfg @@ -7,10 +7,10 @@ AppName="Ur-Quan Masters HD" AppFullName=com.googlecode.uqm.hd # Application version code (integer) -AppVersionCode=07009 +AppVersionCode=07010 # Application user-visible version name (string) -AppVersionName="0.7.0.09" +AppVersionName="0.7.0.10" # 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 @@ -24,7 +24,7 @@ AppDataDownloadUrl="!!640x480 graphics (160 Mb)|:packages/hires2x.uqm:http://sou ResetSdlConfigForThisVersion=n # Delete application data files when upgrading (specify file/dir paths separated by spaces) -DeleteFilesOnUpgrade="libsdl-DownloadFinished-11.flag" +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/ diff --git a/project/jni/application/uqm-hd/android.diff b/project/jni/application/uqm-hd/android.diff index 25cf68acf..e9e02f5a3 100644 --- a/project/jni/application/uqm-hd/android.diff +++ b/project/jni/application/uqm-hd/android.diff @@ -1,1794 +1,16 @@ -Index: svnversion.h +Index: libs/input/input_common.h =================================================================== ---- svnversion.h (revision 1353) -+++ svnversion.h (working copy) -@@ -1 +1 @@ --#define UQMHD_SVN_REVISION "1337M" -+#define UQMHD_SVN_REVISION "1351M" -Index: config_unix.h -=================================================================== ---- config_unix.h (revision 0) -+++ config_unix.h (working copy) -@@ -0,0 +1,63 @@ -+/* This file contains some compile-time configuration options for *nix -+ * systems. -+ * config_unix.h is generated from config_unix.h.in by build.sh -+ * When building on MS Windows using build.sh (MinGW, Cygwin), -+ * config_win.h is generated from src/config_win.h.in. -+ * When using MSVC on MS Windows, you'll have to edit src/config_vc6.h -+ * manually if you want anything else than the defaults. -+ */ -+ -+#ifndef _CONFIG_UNIX_H -+#define _CONFIG_UNIX_H -+ -+/* Directory where the UQM game data is located */ -+#define CONTENTDIR "" -+ -+/* Directory where game data will be stored */ -+#define USERDIR "config/" -+ -+/* Directory where config files will be stored */ -+#define CONFIGDIR USERDIR -+ -+/* Directory where supermelee teams will be stored */ -+#define MELEEDIR "teams/" -+ -+/* Directory where save games will be stored */ -+#define SAVEDIR "save/" -+ -+/* Defined if words are stored with the most significant byte first */ -+#undef WORDS_BIGENDIAN -+ -+/* Defined if your system has readdir_r of its own */ -+#define HAVE_READDIR_R -+ -+/* Defined if your system has setenv of its own */ -+#define HAVE_SETENV -+ -+/* Defined if your system has strupr of its own */ -+#undef HAVE_STRUPR -+ -+/* Defined if your system has strcasecmp of its own */ -+#define HAVE_STRCASECMP_UQM -+ // Not using "HAVE_STRCASECMP" as that conflicts with SDL. -+ -+/* Defined if your system has stricmp of its own */ -+#undef HAVE_STRICMP -+ -+/* Defined if your system has getopt_long */ -+#define HAVE_GETOPT_LONG -+ -+/* Defined if your system has iswgraph of its own*/ -+#define HAVE_ISWGRAPH -+ -+/* Defined if your system has wchar_t of its own */ -+#define HAVE_WCHAR_T -+ -+/* Defined if your system has wint_t of its own */ -+#define HAVE_WINT_T -+ -+/* Defined if your system has _Bool of its own */ -+#define HAVE__BOOL -+ -+#endif /* _CONFIG_UNIX_H */ -+ -Index: uqm/menu.c -=================================================================== ---- uqm/menu.c (revision 1353) -+++ uqm/menu.c (working copy) -@@ -508,7 +508,7 @@ - s.origin.x = RADAR_X - r.corner.x; - s.origin.y = RADAR_Y - r.corner.y; - r.corner.x = s.origin.x - 1; -- r.corner.y = s.origin.y - (11 << RESOLUTION_FACTOR); // JMS_GFX -+ r.corner.y = s.origin.y - (40 << RESOLUTION_FACTOR); // JMS_GFX - r.extent.width = RADAR_WIDTH + 2; - BatchGraphics (); - SetContextForeGroundColor ( -Index: uqm/comm/zoqfot/zoqfotc.c -=================================================================== ---- uqm/comm/zoqfot/zoqfotc.c (revision 1353) -+++ uqm/comm/zoqfot/zoqfotc.c (working copy) -@@ -18,7 +18,7 @@ +--- libs/input/input_common.h (revision 1353) ++++ libs/input/input_common.h (working copy) +@@ -31,7 +31,7 @@ + extern int TFB_InitInput (int driver, int flags); + extern void TFB_UninitInput (void); - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../zoqfot/strings.h" - - #include "uqm/build.h" - #include "uqm/gameev.h" -Index: uqm/comm/comandr/comandr.c -=================================================================== ---- uqm/comm/comandr/comandr.c (revision 1353) -+++ uqm/comm/comandr/comandr.c (working copy) -@@ -20,7 +20,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../comandr/strings.h" - - #include "uqm/setup.h" - #include "uqm/sis.h" -Index: uqm/comm/blackur/blackurc.c -=================================================================== ---- uqm/comm/blackur/blackurc.c (revision 1353) -+++ uqm/comm/blackur/blackurc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../blackur/strings.h" - - static LOCDATA blackurq_desc = - { -Index: uqm/comm/mycon/myconc.c -=================================================================== ---- uqm/comm/mycon/myconc.c (revision 1353) -+++ uqm/comm/mycon/myconc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../mycon/strings.h" - - #include "uqm/gameev.h" - #include "libs/mathlib.h" -Index: uqm/comm/arilou/arilouc.c -=================================================================== ---- uqm/comm/arilou/arilouc.c (revision 1353) -+++ uqm/comm/arilou/arilouc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../arilou/strings.h" - - #include "uqm/gameev.h" - -Index: uqm/comm/chmmr/chmmrc.c -=================================================================== ---- uqm/comm/chmmr/chmmrc.c (revision 1353) -+++ uqm/comm/chmmr/chmmrc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../chmmr/strings.h" - - #include "uqm/build.h" - #include "uqm/hyper.h" -Index: uqm/comm/thradd/thraddc.c -=================================================================== ---- uqm/comm/thradd/thraddc.c (revision 1353) -+++ uqm/comm/thradd/thraddc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../thradd/strings.h" - - #include "uqm/build.h" - #include "uqm/gameev.h" -Index: uqm/comm/slyland/slyland.c -=================================================================== ---- uqm/comm/slyland/slyland.c (revision 1353) -+++ uqm/comm/slyland/slyland.c (working copy) -@@ -16,10 +16,10 @@ - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -+#include "../slyland/strings.h" -+#include - #include "../commall.h" --#include - #include "resinst.h" --#include "strings.h" - - #include "options.h" - #include "uqm/battle.h" -Index: uqm/comm/ilwrath/ilwrathc.c -=================================================================== ---- uqm/comm/ilwrath/ilwrathc.c (revision 1353) -+++ uqm/comm/ilwrath/ilwrathc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../ilwrath/strings.h" - - #include "uqm/gameev.h" - -Index: uqm/comm/urquan/urquanc.c -=================================================================== ---- uqm/comm/urquan/urquanc.c (revision 1353) -+++ uqm/comm/urquan/urquanc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../urquan/strings.h" - - static LOCDATA urquan_desc = - { -Index: uqm/comm/supox/supoxc.c -=================================================================== ---- uqm/comm/supox/supoxc.c (revision 1353) -+++ uqm/comm/supox/supoxc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../supox/strings.h" - - #include "uqm/build.h" - -Index: uqm/comm/vux/vuxc.c -=================================================================== ---- uqm/comm/vux/vuxc.c (revision 1353) -+++ uqm/comm/vux/vuxc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../vux/strings.h" - - static LOCDATA vux_desc_1x = - { -Index: uqm/comm/shofixt/shofixt.c -=================================================================== ---- uqm/comm/shofixt/shofixt.c (revision 1353) -+++ uqm/comm/shofixt/shofixt.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../shofixt/strings.h" - - #include "uqm/gameev.h" - -Index: uqm/comm/pkunk/pkunkc.c -=================================================================== ---- uqm/comm/pkunk/pkunkc.c (revision 1353) -+++ uqm/comm/pkunk/pkunkc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../pkunk/strings.h" - - #include "uqm/build.h" - #include "uqm/gameev.h" -Index: uqm/comm/spathi/spathic.c -=================================================================== ---- uqm/comm/spathi/spathic.c (revision 1353) -+++ uqm/comm/spathi/spathic.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../spathi/strings.h" - - #include "uqm/build.h" - -Index: uqm/comm/rebel/rebel.c -=================================================================== ---- uqm/comm/rebel/rebel.c (revision 1353) -+++ uqm/comm/rebel/rebel.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "../yehat/resinst.h" --#include "strings.h" -+#include "../rebel/strings.h" - - #include "uqm/build.h" - -Index: uqm/comm/druuge/druugec.c -=================================================================== ---- uqm/comm/druuge/druugec.c (revision 1353) -+++ uqm/comm/druuge/druugec.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../druuge/strings.h" - - #include "uqm/build.h" - #include "uqm/setup.h" -Index: uqm/comm/spahome/spahome.c -=================================================================== ---- uqm/comm/spahome/spahome.c (revision 1353) -+++ uqm/comm/spahome/spahome.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "../spathi/resinst.h" --#include "strings.h" -+#include "../spahome/strings.h" - - #include "uqm/build.h" - #include "uqm/gameev.h" -Index: uqm/comm/starbas/starbas.c -=================================================================== ---- uqm/comm/starbas/starbas.c (revision 1353) -+++ uqm/comm/starbas/starbas.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "../comandr/resinst.h" --#include "strings.h" -+#include "../starbas/strings.h" - - #include "uqm/build.h" - #include "uqm/setup.h" -Index: uqm/comm/utwig/utwigc.c -=================================================================== ---- uqm/comm/utwig/utwigc.c (revision 1353) -+++ uqm/comm/utwig/utwigc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../utwig/strings.h" - - #include "uqm/build.h" - #include "uqm/gameev.h" -Index: uqm/comm/umgah/umgahc.c -=================================================================== ---- uqm/comm/umgah/umgahc.c (revision 1353) -+++ uqm/comm/umgah/umgahc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../umgah/strings.h" - - #include "uqm/build.h" - -Index: uqm/comm/talkpet/talkpet.c -=================================================================== ---- uqm/comm/talkpet/talkpet.c (revision 1353) -+++ uqm/comm/talkpet/talkpet.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../talkpet/strings.h" - - #include "uqm/build.h" - -Index: uqm/comm/syreen/syreenc.c -=================================================================== ---- uqm/comm/syreen/syreenc.c (revision 1353) -+++ uqm/comm/syreen/syreenc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../syreen/strings.h" - - #include "libs/sound/sound.h" - #include "uqm/build.h" -Index: uqm/comm/melnorm/melnorm.c -=================================================================== ---- uqm/comm/melnorm/melnorm.c (revision 1353) -+++ uqm/comm/melnorm/melnorm.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../melnorm/strings.h" - - #include "uqm/gameev.h" - #include "uqm/setup.h" -Index: uqm/comm/yehat/yehatc.c -=================================================================== ---- uqm/comm/yehat/yehatc.c (revision 1353) -+++ uqm/comm/yehat/yehatc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../yehat/strings.h" - - #include "uqm/build.h" - #include "uqm/gameev.h" -Index: uqm/comm/orz/orzc.c -=================================================================== ---- uqm/comm/orz/orzc.c (revision 1353) -+++ uqm/comm/orz/orzc.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../orz/strings.h" - - #include "uqm/build.h" - -Index: uqm/comm/slyhome/slyhome.c -=================================================================== ---- uqm/comm/slyhome/slyhome.c (revision 1353) -+++ uqm/comm/slyhome/slyhome.c (working copy) -@@ -18,7 +18,7 @@ - - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../slyhome/strings.h" - - #include "uqm/gameev.h" - -Index: uqm/units.h -=================================================================== ---- uqm/units.h (revision 1353) -+++ uqm/units.h (working copy) -@@ -67,6 +67,7 @@ - #define RADAR_WIDTH (STATUS_WIDTH - RES_STAT_SCALE(8)) // JMS_GFX - #define RADAR_HEIGHT RES_STAT_SCALE(53) // JMS_GFX - #define RADAR_Y (SIS_ORG_Y + SIS_SCREEN_HEIGHT - (53 << RESOLUTION_FACTOR)) // JMS_GFX -+#define RADAR_Y_LIFTED_UP (RADAR_Y - (40 << RESOLUTION_FACTOR)) - - /* Blue boxes which display messages and the green date box. */ - #define SIS_TITLE_BOX_WIDTH (57 << RESOLUTION_FACTOR) // JMS_GFX -Index: uqm/controls.h -=================================================================== ---- uqm/controls.h (revision 1353) -+++ uqm/controls.h (working copy) -@@ -32,6 +32,7 @@ - KEY_WEAPON, - KEY_SPECIAL, - KEY_ESCAPE, -+ KEY_THRUST, - NUM_KEYS - }; - enum { -@@ -90,13 +91,14 @@ - #define BATTLE_ESCAPE ((BATTLE_INPUT_STATE)(1 << 5)) - #define BATTLE_DOWN ((BATTLE_INPUT_STATE)(1 << 6)) - --BATTLE_INPUT_STATE CurrentInputToBattleInput (COUNT player); -+BATTLE_INPUT_STATE CurrentInputToBattleInput (COUNT player, int direction /* = -1 for no directional input */); - BATTLE_INPUT_STATE PulsedInputToBattleInput (COUNT player); - - extern CONTROLLER_INPUT_STATE CurrentInputState; - extern CONTROLLER_INPUT_STATE PulsedInputState; - extern volatile CONTROLLER_INPUT_STATE ImmediateInputState; - extern CONTROL_TEMPLATE PlayerControls[]; -+extern BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu; - - void UpdateInputState (void); - extern void FlushInput (void); -@@ -116,6 +118,8 @@ - BOOLEAN WaitForNoInput (TimePeriod duration, BOOLEAN resetInput); - BOOLEAN WaitForNoInputUntil (TimeCount timeOut, BOOLEAN resetInput); - -+extern BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction, int player); -+ - void DoPopupWindow(const char *msg); - - typedef void (InputFrameCallback) (void); -Index: uqm/planets/solarsys.c -=================================================================== ---- uqm/planets/solarsys.c (revision 1353) -+++ uqm/planets/solarsys.c (working copy) -@@ -1245,18 +1245,19 @@ - static void - ProcessShipControls (void) - { -- COUNT index; -+ COUNT index = GetFrameIndex (GLOBAL (ShipStamp.frame));; - SIZE delta_x, delta_y; -+ BATTLE_INPUT_STATE InputState = GetDirectionalJoystickInput(index, 0); - -- if (CurrentInputState.key[PlayerControls[0]][KEY_UP]) -+ if (InputState & BATTLE_THRUST) - delta_y = -1; - else - delta_y = 0; - - delta_x = 0; -- if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT]) -+ if (InputState & BATTLE_LEFT) - delta_x -= 1; -- if (CurrentInputState.key[PlayerControls[0]][KEY_RIGHT]) -+ if (InputState & BATTLE_RIGHT) - delta_x += 1; - - if (delta_x || delta_y < 0) -@@ -1269,7 +1270,6 @@ - else - delta_y = 0; - -- index = GetFrameIndex (GLOBAL (ShipStamp.frame)); - if (pSolarSysState->turn_counter) - --pSolarSysState->turn_counter; - else if (delta_x) -@@ -2473,7 +2473,9 @@ - InitSolarSys (); - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); - SolarSysState.InputFunc = DoIpFlight; -+ TFB_SetOnScreenKeyboard_Melee (); - DoInput (&SolarSysState, FALSE); -+ TFB_SetOnScreenKeyboard_Menu (); - UninitSolarSys (); - pSolarSysState = 0; - } -@@ -2751,13 +2753,17 @@ - - if (pSS->InOrbit) - { // CheckShipLocation() or InitSolarSys() sent us to orbital -+ TFB_SetOnScreenKeyboard_Menu (); - EnterPlanetOrbit (); -+ TFB_SetOnScreenKeyboard_Melee (); - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); - pSS->InOrbit = FALSE; - } - else if (cancel || LastActivity == CHECK_LOAD) - { -+ TFB_SetOnScreenKeyboard_Menu (); - SolarSysMenu (); -+ TFB_SetOnScreenKeyboard_Melee (); - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); - } - else -Index: uqm/planets/pstarmap.c -=================================================================== ---- uqm/planets/pstarmap.c (revision 1353) -+++ uqm/planets/pstarmap.c (working copy) -@@ -2005,7 +2005,9 @@ - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); - SetMenuRepeatDelay (MIN_ACCEL_DELAY, MAX_ACCEL_DELAY, STEP_ACCEL_DELAY, - TRUE); -+ TFB_SetOnScreenKeyboard_Starmap (); - DoInput (&MenuState, FALSE); -+ TFB_SetOnScreenKeyboard_Menu (); - SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); - SetDefaultMenuRepeatDelay (); - -Index: uqm/planets/lander.c -=================================================================== ---- uqm/planets/lander.c (revision 1353) -+++ uqm/planets/lander.c (working copy) -@@ -1852,15 +1852,15 @@ - if (crew_left) - { - SIZE index = GetFrameIndex (LanderFrame[0]); -+ BATTLE_INPUT_STATE InputState = GetDirectionalJoystickInput(index, 0); - if (turn_wait) - --turn_wait; -- else if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT] || -- CurrentInputState.key[PlayerControls[0]][KEY_RIGHT]) -+ else if ((InputState & BATTLE_LEFT) || (InputState & BATTLE_RIGHT)) - { - COUNT landerSpeedNumer; - COUNT angle; - -- if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT]) -+ if (InputState & BATTLE_LEFT) - --index; - else - ++index; -@@ -1884,7 +1884,7 @@ - turn_wait = SHUTTLE_TURN_WAIT; - } - -- if (!CurrentInputState.key[PlayerControls[0]][KEY_UP]) -+ if (!(InputState & BATTLE_THRUST)) - { - dx = 0; - dy = 0; -@@ -2212,7 +2212,9 @@ - landerInputState.Initialized = FALSE; - landerInputState.InputFunc = DoPlanetSide; - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); -+ TFB_SetOnScreenKeyboard_Melee (); - DoInput (&landerInputState, FALSE); -+ TFB_SetOnScreenKeyboard_Menu (); - - if (!(GLOBAL (CurrentActivity) & CHECK_ABORT)) - { -Index: uqm/supermelee/melee.c -=================================================================== ---- uqm/supermelee/melee.c (revision 1353) -+++ uqm/supermelee/melee.c (working copy) -@@ -2124,7 +2124,7 @@ - PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING; - Melee_LocalChange_team (&MenuState, 0, - MenuState.load.preBuiltList[0]); -- PlayerControl[1] = COMPUTER_CONTROL | STANDARD_RATING; -+ PlayerControl[1] = HUMAN_CONTROL | STANDARD_RATING; // COMPUTER_CONTROL | STANDARD_RATING; - Melee_LocalChange_team (&MenuState, 1, - MenuState.load.preBuiltList[1]); - } -Index: uqm/sis.c -=================================================================== ---- uqm/sis.c (revision 1353) -+++ uqm/sis.c (working copy) -@@ -1810,7 +1810,7 @@ - GetContextClipRect (&clip_r); - pRect = &temp_r; - temp_r.corner.x = RADAR_X - clip_r.corner.x; -- temp_r.corner.y = RADAR_Y - clip_r.corner.y; -+ temp_r.corner.y = RADAR_Y_LIFTED_UP - clip_r.corner.y; - temp_r.extent.width = RADAR_WIDTH; - temp_r.extent.height = RADAR_HEIGHT; - SetContext (ScreenContext); -Index: uqm/hyper.c -=================================================================== ---- uqm/hyper.c (revision 1353) -+++ uqm/hyper.c (working copy) -@@ -1930,7 +1930,6 @@ - Color OldColor; - CONTEXT OldContext; - MENU_STATE MenuState; -- - UnbatchGraphics (); - - OldContext = SetContext (SpaceContext); -Index: uqm/intro.c -=================================================================== ---- uqm/intro.c (revision 1353) -+++ uqm/intro.c (working copy) -@@ -35,7 +35,7 @@ - - #include - --static BOOLEAN ShowSlidePresentation (STRING PresStr); -+static BOOLEAN ShowSlidePresentation (STRING PresStr, RESOURCE PresName, BOOLEAN NoMusic); - - typedef struct - { -@@ -52,6 +52,7 @@ - FONT Fonts[MAX_FONTS]; - FRAME Frame; - MUSIC_REF MusicRef; -+ BOOLEAN MusicOverride; - BOOLEAN Batched; - FRAME SisFrame; - FRAME RotatedFrame; -@@ -285,10 +286,10 @@ - } - - static BOOLEAN --ShowPresentationFile (const char *name) -+ShowPresentationFile (const char *name, BOOLEAN NoMusic) - { - STRING pres = CaptureStringTable (LoadStringTableFile (contentDir, name)); -- BOOLEAN result = ShowSlidePresentation (pres); -+ BOOLEAN result = ShowSlidePresentation (pres, "", NoMusic); - DestroyStringTable (ReleaseStringTable (pres)); - return result; - } -@@ -518,14 +519,17 @@ - } - else if (strcmp (Opcode, "MUSIC") == 0) - { /* set music */ -- utf8StringCopy (pPIS->Buffer, sizeof (pPIS->Buffer), pStr); -- if (pPIS->MusicRef) -+ if (!pPIS->MusicOverride) - { -- StopMusic (); -- DestroyMusic (pPIS->MusicRef); -+ utf8StringCopy (pPIS->Buffer, sizeof (pPIS->Buffer), pStr); -+ if (pPIS->MusicRef) -+ { -+ StopMusic (); -+ DestroyMusic (pPIS->MusicRef); -+ } -+ pPIS->MusicRef = LoadMusicFile (pPIS->Buffer); -+ PlayMusic (pPIS->MusicRef, FALSE, 1); - } -- pPIS->MusicRef = LoadMusicFile (pPIS->Buffer); -- PlayMusic (pPIS->MusicRef, FALSE, 1); - } - else if (strcmp (Opcode, "WAIT") == 0) - { /* wait */ -@@ -817,7 +821,7 @@ - Present_UnbatchGraphics (pPIS, TRUE); - - utf8StringCopy (pPIS->Buffer, sizeof (pPIS->Buffer), pStr); -- ShowPresentationFile (pPIS->Buffer); -+ ShowPresentationFile (pPIS->Buffer, pPIS->MusicOverride); - } - else if (strcmp (Opcode, "LINE") == 0) - { -@@ -880,12 +884,13 @@ - } - - static BOOLEAN --ShowSlidePresentation (STRING PresStr) -+ShowSlidePresentation (STRING PresStr, RESOURCE PresName, BOOLEAN NoMusic) - { - CONTEXT OldContext; - FONT OldFont; - RECT OldRect; - PRESENTATION_INPUT_STATE pis; -+ char MusicOverrideRes[256]; - int i; - - memset (&pis, 0, sizeof(pis)); -@@ -901,6 +906,24 @@ - OldFont = SetContextFont (NULL); - SetContextBackGroundColor (BLACK_COLOR); - UnlockMutex (GraphicsLock); -+ /* Override intro and ending music with Precursors remix, if it's available */ -+ pis.MusicOverride = NoMusic; -+ if (!NoMusic && strlen(PresName) < sizeof(MusicOverrideRes) - 10) -+ { -+ const char *ResType; -+ strcpy (MusicOverrideRes, PresName); -+ strcat (MusicOverrideRes, ".music"); -+ ResType = res_GetResourceType (MusicOverrideRes); -+ if (strcmp(ResType, "MUSICRES") == 0) -+ { -+ pis.MusicRef = LoadMusic (MusicOverrideRes); -+ if (pis.MusicRef) -+ { -+ pis.MusicOverride = TRUE; -+ PlayMusic (pis.MusicRef, FALSE, 1); -+ } -+ } -+ } - - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); - pis.InputFunc = DoPresentation; -@@ -909,7 +932,9 @@ - pis.MovieFrame = -1; - pis.StartTime = GetTimeCounter (); - pis.LastSyncTime = pis.StartTime; -+ TFB_SetOnScreenKeyboard_Hidden (); - DoInput (&pis, TRUE); -+ TFB_SetOnScreenKeyboard_Menu(); - - SleepThreadUntil (FadeMusic (0, ONE_SECOND)); - StopMusic (); -@@ -1001,7 +1026,9 @@ - vis.InputFunc = DoVideoInput; - vis.CurVideo = ref; - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); -+ TFB_SetOnScreenKeyboard_Hidden (); - DoInput (&vis, TRUE); -+ TFB_SetOnScreenKeyboard_Menu (); - - StopLegacyVideo (ref); - FadeClearScreen (); -@@ -1017,10 +1044,11 @@ - { - return FALSE; - } -+ - if (!strcmp (resType, "STRTAB")) - { - STRING pres = CaptureStringTable (LoadStringTable (res)); -- BOOLEAN result = ShowSlidePresentation (pres); -+ BOOLEAN result = ShowSlidePresentation (pres, res, FALSE); - DestroyStringTable (ReleaseStringTable (pres)); - return result; - } -Index: uqm/gameinp.c -=================================================================== ---- uqm/gameinp.c (revision 1353) -+++ uqm/gameinp.c (working copy) -@@ -16,6 +16,7 @@ - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -+#include - #include "controls.h" - #include "battlecontrols.h" - #include "init.h" -@@ -32,11 +33,14 @@ - #include "libs/timelib.h" - #include "libs/threadlib.h" - -- -+#ifdef ANDROID -+#define ACCELERATION_INCREMENT (ONE_SECOND) -+#define MENU_REPEAT_DELAY (ONE_SECOND) -+#else - #define ACCELERATION_INCREMENT (ONE_SECOND / 12) - #define MENU_REPEAT_DELAY (ONE_SECOND / 2) -+#endif - -- - typedef struct - { - BOOLEAN (*InputFunc) (void *pInputState); -@@ -66,6 +70,7 @@ - - volatile BOOLEAN ExitRequested; - volatile BOOLEAN GamePaused; -+volatile BOOLEAN OnScreenKeyboardLocked; - - static InputFrameCallback *inputCallback; - -@@ -422,16 +427,10 @@ - } - - static BATTLE_INPUT_STATE --ControlInputToBattleInput (const int *keyState) -+ControlInputToBattleInput (const int *keyState, COUNT player, int direction) - { - BATTLE_INPUT_STATE InputState = 0; - -- if (keyState[KEY_UP]) -- InputState |= BATTLE_THRUST; -- if (keyState[KEY_LEFT]) -- InputState |= BATTLE_LEFT; -- if (keyState[KEY_RIGHT]) -- InputState |= BATTLE_RIGHT; - if (keyState[KEY_WEAPON]) - InputState |= BATTLE_WEAPON; - if (keyState[KEY_SPECIAL]) -@@ -441,21 +440,35 @@ - if (keyState[KEY_DOWN]) - InputState |= BATTLE_DOWN; - -+ if(direction < 0) -+ { -+ if (keyState[KEY_LEFT]) -+ InputState |= BATTLE_LEFT; -+ if (keyState[KEY_RIGHT]) -+ InputState |= BATTLE_RIGHT; -+ if (keyState[KEY_UP]) -+ InputState |= BATTLE_THRUST; -+ } -+ else -+ { -+ InputState |= GetDirectionalJoystickInput(direction, player); -+ } -+ - return InputState; - } - - BATTLE_INPUT_STATE --CurrentInputToBattleInput (COUNT player) -+CurrentInputToBattleInput (COUNT player, int direction) - { - return ControlInputToBattleInput( -- CurrentInputState.key[PlayerControls[player]]); -+ CurrentInputState.key[PlayerControls[player]], player, direction); - } - - BATTLE_INPUT_STATE - PulsedInputToBattleInput (COUNT player) - { - return ControlInputToBattleInput( -- PulsedInputState.key[PlayerControls[player]]); -+ PulsedInputState.key[PlayerControls[player]], player, -1); - } - - BOOLEAN -@@ -500,3 +513,144 @@ - return result; - } - -+// Fast arctan2, returns angle in radians as integer, with fractional part in lower 16 bits -+// Stolen from http://www.dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization , precision is said to be 0.07 rads -+ -+#ifndef M_PI -+#define M_PI 3.14159265358979323846 -+#endif -+enum { atan2i_coeff_1 = ((int)(M_PI*65536.0/4)), atan2i_coeff_2 = (3*atan2i_coeff_1), atan2i_PI = (int)(M_PI * 65536.0), SHIP_DIRECTIONS = 16 }; -+ -+static inline int atan2i(int y, int x) -+{ -+ int angle; -+ int abs_y = abs(y); -+ if( abs_y == 0 ) -+ abs_y = 1; -+ if (x>=0) -+ { -+ angle = atan2i_coeff_1 - atan2i_coeff_1 * (x - abs_y) / (x + abs_y); -+ } -+ else -+ { -+ angle = atan2i_coeff_2 - atan2i_coeff_1 * (x + abs_y) / (abs_y - x); -+ } -+ if (y < 0) -+ return(-angle); // negate if in quad III or IV -+ else -+ return(angle); -+} -+ -+BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction, int player) -+{ -+ BATTLE_INPUT_STATE InputState = 0; -+ static BOOLEAN JoystickThrust[NUM_PLAYERS] = { FALSE, FALSE }; -+ static BOOLEAN JoystickTapFlag[NUM_PLAYERS] = { FALSE, FALSE }; -+ static TimeCount JoystickTapTime[NUM_PLAYERS] = { 0, 0 }; -+ -+ if (CurrentInputState.key[PlayerControls[player]][KEY_THRUST]) -+ InputState |= BATTLE_THRUST; -+ -+ if( VControl_GetJoysticksAmount() <= 0 ) -+ { -+ if (CurrentInputState.key[PlayerControls[player]][KEY_LEFT]) -+ InputState |= BATTLE_LEFT; -+ if (CurrentInputState.key[PlayerControls[player]][KEY_RIGHT]) -+ InputState |= BATTLE_RIGHT; -+ if (CurrentInputState.key[PlayerControls[player]][KEY_UP]) -+ InputState |= BATTLE_THRUST; -+ return InputState; -+ } -+ -+ int axisX = VControl_GetJoyAxis(0, player * 2), axisY = VControl_GetJoyAxis(0, player * 2 + 1); -+ -+ if( axisX == 0 && axisY == 0 ) -+ { -+ // Some basic gamepad input support -+ axisX = VControl_GetJoyAxis(2, player * 2); -+ axisY = VControl_GetJoyAxis(2, player * 2 + 1); -+ if( abs( axisX ) > 5000 || abs( axisY ) > 5000 ) // Deadspot at the center -+ { -+ JoystickTapFlag[player] = TRUE; -+ JoystickThrust[player] = FALSE; -+ // Turning thrust with joystick is uncomfortable -+ //if( abs( axisX ) > 25000 || abs( axisY ) > 25000 ) -+ // JoystickThrust[player] = TRUE; -+ } -+ else -+ { -+ axisX = 0; -+ axisY = 0; -+ } -+ } -+ -+ if( axisX == 0 && axisY == 0 ) -+ { -+ // Process keyboard input only when joystick is not used -+ if (CurrentInputState.key[PlayerControls[player]][KEY_LEFT]) -+ InputState |= BATTLE_LEFT; -+ if (CurrentInputState.key[PlayerControls[player]][KEY_RIGHT]) -+ InputState |= BATTLE_RIGHT; -+ if (CurrentInputState.key[PlayerControls[player]][KEY_UP]) -+ InputState |= BATTLE_THRUST; -+ } -+ -+ if( !optDirectionalJoystick ) -+ { -+ if( player == 1 ) -+ { -+ axisX = - axisX; -+ axisY = - axisY; -+ } -+ if( axisX < -10000 ) -+ InputState |= BATTLE_LEFT; -+ if( axisX > 10000 ) -+ InputState |= BATTLE_RIGHT; -+ if( axisY < 0 ) -+ InputState |= BATTLE_THRUST; -+ return InputState; -+ } -+ -+ if( axisX != 0 || axisY != 0 ) -+ { -+ int angle = atan2i(axisY, axisX), diff; -+ // Convert it to 16 directions used by Melee -+ angle += atan2i_PI / SHIP_DIRECTIONS; -+ if( angle < 0 ) -+ angle += atan2i_PI * 2; -+ if( angle > atan2i_PI * 2 ) -+ angle -= atan2i_PI * 2; -+ angle = angle * SHIP_DIRECTIONS / atan2i_PI / 2; -+ -+ diff = angle - direction - SHIP_DIRECTIONS / 4; -+ while( diff >= SHIP_DIRECTIONS ) -+ diff -= SHIP_DIRECTIONS; -+ while( diff < 0 ) -+ diff += SHIP_DIRECTIONS; -+ -+ if( diff < SHIP_DIRECTIONS / 2 ) -+ InputState |= BATTLE_LEFT; -+ if( diff > SHIP_DIRECTIONS / 2 ) -+ InputState |= BATTLE_RIGHT; -+ -+ if( !JoystickTapFlag[player] ) -+ { -+ JoystickTapFlag[player] = TRUE; -+ if( GetTimeCounter() < JoystickTapTime[player] + ONE_SECOND ) -+ JoystickThrust[player] = !JoystickThrust[player]; -+ else -+ JoystickThrust[player] = TRUE; -+ } -+ if( JoystickThrust[player] ) -+ InputState |= BATTLE_THRUST; -+ } -+ else -+ { -+ if( JoystickTapFlag[player] ) -+ { -+ JoystickTapFlag[player] = FALSE; -+ JoystickTapTime[player] = GetTimeCounter(); -+ } -+ } -+ return InputState; -+} -Index: uqm/shipstat.c -=================================================================== ---- uqm/shipstat.c (revision 1353) -+++ uqm/shipstat.c (working copy) -@@ -144,6 +144,45 @@ - DrawFilledRectangle (&r); - } - -+static void -+DrawCrewEnergyBoxOutline (RECT *box) -+{ -+ RECT r; -+ -+ SetContextForeGroundColor ( -+ BUILD_COLOR (MAKE_RGB15 (0x10, 0x10, 0x10), 0x19)); -+ r.corner.x = box->corner.x; -+ r.corner.y = box->corner.y + box->extent.height - 1; -+ r.extent.width = box->extent.width; -+ r.extent.height = 1; -+ DrawFilledRectangle (&r); -+ r.corner.x = box->corner.x + box->extent.width - 1; -+ r.corner.y = box->corner.y; -+ r.extent.width = 1; -+ r.extent.height = box->extent.height; -+ DrawFilledRectangle (&r); -+ -+ SetContextForeGroundColor ( -+ BUILD_COLOR (MAKE_RGB15 (0x08, 0x08, 0x08), 0x1F)); -+ r.corner.x = box->corner.x; -+ r.corner.y = box->corner.y; -+ r.extent.width = box->extent.width; -+ r.extent.height = 1; -+ DrawFilledRectangle (&r); -+ r.corner.x = box->corner.x; -+ r.corner.y = box->corner.y; -+ r.extent.width = 1; -+ r.extent.height = box->extent.height; -+ DrawFilledRectangle (&r); -+ -+ SetContextForeGroundColor (BLACK_COLOR); -+ r.corner.x = box->corner.x + 1; -+ r.corner.y = box->corner.y + 1; -+ r.extent.width = box->extent.width - 2; -+ r.extent.height = box->extent.height - 2; -+ DrawFilledRectangle (&r); -+} -+ - void - InitShipStatus (SHIP_INFO *SIPtr, STARSHIP *StarShipPtr, RECT *pClipRect, BOOLEAN inMeleeMenu) - { -@@ -256,6 +295,28 @@ - r.extent.height = energy_height; - r.corner.y = y - r.extent.height + GAUGE_YOFFS + 1; - DrawFilledRectangle (&r); -+ -+ // TODO: replace the above ugly code with DrawCrewEnergyBoxOutline(), but I don't want to touch that as long as it works -+ r.corner.x = RESOLUTION_FACTOR == 2 ? 3 : RESOLUTION_FACTOR; -+ r.corner.y = BAD_GUY_HORIZ_CREW_YOFFS; -+ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) -+ r.corner.y = GOOD_GUY_HORIZ_CREW_YOFFS; -+ r.corner.y += RESOLUTION_FACTOR == 2 ? 3 : RESOLUTION_FACTOR; -+ r.extent.width = 1000; -+ r.extent.height = STAT_WIDTH + (2 << RESOLUTION_FACTOR); -+ SetContextForeGroundColor (BLACK_COLOR); -+ DrawFilledRectangle (&r); -+ r.extent.width = crew_height + (2 << RESOLUTION_FACTOR); -+ DrawCrewEnergyBoxOutline (&r); -+ r.corner.y = BAD_GUY_HORIZ_ENERGY_YOFFS; -+ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) -+ r.corner.y = GOOD_GUY_HORIZ_ENERGY_YOFFS; -+ r.corner.y += RESOLUTION_FACTOR == 2 ? 3 : RESOLUTION_FACTOR; -+ r.extent.width = 1000; -+ SetContextForeGroundColor (BLACK_COLOR); -+ DrawFilledRectangle (&r); -+ r.extent.width = energy_height + (2 << RESOLUTION_FACTOR); -+ DrawCrewEnergyBoxOutline (&r); - } - - if (!StarShipPtr || StarShipPtr->captains_name_index) -@@ -315,7 +376,7 @@ - // DeltaStatistics() below will add specified values to these - SIPtr->crew_level = 0; - SIPtr->energy_level = 0; -- DeltaStatistics (SIPtr, y, crew_delta, energy_delta); -+ DeltaStatistics (SIPtr, y, crew_delta, energy_delta, StarShipPtr ? StarShipPtr->playerNr : NPC_PLAYER_NUM); - } - - UnbatchGraphics (); -@@ -333,10 +394,11 @@ - // crew_delta <= ShipInfoPtr->max_crew - ShipInfoPtr->crew_level - void - DeltaStatistics (SHIP_INFO *ShipInfoPtr, COORD y_offs, -- SIZE crew_delta, SIZE energy_delta) -+ SIZE crew_delta, SIZE energy_delta, SIZE player_num) - { -- COORD x, y; -- RECT r; -+ COORD x, y, y2; -+ RECT r, r2; -+ SIZE max_crew_size, max_energy_size; - - if (crew_delta == 0 && energy_delta == 0) - return; -@@ -346,13 +408,15 @@ - - r.extent.width = UNIT_WIDTH; - r.extent.height = UNIT_HEIGHT; -+#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) -+ max_crew_size = MIN(ShipInfoPtr->max_crew, MAX_CREW_SIZE); -+ max_energy_size = ShipInfoPtr->max_energy; - - if (crew_delta != 0) - { - COUNT oldNumBlocks, newNumBlocks, blockI; - COUNT newCrewLevel; - --#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) - oldNumBlocks = MIN(ShipInfoPtr->crew_level, MAX_CREW_SIZE); - newCrewLevel = ShipInfoPtr->crew_level + crew_delta; - newNumBlocks = MIN(newCrewLevel, MAX_CREW_SIZE); -@@ -419,10 +483,33 @@ - // Always print a number for the SIS in the full game. - DrawBattleCrewAmount (ShipInfoPtr, y_offs); - } -+ -+ y2 = BAD_GUY_HORIZ_CREW_YOFFS; -+ if (player_num == RPG_PLAYER_NUM) -+ y2 = GOOD_GUY_HORIZ_CREW_YOFFS; -+ -+ r2.extent.height = UNIT_WIDTH; -+ r2.extent.width = UNIT_HEIGHT; -+ -+ for (blockI = 0; blockI < max_crew_size; blockI++) -+ { -+ SetContextForeGroundColor ( -+ (ShipInfoPtr->ship_flags & CREW_IMMUNE) ? -+ ROBOT_UNIT_COLOR : CREW_UNIT_COLOR); -+ if (blockI >= newNumBlocks) -+ SetContextForeGroundColor (BLACK_COLOR); -+ -+ r2.corner.x = HORIZ_CREW_XOFFS + (blockI >> 1) * (UNIT_HEIGHT + 1); -+ r2.corner.y = y2 + HORIZ_CREW_XOFFS; -+ if (blockI & 1) -+ r2.corner.y += UNIT_WIDTH + 1; -+ DrawFilledRectangle (&r2); -+ } - } - - if (energy_delta != 0) - { -+ COUNT blockI; - if (energy_delta > 0) - { - #define FUEL_UNIT_COLOR BUILD_COLOR (MAKE_RGB15 (0x14, 0x00, 0x00), 0x04) -@@ -458,6 +545,26 @@ - --ShipInfoPtr->energy_level; - } while (++energy_delta); - } -+ -+ y2 = BAD_GUY_HORIZ_ENERGY_YOFFS; -+ if (player_num == RPG_PLAYER_NUM) -+ y2 = GOOD_GUY_HORIZ_ENERGY_YOFFS; -+ -+ r2.extent.height = UNIT_WIDTH; -+ r2.extent.width = UNIT_HEIGHT; -+ -+ for (blockI = 0; blockI < max_energy_size; blockI++) -+ { -+ SetContextForeGroundColor (FUEL_UNIT_COLOR); -+ if (blockI >= ShipInfoPtr->energy_level) -+ SetContextForeGroundColor (BLACK_COLOR); -+ -+ r2.corner.x = HORIZ_CREW_XOFFS + (blockI >> 1) * (UNIT_HEIGHT + 1); -+ r2.corner.y = y2 + HORIZ_CREW_XOFFS; -+ if (blockI & 1) -+ r2.corner.y += UNIT_WIDTH + 1; -+ DrawFilledRectangle (&r2); -+ } - } - } - -Index: uqm/intel.c -=================================================================== ---- uqm/intel.c (revision 1353) -+++ uqm/intel.c (working copy) -@@ -45,10 +45,10 @@ - // Allow a player to warp-escape in cyborg mode - if (StarShipPtr->playerNr == RPG_PLAYER_NUM) - InputState |= CurrentInputToBattleInput ( -- context->playerNr) & BATTLE_ESCAPE; -+ context->playerNr, -1) & BATTLE_ESCAPE; - } - else -- InputState = CurrentInputToBattleInput (context->playerNr); -+ InputState = CurrentInputToBattleInput (context->playerNr, -1); - } - else if (!(PlayerControl[context->playerNr] & PSYTRON_CONTROL)) - InputState = 0; -Index: uqm/battle.c -=================================================================== ---- uqm/battle.c (revision 1353) -+++ uqm/battle.c (working copy) -@@ -16,6 +16,10 @@ - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -+#ifdef ANDROID -+#include -+#endif -+ - #include "battle.h" - - #include "battlecontrols.h" -@@ -43,6 +47,8 @@ - #include "libs/graphics/gfx_common.h" - #include "libs/log.h" - #include "libs/mathlib.h" -+#include "globdata.h" -+#include "libs/input/sdl/vcontrol.h" - - - BYTE battle_counter[NUM_SIDES]; -@@ -137,7 +143,8 @@ - frameInputHuman (HumanInputContext *context, STARSHIP *StarShipPtr) - { - (void) StarShipPtr; -- return CurrentInputToBattleInput (context->playerNr); -+ -+ return CurrentInputToBattleInput (context->playerNr, StarShipPtr ? StarShipPtr->ShipFacing : -1); - } - - static void -@@ -207,8 +214,11 @@ - StarShipPtr->ship_input_state |= SPECIAL; - - if (CanRunAway && cur_player == 0 && -- (InputState & BATTLE_ESCAPE)) -+ ((InputState & BATTLE_ESCAPE) || EmergencyEscapeWarpUnitActivatedFromMenu)) -+ { -+ EmergencyEscapeWarpUnitActivatedFromMenu = FALSE; - DoRunAway (StarShipPtr); -+ } - } - } - -@@ -399,6 +409,11 @@ - - LockMutex (GraphicsLock); - -+ TFB_SetOnScreenKeyboard_Melee (); -+ if (PlayerControl[1] & HUMAN_CONTROL) { -+ TFB_SetOnScreenKeyboard_TwoPlayersMelee (); -+ } -+ - #if !(DEMO_MODE || CREATE_JOURNAL) - if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) { - // In Supermelee, the RNG is already initialised. -@@ -512,6 +527,8 @@ - UninitShips (); - FreeBattleSong (); - -+ TFB_SetOnScreenKeyboard_Menu (); -+ - UnlockMutex (GraphicsLock); - - return (BOOLEAN) (num_ships < 0); -Index: uqm/setupmenu.c -=================================================================== ---- uqm/setupmenu.c (revision 1353) -+++ uqm/setupmenu.c (working copy) -@@ -83,7 +83,7 @@ - #endif - - #define MENU_COUNT 8 --#define CHOICE_COUNT 29 // JMS: New options added. -+#define CHOICE_COUNT 30 // JMS: New options added. - #define SLIDER_COUNT 3 - #define BUTTON_COUNT 10 - #define LABEL_COUNT 4 -@@ -106,7 +106,7 @@ - static int choice_widths[CHOICE_COUNT] = { - 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 3, 3, 2, 3, 3, -- 3, 2, 3, 2, 2, 2, 2, 2, 2 }; -+ 3, 2, 3, 2, 2, 2, 2, 2, 2, 2 }; - - static HANDLER button_handlers[BUTTON_COUNT] = { - quit_main_menu, quit_sub_menu, do_graphics, do_engine, -@@ -117,7 +117,7 @@ - // JMS: The first 8 was 7 (sound options.) Added mainmenumusic on/off. - // JMS: The HAVE_OPENGL options were 5 and 4. Added cheatMode, mineralSubmenu, nebulae and planet options. - static int menu_sizes[MENU_COUNT] = { -- 7, 6, 8, 8, 2, 5, -+ 7, 6, 8, 8, 2, 6, - #ifdef HAVE_OPENGL - 10, - #else -@@ -185,6 +185,7 @@ - static WIDGET *keyconfig_widgets[] = { - (WIDGET *)(&choices[18]), - (WIDGET *)(&choices[19]), -+ (WIDGET *)(&choices[29]), // Directional joystick - (WIDGET *)(&labels[1]), - (WIDGET *)(&buttons[8]), - (WIDGET *)(&buttons[1]) }; -@@ -293,6 +294,8 @@ - if (event == WIDGET_EVENT_SELECT) - { - next = (WIDGET *)(&menus[5]); -+ if (getenv("OUYA")) -+ next = (WIDGET *)(&menus[4]); - (*next->receiveFocus) (next, WIDGET_EVENT_DOWN); - return TRUE; - } -@@ -414,6 +417,7 @@ - choices[26].selected = opts.rotatingIpPlanets; // JMS - choices[27].selected = opts.texturedIpPlanets || opts.rotatingIpPlanets; // JMS - choices[28].selected = opts.cheatMode; // JMS -+ choices[29].selected = opts.directionalJoystick; - - sliders[0].value = opts.musicvol; - sliders[1].value = opts.sfxvol; -@@ -452,6 +456,7 @@ - opts.rotatingIpPlanets = choices[26].selected; // JMS - opts.texturedIpPlanets = choices[27].selected || opts.rotatingIpPlanets; // JMS - opts.cheatMode = choices[28].selected; // JMS -+ opts.directionalJoystick = choices[29].selected; - - opts.musicvol = sliders[0].value; - opts.sfxvol = sliders[1].value; -@@ -1164,6 +1169,7 @@ - opts->rotatingIpPlanets = optRotatingIpPlanets ? OPTVAL_ENABLED : OPTVAL_DISABLED; - opts->texturedIpPlanets = (optTexturedIpPlanets ? OPTVAL_ENABLED : OPTVAL_DISABLED) || opts->rotatingIpPlanets; - opts->cheatMode = optCheatMode ? OPTVAL_ENABLED : OPTVAL_DISABLED; -+ opts->directionalJoystick = optDirectionalJoystick ? OPTVAL_ENABLED : OPTVAL_DISABLED; - - /* Work out resolution. On the way, try to guess a good default - * for config.alwaysgl, then overwrite it if it was set previously. */ -@@ -1376,6 +1382,9 @@ - res_PutBoolean ("config.cheatMode", opts->cheatMode == OPTVAL_ENABLED); - optCheatMode = opts->cheatMode == OPTVAL_ENABLED; - -+ res_PutBoolean ("config.directionaljoystick", opts->directionalJoystick == OPTVAL_ENABLED); -+ optDirectionalJoystick = (opts->directionalJoystick == OPTVAL_ENABLED) ? TRUE : FALSE; -+ - if (NewWidth == 320 && NewHeight == 240) - { - switch (opts->scaler) -Index: uqm/setupmenu.h -=================================================================== ---- uqm/setupmenu.h (revision 1353) -+++ uqm/setupmenu.h (working copy) -@@ -86,7 +86,7 @@ - OPT_CONSOLETYPE menu, text, cscan, scroll, intro, meleezoom, shield; - CONTROL_TEMPLATE player1, player2; - int speechvol, musicvol, sfxvol; -- BOOLEAN mainmenuMusic, mineralSubmenu, nebulae, rotatingIpPlanets, texturedIpPlanets, cheatMode; // JMS -+ BOOLEAN mainmenuMusic, mineralSubmenu, nebulae, rotatingIpPlanets, texturedIpPlanets, cheatMode, directionalJoystick; // JMS - } GLOBALOPTS; - - void SetupMenu (void); -Index: uqm/confirm.c -=================================================================== ---- uqm/confirm.c (revision 1353) -+++ uqm/confirm.c (working copy) -@@ -34,9 +34,11 @@ - #include - - --#define CONFIRM_WIN_WIDTH (80 << RESOLUTION_FACTOR) // JMS_GFX -+#define CONFIRM_WIN_WIDTH (160 << RESOLUTION_FACTOR) // JMS_GFX - #define CONFIRM_WIN_HEIGHT (22 << RESOLUTION_FACTOR) // JMS_GFX - -+BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu = FALSE; -+ - static void - DrawConfirmationWindow (BOOLEAN answer) - { -@@ -67,6 +69,8 @@ - font_DrawText (&t); - t.baseline.x += (r.extent.width >> 1); - t.pStr = GAME_STRING (QUITMENU_STRING_BASE + 2); // "No" -+ if (GLOBAL (CurrentActivity) & IN_BATTLE) -+ t.pStr = "Escape unit"; // GAME_STRING (QUITMENU_STRING_BASE + 3); // TODO: modify gamestrings.txt - SetContextForeGroundColor (answer ? MENU_TEXT_COLOR : MENU_HIGHLIGHT_COLOR); - font_DrawText (&t); - -@@ -111,8 +115,16 @@ - - FlushInput (); - done = FALSE; -+ -+ #ifdef ANDROID -+ if ( !(GLOBAL (CurrentActivity) & IN_BATTLE) ) { -+ /* Abort immediately */ -+ response = TRUE; -+ done = TRUE; -+ } -+ #endif - -- do { -+ while (!done) { - // Forbid recursive calls or pausing here! - ExitRequested = FALSE; - GamePaused = FALSE; -@@ -139,7 +151,7 @@ - PlayMenuSound (MENU_SOUND_MOVE); - } - SleepThread (ONE_SECOND / 30); -- } while (!done); -+ } - - // Restore the screen under the confirmation window - DrawStamp (&s); -@@ -152,6 +164,8 @@ - } - else - { -+ if (GLOBAL (CurrentActivity) & IN_BATTLE) -+ EmergencyEscapeWarpUnitActivatedFromMenu = TRUE; - result = FALSE; - } - ExitRequested = FALSE; -Index: uqm/outfit.c -=================================================================== ---- uqm/outfit.c (revision 1353) -+++ uqm/outfit.c (working copy) -@@ -59,7 +59,7 @@ - OldContext = SetContext (StatusContext); - GetContextClipRect (&r); - s.origin.x = RADAR_X - r.corner.x; -- s.origin.y = RADAR_Y - r.corner.y - 19 * RESOLUTION_FACTOR; // JMS_GFX; -+ s.origin.y = RADAR_Y_LIFTED_UP - r.corner.y + RES_CASE(10,6,12); // JMS_GFX; - r.corner.x = s.origin.x - 1; - r.corner.y = s.origin.y - 11; - r.extent.width = RADAR_WIDTH + 2; -Index: uqm/getchar.c -=================================================================== ---- uqm/getchar.c (revision 1353) -+++ uqm/getchar.c (working copy) -@@ -27,7 +27,11 @@ - #include "resinst.h" - #include "nameref.h" - -+#ifdef __ANDROID__ -+#include -+#endif - -+ - // TODO: This may be better done with UniChar at the cost of a tiny bit - // of overhead to convert UniChar back to UTF8 string. This overhead - // will probably be offset by removal of looped string-compare overhead ;) -@@ -141,6 +145,11 @@ - { // init basic vars - int lwlen; - -+#ifdef __ANDROID__ -+ SDL_ANDROID_ToggleScreenKeyboardTextInput (pTES->BaseStr); -+ pTES->BaseStr[0] = 0; -+#endif -+ - pTES->InputFunc = DoTextEntry; - pTES->Success = FALSE; - pTES->Initialized = TRUE; -@@ -198,7 +207,6 @@ - CacheInsPt = pTES->InsPt; - CacheCursorPos = pTES->CursorPos; - memcpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize); -- - // process the pending character buffer - ch = GetNextCharacter (); - if (!ch && PulsedInputState.menu[KEY_MENU_ANY]) -Index: uqm/globdata.c -=================================================================== ---- uqm/globdata.c (revision 1353) -+++ uqm/globdata.c (working copy) -@@ -130,7 +130,7 @@ - OldContext = SetContext (RadarContext); - SetContextFGFrame (Screen); - r.corner.x = RADAR_X; -- r.corner.y = RADAR_Y; -+ r.corner.y = RADAR_Y_LIFTED_UP; - r.extent.width = RADAR_WIDTH; - r.extent.height = RADAR_HEIGHT; - SetContextClipRect (&r); -Index: uqm/status.c -=================================================================== ---- uqm/status.c (revision 1353) -+++ uqm/status.c (working copy) -@@ -328,7 +328,7 @@ - StarShipPtr->RaceDescPtr->characteristics.energy_wait; - - DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], -- 0, energy_delta); -+ 0, energy_delta, StarShipPtr->playerNr); - } - - return (retval); -@@ -370,7 +370,7 @@ - } - - DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], -- crew_delta, 0); -+ crew_delta, 0, StarShipPtr->playerNr); - - return (retval); - } -Index: uqm/shipyard.c -=================================================================== ---- uqm/shipyard.c (revision 1353) -+++ uqm/shipyard.c (working copy) -@@ -212,9 +212,9 @@ - OldContext = SetContext (StatusContext); - GetContextClipRect (&r); - s.origin.x = RADAR_X - r.corner.x; -- s.origin.y = RADAR_Y - r.corner.y; -+ s.origin.y = RADAR_Y_LIFTED_UP - r.corner.y; - r.corner.x = s.origin.x - 1; -- r.corner.y = s.origin.y - RES_CASE(11,24,33); // JMS_GFX -+ r.corner.y = s.origin.y - RES_CASE(1,2,3); // JMS_GFX - r.extent.width = RADAR_WIDTH + 2; - r.extent.height = RES_CASE(11,24,33); // JMS_GFX - BatchGraphics (); -@@ -242,8 +242,6 @@ - hStarShip = GetAvailableRaceFromIndex (NewRaceItem); - NewRaceItem = GetIndexFromStarShip (&GLOBAL (avail_race_q), - hStarShip); -- s.frame = SetAbsFrameIndex (pMS->ModuleFrame, 3 + NewRaceItem); -- DrawStamp (&s); - FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); - s.frame = FleetPtr->melee_icon; - UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); -@@ -253,6 +251,12 @@ - s.origin.x += (RADAR_WIDTH >> 1); - s.origin.y += (RADAR_HEIGHT >> 1); - DrawStamp (&s); -+ // Draw the ship name, above the ship image. -+ s.origin.x -= (RADAR_WIDTH >> 1); -+ s.origin.y -= (RADAR_HEIGHT >> 2); -+ s.frame = SetAbsFrameIndex (pMS->ModuleFrame, 3 + NewRaceItem); -+ DrawStamp (&s); -+ - t.align = ALIGN_RIGHT; - t.CharCount = (COUNT)~0; - t.pStr = buf; -Index: uqm/status.h -=================================================================== ---- uqm/status.h (revision 1353) -+++ uqm/status.h (working copy) -@@ -36,9 +36,15 @@ - #define CAPTAIN_HEIGHT RES_STAT_SCALE(30) // JMS_GFX - #define CAPTAIN_XOFFS ((STATUS_WIDTH - CAPTAIN_WIDTH) >> 1) // JMS_GFX - #define CAPTAIN_YOFFS (SHIP_INFO_HEIGHT + (4 << RESOLUTION_FACTOR)) // JMS_GFX --#define SHIP_STATUS_HEIGHT (STATUS_HEIGHT >> 1) --#define BAD_GUY_YOFFS 0 --#define GOOD_GUY_YOFFS SHIP_STATUS_HEIGHT -+#define SHIP_STATUS_HEIGHT ((STATUS_HEIGHT >> 1) - (17 << RESOLUTION_FACTOR)) -+#define BAD_GUY_YOFFS (-1 << RESOLUTION_FACTOR) -+#define GOOD_GUY_YOFFS (STATUS_HEIGHT - SHIP_STATUS_HEIGHT) -+#define HORIZ_CREW_ENERGY_SIZE (18 << RESOLUTION_FACTOR) -+#define HORIZ_CREW_XOFFS (2 << RESOLUTION_FACTOR) -+#define BAD_GUY_HORIZ_CREW_YOFFS (BAD_GUY_YOFFS + SHIP_STATUS_HEIGHT + (HORIZ_CREW_ENERGY_SIZE >> 1)) -+#define GOOD_GUY_HORIZ_CREW_YOFFS (GOOD_GUY_YOFFS - HORIZ_CREW_ENERGY_SIZE + (1 << RESOLUTION_FACTOR)) -+#define BAD_GUY_HORIZ_ENERGY_YOFFS (BAD_GUY_YOFFS + SHIP_STATUS_HEIGHT) -+#define GOOD_GUY_HORIZ_ENERGY_YOFFS (GOOD_GUY_YOFFS - (HORIZ_CREW_ENERGY_SIZE >> 1) + (1 << RESOLUTION_FACTOR)) - #define STARCON_TEXT_HEIGHT (7 << RESOLUTION_FACTOR) // JMS_GFX - #define TINY_TEXT_HEIGHT (9 << RESOLUTION_FACTOR) // JMS_GFX - #define BATTLE_CREW_X RES_STAT_SCALE(10) // JMS_GFX -@@ -54,7 +60,7 @@ - extern void InitShipStatus (SHIP_INFO *ShipInfoPtr, STARSHIP *StarShipPtr, RECT *pClipRect, BOOLEAN inMeleeMenu); - // StarShipPtr or pClipRect can be NULL - extern void DeltaStatistics (SHIP_INFO *ShipInfoPtr, COORD y_offs, -- SIZE crew_delta, SIZE energy_delta); -+ SIZE crew_delta, SIZE energy_delta, SIZE player_num); - extern void DrawBattleCrewAmount (SHIP_INFO *ShipInfoPtr, COORD y_offs); - - extern void DrawCaptainsWindow (STARSHIP *StarShipPtr); -Index: uqm/starcon.c -=================================================================== ---- uqm/starcon.c (revision 1353) -+++ uqm/starcon.c (working copy) -@@ -240,6 +240,7 @@ - if (LastActivity == (CHECK_LOAD | CHECK_RESTART)) - AskNameForCaptainAndShip(); - -+ TFB_SetOnScreenKeyboard_Melee (); - do - { - #ifdef DEBUG -Index: options.c -=================================================================== ---- options.c (revision 1353) -+++ options.c (working copy) -@@ -67,6 +67,7 @@ - BOOLEAN optRotatingIpPlanets; - BOOLEAN optTexturedIpPlanets; - BOOLEAN optCheatMode; -+BOOLEAN optDirectionalJoystick; - - BOOLEAN opt3doMusic; - BOOLEAN optRemixMusic; -@@ -480,6 +481,7 @@ - - for (i = 0; i < dirList->numNames; i++) - { -+ log_add (log_Info, "Mounting ZIP '%s'", dirList->names[i]); - if (uio_mountDir (repository, mountPoint, uio_FSTYPE_ZIP, - dirHandle, dirList->names[i], "/", autoMount, - relativeFlags | uio_MOUNT_RDONLY, -Index: options.h -=================================================================== ---- options.h (revision 1353) -+++ options.h (working copy) -@@ -54,6 +54,7 @@ - extern BOOLEAN optRotatingIpPlanets; - extern BOOLEAN optTexturedIpPlanets; - extern BOOLEAN optCheatMode; -+extern BOOLEAN optDirectionalJoystick; - - extern BOOLEAN opt3doMusic; - extern BOOLEAN optRemixMusic; -Index: uqm.c -=================================================================== ---- uqm.c (revision 1353) -+++ uqm.c (working copy) -@@ -63,6 +63,20 @@ - // Including this is actually necessary on OSX. - #endif - -+#if defined (__ANDROID__) -+# include -+static void AndroidAppPutToBackgroundCallback (void) -+{ -+ SDL_ANDROID_PauseAudioPlayback (); -+ GameActive = FALSE; -+} -+static void SDLCALL AndroidAppRestoredCallback (void) -+{ -+ SDL_ANDROID_ResumeAudioPlayback (); -+ GameActive = TRUE; -+} -+#endif -+ - struct bool_option - { - bool value; -@@ -138,6 +152,7 @@ - DECL_CONFIG_OPTION(bool, rotatingIpPlanets); // JMS - DECL_CONFIG_OPTION(bool, texturedIpPlanets); // JMS - DECL_CONFIG_OPTION(bool, cheatMode); // JMS -+ DECL_CONFIG_OPTION(bool, directionalJoystick); - - #define INIT_CONFIG_OPTION(name, val) \ - { val, false } -@@ -256,8 +271,8 @@ - INIT_CONFIG_OPTION( gamma, 0.0f ), - INIT_CONFIG_OPTION( soundDriver, audio_DRIVER_MIXSDL ), - INIT_CONFIG_OPTION( soundQuality, audio_QUALITY_MEDIUM ), -- INIT_CONFIG_OPTION( use3doMusic, true ), -- INIT_CONFIG_OPTION( useRemixMusic, false ), -+ INIT_CONFIG_OPTION( use3doMusic, false ), -+ INIT_CONFIG_OPTION( useRemixMusic, true ), - INIT_CONFIG_OPTION( whichCoarseScan, OPT_PC ), - INIT_CONFIG_OPTION( whichMenu, OPT_PC ), - INIT_CONFIG_OPTION( whichFonts, OPT_PC ), -@@ -269,17 +284,18 @@ - INIT_CONFIG_OPTION( stereoSFX, false ), - INIT_CONFIG_OPTION( musicVolumeScale, 1.0f ), - INIT_CONFIG_OPTION( sfxVolumeScale, 1.0f ), -- INIT_CONFIG_OPTION( speechVolumeScale, 0.3f ), -+ INIT_CONFIG_OPTION( speechVolumeScale, 0.7f ), - INIT_CONFIG_OPTION( safeMode, false ), -- INIT_CONFIG_OPTION( resolutionFactor, 2 ), -+ INIT_CONFIG_OPTION( resolutionFactor, 1 ), - INIT_CONFIG_OPTION( forceAspectRatio, false ), - INIT_CONFIG_OPTION( loresBlowupScale, 0 ), - INIT_CONFIG_OPTION( mainmenuMusic, true ), -- INIT_CONFIG_OPTION( mineralSubmenu, true ), -+ INIT_CONFIG_OPTION( mineralSubmenu, false ), - INIT_CONFIG_OPTION( nebulae, true ), - INIT_CONFIG_OPTION( rotatingIpPlanets, true), - INIT_CONFIG_OPTION( texturedIpPlanets, true), - INIT_CONFIG_OPTION( cheatMode, false ), -+ INIT_CONFIG_OPTION( directionalJoystick, true ), - }; - struct options_struct defaults = options; - int optionsResult; -@@ -346,6 +362,14 @@ - return optionsResult; - } - -+#if defined (ANDROID) -+ SDL_ANDROID_SetApplicationPutToBackgroundCallback (AndroidAppPutToBackgroundCallback, AndroidAppRestoredCallback); -+ if( !fileExists("config/save") ) { -+ // Copy savegames from UQM non-HD, I'm too lazy to do that properly. -+ system("SAVEDIR=`pwd`/config/save ; mkdir -p $SAVEDIR ; cd ../../../../app-data/com.sourceforge.sc2/config/save || exit 1 ; for f in * ; do cat $f > $SAVEDIR/$f ; done"); -+ } -+#endif -+ - TFB_PreInit (); - mem_init (); - InitThreadSystem (); -@@ -413,6 +437,7 @@ - optRotatingIpPlanets = options.rotatingIpPlanets.value; // JMS - optTexturedIpPlanets = options.texturedIpPlanets.value || optRotatingIpPlanets; // JMS - optCheatMode = options.cheatMode.value; // JMS -+ optDirectionalJoystick = options.directionalJoystick.value; - - prepareContentDir (options.contentDir, options.addonDir, argv[0]); - prepareMeleeDir (); -@@ -696,6 +721,7 @@ - getBoolConfigValue (&options->rotatingIpPlanets, "config.rotatingIpPlanets"); - getBoolConfigValue (&options->texturedIpPlanets, "config.texturedIpPlanets"); - getBoolConfigValue (&options->cheatMode, "config.cheatMode"); -+ getBoolConfigValue (&options->directionalJoystick, "config.directionaljoystick"); - - if (res_IsInteger ("config.player1control")) - { -Index: libs/strings/unicode.c -=================================================================== ---- libs/strings/unicode.c (revision 1353) -+++ libs/strings/unicode.c (working copy) -@@ -41,7 +41,8 @@ - // function. - UniChar - getCharFromString(const unsigned char **ptr) { -- UniChar result; -+ const unsigned char *origPtr = *ptr; -+ UniChar result, errData; - - if (**ptr < 0x80) { - // 0xxxxxxx, regular ASCII -@@ -121,7 +122,14 @@ - } - - err: -- log_add(log_Warning, "Warning: Invalid UTF8 sequence."); -+ errData = origPtr[0] * 0x1000000; -+ if (origPtr[0] && origPtr[1]) -+ errData &= origPtr[1] * 0x10000; -+ if (origPtr[0] && origPtr[1] && origPtr[2]) -+ errData &= origPtr[2] * 0x100; -+ if (origPtr[0] && origPtr[1] && origPtr[2] && origPtr[3]) -+ errData &= origPtr[3]; -+ log_add(log_Warning, "Warning: Invalid UTF8 sequence: result 0x%x last byte 0x%02x str 0x%08x %s", result, (unsigned)(**ptr), errData, origPtr); - - // Resynchronise (skip everything starting with 0x10xxxxxx): - resyncUTF8(ptr); -Index: libs/input/sdl/vcontrol.h -=================================================================== ---- libs/input/sdl/vcontrol.h (revision 1353) -+++ libs/input/sdl/vcontrol.h (working copy) -@@ -76,6 +76,9 @@ - void VControl_ProcessJoyAxis (int port, int axis, int value); - void VControl_ProcessJoyHat (int port, int which, Uint8 value); - -+int VControl_GetJoyAxis(int port, int axis); -+int VControl_GetJoysticksAmount(); -+ - /* Force the input into the blank state. For preventing "sticky" keys. */ - void VControl_ResetInput (void); +-#define MAX_FLIGHT_ALTERNATES 2 ++#define MAX_FLIGHT_ALTERNATES 3 + extern void TFB_SetInputVectors (volatile int menu[], int num_menu, + volatile int flight[], int num_templ, int num_flight); Index: libs/input/sdl/input.c =================================================================== --- libs/input/sdl/input.c (revision 1353) @@ -1887,19 +109,44 @@ Index: libs/input/sdl/vcontrol.c void VControl_ResetInput (void) { -Index: libs/input/input_common.h +Index: libs/input/sdl/vcontrol.h =================================================================== ---- libs/input/input_common.h (revision 1353) -+++ libs/input/input_common.h (working copy) -@@ -31,7 +31,7 @@ - extern int TFB_InitInput (int driver, int flags); - extern void TFB_UninitInput (void); +--- libs/input/sdl/vcontrol.h (revision 1353) ++++ libs/input/sdl/vcontrol.h (working copy) +@@ -76,6 +76,9 @@ + void VControl_ProcessJoyAxis (int port, int axis, int value); + void VControl_ProcessJoyHat (int port, int which, Uint8 value); --#define MAX_FLIGHT_ALTERNATES 2 -+#define MAX_FLIGHT_ALTERNATES 3 ++int VControl_GetJoyAxis(int port, int axis); ++int VControl_GetJoysticksAmount(); ++ + /* Force the input into the blank state. For preventing "sticky" keys. */ + void VControl_ResetInput (void); - extern void TFB_SetInputVectors (volatile int menu[], int num_menu, - volatile int flight[], int num_templ, int num_flight); +Index: libs/log/msgbox_stub.c +=================================================================== +--- libs/log/msgbox_stub.c (revision 1353) ++++ libs/log/msgbox_stub.c (working copy) +@@ -16,6 +16,9 @@ + + #include "msgbox.h" + #include "loginternal.h" ++#ifdef ANDROID ++#include ++#endif + + void + log_displayBox (const /*UTF-8*/char *title, int isError, +@@ -26,6 +29,9 @@ + // So just inform the user of our predicament + fprintf (streamOut, "Do not know how to display %s box\n", + isError ? "an error" : "a"); ++#ifdef ANDROID ++ __android_log_print( isError ? ANDROID_LOG_FATAL : ANDROID_LOG_INFO, "Ur-Quan Masters", "%s: %s", title, msg ); ++#endif + + // Suppress the compiler warnings in any case. + (void)title; Index: libs/log/uqmlog.c =================================================================== --- libs/log/uqmlog.c (revision 1353) @@ -1952,30 +199,6 @@ Index: libs/log/msgbox_win.c } - +#endif -Index: libs/log/msgbox_stub.c -=================================================================== ---- libs/log/msgbox_stub.c (revision 1353) -+++ libs/log/msgbox_stub.c (working copy) -@@ -16,6 +16,9 @@ - - #include "msgbox.h" - #include "loginternal.h" -+#ifdef ANDROID -+#include -+#endif - - void - log_displayBox (const /*UTF-8*/char *title, int isError, -@@ -26,6 +29,9 @@ - // So just inform the user of our predicament - fprintf (streamOut, "Do not know how to display %s box\n", - isError ? "an error" : "a"); -+#ifdef ANDROID -+ __android_log_print( isError ? ANDROID_LOG_FATAL : ANDROID_LOG_INFO, "Ur-Quan Masters", "%s: %s", title, msg ); -+#endif - - // Suppress the compiler warnings in any case. - (void)title; Index: libs/uio/io.c =================================================================== --- libs/uio/io.c (revision 1353) @@ -2107,6 +330,22 @@ Index: libs/sound/decoders/oggaud.c #else return ova->vf.os.pageno; #endif /* OVCODEC_TREMOR */ +Index: libs/graphics/gfx_common.h +=================================================================== +--- libs/graphics/gfx_common.h (revision 1353) ++++ libs/graphics/gfx_common.h (working copy) +@@ -119,4 +119,11 @@ + extern int ScreenColorDepth; + extern int GraphicsDriver; + ++void TFB_SetOnScreenKeyboard_Hidden (void); ++void TFB_SetOnScreenKeyboard_HiddenPermanently (void); ++void TFB_SetOnScreenKeyboard_Menu (void); ++void TFB_SetOnScreenKeyboard_Starmap (void); ++void TFB_SetOnScreenKeyboard_Melee (void); ++void TFB_SetOnScreenKeyboard_TwoPlayersMelee (void); ++ + #endif Index: libs/graphics/sdl/sdl_common.c =================================================================== --- libs/graphics/sdl/sdl_common.c (revision 1353) @@ -2346,19 +585,1780 @@ Index: libs/graphics/sdl/pure.c if (SDL_Video == NULL) { -Index: libs/graphics/gfx_common.h +Index: libs/strings/unicode.c =================================================================== ---- libs/graphics/gfx_common.h (revision 1353) -+++ libs/graphics/gfx_common.h (working copy) -@@ -119,4 +119,11 @@ - extern int ScreenColorDepth; - extern int GraphicsDriver; +--- libs/strings/unicode.c (revision 1353) ++++ libs/strings/unicode.c (working copy) +@@ -41,7 +41,8 @@ + // function. + UniChar + getCharFromString(const unsigned char **ptr) { +- UniChar result; ++ const unsigned char *origPtr = *ptr; ++ UniChar result, errData; -+void TFB_SetOnScreenKeyboard_Hidden (void); -+void TFB_SetOnScreenKeyboard_HiddenPermanently (void); -+void TFB_SetOnScreenKeyboard_Menu (void); -+void TFB_SetOnScreenKeyboard_Starmap (void); -+void TFB_SetOnScreenKeyboard_Melee (void); -+void TFB_SetOnScreenKeyboard_TwoPlayersMelee (void); + if (**ptr < 0x80) { + // 0xxxxxxx, regular ASCII +@@ -121,7 +122,14 @@ + } + + err: +- log_add(log_Warning, "Warning: Invalid UTF8 sequence."); ++ errData = origPtr[0] * 0x1000000; ++ if (origPtr[0] && origPtr[1]) ++ errData &= origPtr[1] * 0x10000; ++ if (origPtr[0] && origPtr[1] && origPtr[2]) ++ errData &= origPtr[2] * 0x100; ++ if (origPtr[0] && origPtr[1] && origPtr[2] && origPtr[3]) ++ errData &= origPtr[3]; ++ log_add(log_Warning, "Warning: Invalid UTF8 sequence: result 0x%x last byte 0x%02x str 0x%08x %s", result, (unsigned)(**ptr), errData, origPtr); + + // Resynchronise (skip everything starting with 0x10xxxxxx): + resyncUTF8(ptr); +Index: config_unix.h +=================================================================== +--- config_unix.h (revision 0) ++++ config_unix.h (working copy) +@@ -0,0 +1,63 @@ ++/* This file contains some compile-time configuration options for *nix ++ * systems. ++ * config_unix.h is generated from config_unix.h.in by build.sh ++ * When building on MS Windows using build.sh (MinGW, Cygwin), ++ * config_win.h is generated from src/config_win.h.in. ++ * When using MSVC on MS Windows, you'll have to edit src/config_vc6.h ++ * manually if you want anything else than the defaults. ++ */ + ++#ifndef _CONFIG_UNIX_H ++#define _CONFIG_UNIX_H ++ ++/* Directory where the UQM game data is located */ ++#define CONTENTDIR "" ++ ++/* Directory where game data will be stored */ ++#define USERDIR "config/" ++ ++/* Directory where config files will be stored */ ++#define CONFIGDIR USERDIR ++ ++/* Directory where supermelee teams will be stored */ ++#define MELEEDIR "teams/" ++ ++/* Directory where save games will be stored */ ++#define SAVEDIR "save/" ++ ++/* Defined if words are stored with the most significant byte first */ ++#undef WORDS_BIGENDIAN ++ ++/* Defined if your system has readdir_r of its own */ ++#define HAVE_READDIR_R ++ ++/* Defined if your system has setenv of its own */ ++#define HAVE_SETENV ++ ++/* Defined if your system has strupr of its own */ ++#undef HAVE_STRUPR ++ ++/* Defined if your system has strcasecmp of its own */ ++#define HAVE_STRCASECMP_UQM ++ // Not using "HAVE_STRCASECMP" as that conflicts with SDL. ++ ++/* Defined if your system has stricmp of its own */ ++#undef HAVE_STRICMP ++ ++/* Defined if your system has getopt_long */ ++#define HAVE_GETOPT_LONG ++ ++/* Defined if your system has iswgraph of its own*/ ++#define HAVE_ISWGRAPH ++ ++/* Defined if your system has wchar_t of its own */ ++#define HAVE_WCHAR_T ++ ++/* Defined if your system has wint_t of its own */ ++#define HAVE_WINT_T ++ ++/* Defined if your system has _Bool of its own */ ++#define HAVE__BOOL ++ ++#endif /* _CONFIG_UNIX_H */ ++ +Index: uqm/supermelee/melee.c +=================================================================== +--- uqm/supermelee/melee.c (revision 1353) ++++ uqm/supermelee/melee.c (working copy) +@@ -2124,7 +2124,7 @@ + PlayerControl[0] = HUMAN_CONTROL | STANDARD_RATING; + Melee_LocalChange_team (&MenuState, 0, + MenuState.load.preBuiltList[0]); +- PlayerControl[1] = COMPUTER_CONTROL | STANDARD_RATING; ++ PlayerControl[1] = HUMAN_CONTROL | STANDARD_RATING; // COMPUTER_CONTROL | STANDARD_RATING; + Melee_LocalChange_team (&MenuState, 1, + MenuState.load.preBuiltList[1]); + } +Index: uqm/units.h +=================================================================== +--- uqm/units.h (revision 1353) ++++ uqm/units.h (working copy) +@@ -67,6 +67,7 @@ + #define RADAR_WIDTH (STATUS_WIDTH - RES_STAT_SCALE(8)) // JMS_GFX + #define RADAR_HEIGHT RES_STAT_SCALE(53) // JMS_GFX + #define RADAR_Y (SIS_ORG_Y + SIS_SCREEN_HEIGHT - (53 << RESOLUTION_FACTOR)) // JMS_GFX ++#define RADAR_Y_LIFTED_UP (RADAR_Y - (40 << RESOLUTION_FACTOR)) + + /* Blue boxes which display messages and the green date box. */ + #define SIS_TITLE_BOX_WIDTH (57 << RESOLUTION_FACTOR) // JMS_GFX +Index: uqm/menu.c +=================================================================== +--- uqm/menu.c (revision 1353) ++++ uqm/menu.c (working copy) +@@ -508,7 +508,7 @@ + s.origin.x = RADAR_X - r.corner.x; + s.origin.y = RADAR_Y - r.corner.y; + r.corner.x = s.origin.x - 1; +- r.corner.y = s.origin.y - (11 << RESOLUTION_FACTOR); // JMS_GFX ++ r.corner.y = s.origin.y - (40 << RESOLUTION_FACTOR); // JMS_GFX + r.extent.width = RADAR_WIDTH + 2; + BatchGraphics (); + SetContextForeGroundColor ( +Index: uqm/planets/lander.c +=================================================================== +--- uqm/planets/lander.c (revision 1353) ++++ uqm/planets/lander.c (working copy) +@@ -1852,15 +1852,15 @@ + if (crew_left) + { + SIZE index = GetFrameIndex (LanderFrame[0]); ++ BATTLE_INPUT_STATE InputState = GetDirectionalJoystickInput(index, 0); + if (turn_wait) + --turn_wait; +- else if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT] || +- CurrentInputState.key[PlayerControls[0]][KEY_RIGHT]) ++ else if ((InputState & BATTLE_LEFT) || (InputState & BATTLE_RIGHT)) + { + COUNT landerSpeedNumer; + COUNT angle; + +- if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT]) ++ if (InputState & BATTLE_LEFT) + --index; + else + ++index; +@@ -1884,7 +1884,7 @@ + turn_wait = SHUTTLE_TURN_WAIT; + } + +- if (!CurrentInputState.key[PlayerControls[0]][KEY_UP]) ++ if (!(InputState & BATTLE_THRUST)) + { + dx = 0; + dy = 0; +@@ -2212,7 +2212,9 @@ + landerInputState.Initialized = FALSE; + landerInputState.InputFunc = DoPlanetSide; + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); ++ TFB_SetOnScreenKeyboard_Melee (); + DoInput (&landerInputState, FALSE); ++ TFB_SetOnScreenKeyboard_Menu (); + + if (!(GLOBAL (CurrentActivity) & CHECK_ABORT)) + { +Index: uqm/planets/solarsys.c +=================================================================== +--- uqm/planets/solarsys.c (revision 1353) ++++ uqm/planets/solarsys.c (working copy) +@@ -1245,18 +1245,19 @@ + static void + ProcessShipControls (void) + { +- COUNT index; ++ COUNT index = GetFrameIndex (GLOBAL (ShipStamp.frame));; + SIZE delta_x, delta_y; ++ BATTLE_INPUT_STATE InputState = GetDirectionalJoystickInput(index, 0); + +- if (CurrentInputState.key[PlayerControls[0]][KEY_UP]) ++ if (InputState & BATTLE_THRUST) + delta_y = -1; + else + delta_y = 0; + + delta_x = 0; +- if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT]) ++ if (InputState & BATTLE_LEFT) + delta_x -= 1; +- if (CurrentInputState.key[PlayerControls[0]][KEY_RIGHT]) ++ if (InputState & BATTLE_RIGHT) + delta_x += 1; + + if (delta_x || delta_y < 0) +@@ -1269,7 +1270,6 @@ + else + delta_y = 0; + +- index = GetFrameIndex (GLOBAL (ShipStamp.frame)); + if (pSolarSysState->turn_counter) + --pSolarSysState->turn_counter; + else if (delta_x) +@@ -2473,7 +2473,9 @@ + InitSolarSys (); + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); + SolarSysState.InputFunc = DoIpFlight; ++ TFB_SetOnScreenKeyboard_Melee (); + DoInput (&SolarSysState, FALSE); ++ TFB_SetOnScreenKeyboard_Menu (); + UninitSolarSys (); + pSolarSysState = 0; + } +@@ -2751,13 +2753,17 @@ + + if (pSS->InOrbit) + { // CheckShipLocation() or InitSolarSys() sent us to orbital ++ TFB_SetOnScreenKeyboard_Menu (); + EnterPlanetOrbit (); ++ TFB_SetOnScreenKeyboard_Melee (); + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); + pSS->InOrbit = FALSE; + } + else if (cancel || LastActivity == CHECK_LOAD) + { ++ TFB_SetOnScreenKeyboard_Menu (); + SolarSysMenu (); ++ TFB_SetOnScreenKeyboard_Melee (); + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); + } + else +Index: uqm/planets/pstarmap.c +=================================================================== +--- uqm/planets/pstarmap.c (revision 1353) ++++ uqm/planets/pstarmap.c (working copy) +@@ -2005,7 +2005,9 @@ + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); + SetMenuRepeatDelay (MIN_ACCEL_DELAY, MAX_ACCEL_DELAY, STEP_ACCEL_DELAY, + TRUE); ++ TFB_SetOnScreenKeyboard_Starmap (); + DoInput (&MenuState, FALSE); ++ TFB_SetOnScreenKeyboard_Menu (); + SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + SetDefaultMenuRepeatDelay (); + +Index: uqm/shipstat.c +=================================================================== +--- uqm/shipstat.c (revision 1353) ++++ uqm/shipstat.c (working copy) +@@ -144,6 +144,45 @@ + DrawFilledRectangle (&r); + } + ++static void ++DrawCrewEnergyBoxOutline (RECT *box) ++{ ++ RECT r; ++ ++ SetContextForeGroundColor ( ++ BUILD_COLOR (MAKE_RGB15 (0x10, 0x10, 0x10), 0x19)); ++ r.corner.x = box->corner.x; ++ r.corner.y = box->corner.y + box->extent.height - 1; ++ r.extent.width = box->extent.width; ++ r.extent.height = 1; ++ DrawFilledRectangle (&r); ++ r.corner.x = box->corner.x + box->extent.width - 1; ++ r.corner.y = box->corner.y; ++ r.extent.width = 1; ++ r.extent.height = box->extent.height; ++ DrawFilledRectangle (&r); ++ ++ SetContextForeGroundColor ( ++ BUILD_COLOR (MAKE_RGB15 (0x08, 0x08, 0x08), 0x1F)); ++ r.corner.x = box->corner.x; ++ r.corner.y = box->corner.y; ++ r.extent.width = box->extent.width; ++ r.extent.height = 1; ++ DrawFilledRectangle (&r); ++ r.corner.x = box->corner.x; ++ r.corner.y = box->corner.y; ++ r.extent.width = 1; ++ r.extent.height = box->extent.height; ++ DrawFilledRectangle (&r); ++ ++ SetContextForeGroundColor (BLACK_COLOR); ++ r.corner.x = box->corner.x + 1; ++ r.corner.y = box->corner.y + 1; ++ r.extent.width = box->extent.width - 2; ++ r.extent.height = box->extent.height - 2; ++ DrawFilledRectangle (&r); ++} ++ + void + InitShipStatus (SHIP_INFO *SIPtr, STARSHIP *StarShipPtr, RECT *pClipRect, BOOLEAN inMeleeMenu) + { +@@ -256,6 +295,28 @@ + r.extent.height = energy_height; + r.corner.y = y - r.extent.height + GAUGE_YOFFS + 1; + DrawFilledRectangle (&r); ++ ++ // TODO: replace the above ugly code with DrawCrewEnergyBoxOutline(), but I don't want to touch that as long as it works ++ r.corner.x = RESOLUTION_FACTOR == 2 ? 3 : RESOLUTION_FACTOR; ++ r.corner.y = BAD_GUY_HORIZ_CREW_YOFFS; ++ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) ++ r.corner.y = GOOD_GUY_HORIZ_CREW_YOFFS; ++ r.corner.y += RESOLUTION_FACTOR == 2 ? 3 : RESOLUTION_FACTOR; ++ r.extent.width = 1000; ++ r.extent.height = STAT_WIDTH + (2 << RESOLUTION_FACTOR); ++ SetContextForeGroundColor (BLACK_COLOR); ++ DrawFilledRectangle (&r); ++ r.extent.width = crew_height + (2 << RESOLUTION_FACTOR); ++ DrawCrewEnergyBoxOutline (&r); ++ r.corner.y = BAD_GUY_HORIZ_ENERGY_YOFFS; ++ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) ++ r.corner.y = GOOD_GUY_HORIZ_ENERGY_YOFFS; ++ r.corner.y += RESOLUTION_FACTOR == 2 ? 3 : RESOLUTION_FACTOR; ++ r.extent.width = 1000; ++ SetContextForeGroundColor (BLACK_COLOR); ++ DrawFilledRectangle (&r); ++ r.extent.width = energy_height + (2 << RESOLUTION_FACTOR); ++ DrawCrewEnergyBoxOutline (&r); + } + + if (!StarShipPtr || StarShipPtr->captains_name_index) +@@ -315,7 +376,7 @@ + // DeltaStatistics() below will add specified values to these + SIPtr->crew_level = 0; + SIPtr->energy_level = 0; +- DeltaStatistics (SIPtr, y, crew_delta, energy_delta); ++ DeltaStatistics (SIPtr, y, crew_delta, energy_delta, StarShipPtr ? StarShipPtr->playerNr : NPC_PLAYER_NUM); + } + + UnbatchGraphics (); +@@ -333,10 +394,11 @@ + // crew_delta <= ShipInfoPtr->max_crew - ShipInfoPtr->crew_level + void + DeltaStatistics (SHIP_INFO *ShipInfoPtr, COORD y_offs, +- SIZE crew_delta, SIZE energy_delta) ++ SIZE crew_delta, SIZE energy_delta, SIZE player_num) + { +- COORD x, y; +- RECT r; ++ COORD x, y, y2; ++ RECT r, r2; ++ SIZE max_crew_size, max_energy_size; + + if (crew_delta == 0 && energy_delta == 0) + return; +@@ -346,13 +408,15 @@ + + r.extent.width = UNIT_WIDTH; + r.extent.height = UNIT_HEIGHT; ++#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) ++ max_crew_size = MIN(ShipInfoPtr->max_crew, MAX_CREW_SIZE); ++ max_energy_size = ShipInfoPtr->max_energy; + + if (crew_delta != 0) + { + COUNT oldNumBlocks, newNumBlocks, blockI; + COUNT newCrewLevel; + +-#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) + oldNumBlocks = MIN(ShipInfoPtr->crew_level, MAX_CREW_SIZE); + newCrewLevel = ShipInfoPtr->crew_level + crew_delta; + newNumBlocks = MIN(newCrewLevel, MAX_CREW_SIZE); +@@ -419,10 +483,33 @@ + // Always print a number for the SIS in the full game. + DrawBattleCrewAmount (ShipInfoPtr, y_offs); + } ++ ++ y2 = BAD_GUY_HORIZ_CREW_YOFFS; ++ if (player_num == RPG_PLAYER_NUM) ++ y2 = GOOD_GUY_HORIZ_CREW_YOFFS; ++ ++ r2.extent.height = UNIT_WIDTH; ++ r2.extent.width = UNIT_HEIGHT; ++ ++ for (blockI = 0; blockI < max_crew_size; blockI++) ++ { ++ SetContextForeGroundColor ( ++ (ShipInfoPtr->ship_flags & CREW_IMMUNE) ? ++ ROBOT_UNIT_COLOR : CREW_UNIT_COLOR); ++ if (blockI >= newNumBlocks) ++ SetContextForeGroundColor (BLACK_COLOR); ++ ++ r2.corner.x = HORIZ_CREW_XOFFS + (blockI >> 1) * (UNIT_HEIGHT + 1); ++ r2.corner.y = y2 + HORIZ_CREW_XOFFS; ++ if (blockI & 1) ++ r2.corner.y += UNIT_WIDTH + 1; ++ DrawFilledRectangle (&r2); ++ } + } + + if (energy_delta != 0) + { ++ COUNT blockI; + if (energy_delta > 0) + { + #define FUEL_UNIT_COLOR BUILD_COLOR (MAKE_RGB15 (0x14, 0x00, 0x00), 0x04) +@@ -458,6 +545,26 @@ + --ShipInfoPtr->energy_level; + } while (++energy_delta); + } ++ ++ y2 = BAD_GUY_HORIZ_ENERGY_YOFFS; ++ if (player_num == RPG_PLAYER_NUM) ++ y2 = GOOD_GUY_HORIZ_ENERGY_YOFFS; ++ ++ r2.extent.height = UNIT_WIDTH; ++ r2.extent.width = UNIT_HEIGHT; ++ ++ for (blockI = 0; blockI < max_energy_size; blockI++) ++ { ++ SetContextForeGroundColor (FUEL_UNIT_COLOR); ++ if (blockI >= ShipInfoPtr->energy_level) ++ SetContextForeGroundColor (BLACK_COLOR); ++ ++ r2.corner.x = HORIZ_CREW_XOFFS + (blockI >> 1) * (UNIT_HEIGHT + 1); ++ r2.corner.y = y2 + HORIZ_CREW_XOFFS; ++ if (blockI & 1) ++ r2.corner.y += UNIT_WIDTH + 1; ++ DrawFilledRectangle (&r2); ++ } + } + } + +Index: uqm/setupmenu.c +=================================================================== +--- uqm/setupmenu.c (revision 1353) ++++ uqm/setupmenu.c (working copy) +@@ -83,7 +83,7 @@ #endif + + #define MENU_COUNT 8 +-#define CHOICE_COUNT 29 // JMS: New options added. ++#define CHOICE_COUNT 30 // JMS: New options added. + #define SLIDER_COUNT 3 + #define BUTTON_COUNT 10 + #define LABEL_COUNT 4 +@@ -106,7 +106,7 @@ + static int choice_widths[CHOICE_COUNT] = { + 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 2, 3, 3, +- 3, 2, 3, 2, 2, 2, 2, 2, 2 }; ++ 3, 2, 3, 2, 2, 2, 2, 2, 2, 2 }; + + static HANDLER button_handlers[BUTTON_COUNT] = { + quit_main_menu, quit_sub_menu, do_graphics, do_engine, +@@ -117,7 +117,7 @@ + // JMS: The first 8 was 7 (sound options.) Added mainmenumusic on/off. + // JMS: The HAVE_OPENGL options were 5 and 4. Added cheatMode, mineralSubmenu, nebulae and planet options. + static int menu_sizes[MENU_COUNT] = { +- 7, 6, 8, 8, 2, 5, ++ 7, 6, 8, 8, 2, 6, + #ifdef HAVE_OPENGL + 10, + #else +@@ -185,6 +185,7 @@ + static WIDGET *keyconfig_widgets[] = { + (WIDGET *)(&choices[18]), + (WIDGET *)(&choices[19]), ++ (WIDGET *)(&choices[29]), // Directional joystick + (WIDGET *)(&labels[1]), + (WIDGET *)(&buttons[8]), + (WIDGET *)(&buttons[1]) }; +@@ -293,6 +294,8 @@ + if (event == WIDGET_EVENT_SELECT) + { + next = (WIDGET *)(&menus[5]); ++ if (getenv("OUYA")) ++ next = (WIDGET *)(&menus[4]); + (*next->receiveFocus) (next, WIDGET_EVENT_DOWN); + return TRUE; + } +@@ -414,6 +417,7 @@ + choices[26].selected = opts.rotatingIpPlanets; // JMS + choices[27].selected = opts.texturedIpPlanets || opts.rotatingIpPlanets; // JMS + choices[28].selected = opts.cheatMode; // JMS ++ choices[29].selected = opts.directionalJoystick; + + sliders[0].value = opts.musicvol; + sliders[1].value = opts.sfxvol; +@@ -452,6 +456,7 @@ + opts.rotatingIpPlanets = choices[26].selected; // JMS + opts.texturedIpPlanets = choices[27].selected || opts.rotatingIpPlanets; // JMS + opts.cheatMode = choices[28].selected; // JMS ++ opts.directionalJoystick = choices[29].selected; + + opts.musicvol = sliders[0].value; + opts.sfxvol = sliders[1].value; +@@ -1164,6 +1169,7 @@ + opts->rotatingIpPlanets = optRotatingIpPlanets ? OPTVAL_ENABLED : OPTVAL_DISABLED; + opts->texturedIpPlanets = (optTexturedIpPlanets ? OPTVAL_ENABLED : OPTVAL_DISABLED) || opts->rotatingIpPlanets; + opts->cheatMode = optCheatMode ? OPTVAL_ENABLED : OPTVAL_DISABLED; ++ opts->directionalJoystick = optDirectionalJoystick ? OPTVAL_ENABLED : OPTVAL_DISABLED; + + /* Work out resolution. On the way, try to guess a good default + * for config.alwaysgl, then overwrite it if it was set previously. */ +@@ -1376,6 +1382,9 @@ + res_PutBoolean ("config.cheatMode", opts->cheatMode == OPTVAL_ENABLED); + optCheatMode = opts->cheatMode == OPTVAL_ENABLED; + ++ res_PutBoolean ("config.directionaljoystick", opts->directionalJoystick == OPTVAL_ENABLED); ++ optDirectionalJoystick = (opts->directionalJoystick == OPTVAL_ENABLED) ? TRUE : FALSE; ++ + if (NewWidth == 320 && NewHeight == 240) + { + switch (opts->scaler) +Index: uqm/setupmenu.h +=================================================================== +--- uqm/setupmenu.h (revision 1353) ++++ uqm/setupmenu.h (working copy) +@@ -86,7 +86,7 @@ + OPT_CONSOLETYPE menu, text, cscan, scroll, intro, meleezoom, shield; + CONTROL_TEMPLATE player1, player2; + int speechvol, musicvol, sfxvol; +- BOOLEAN mainmenuMusic, mineralSubmenu, nebulae, rotatingIpPlanets, texturedIpPlanets, cheatMode; // JMS ++ BOOLEAN mainmenuMusic, mineralSubmenu, nebulae, rotatingIpPlanets, texturedIpPlanets, cheatMode, directionalJoystick; // JMS + } GLOBALOPTS; + + void SetupMenu (void); +Index: uqm/gameinp.c +=================================================================== +--- uqm/gameinp.c (revision 1353) ++++ uqm/gameinp.c (working copy) +@@ -16,6 +16,7 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++#include + #include "controls.h" + #include "battlecontrols.h" + #include "init.h" +@@ -32,11 +33,14 @@ + #include "libs/timelib.h" + #include "libs/threadlib.h" + +- ++#ifdef ANDROID ++#define ACCELERATION_INCREMENT (ONE_SECOND) ++#define MENU_REPEAT_DELAY (ONE_SECOND) ++#else + #define ACCELERATION_INCREMENT (ONE_SECOND / 12) + #define MENU_REPEAT_DELAY (ONE_SECOND / 2) ++#endif + +- + typedef struct + { + BOOLEAN (*InputFunc) (void *pInputState); +@@ -66,6 +70,7 @@ + + volatile BOOLEAN ExitRequested; + volatile BOOLEAN GamePaused; ++volatile BOOLEAN OnScreenKeyboardLocked; + + static InputFrameCallback *inputCallback; + +@@ -422,16 +427,10 @@ + } + + static BATTLE_INPUT_STATE +-ControlInputToBattleInput (const int *keyState) ++ControlInputToBattleInput (const int *keyState, COUNT player, int direction) + { + BATTLE_INPUT_STATE InputState = 0; + +- if (keyState[KEY_UP]) +- InputState |= BATTLE_THRUST; +- if (keyState[KEY_LEFT]) +- InputState |= BATTLE_LEFT; +- if (keyState[KEY_RIGHT]) +- InputState |= BATTLE_RIGHT; + if (keyState[KEY_WEAPON]) + InputState |= BATTLE_WEAPON; + if (keyState[KEY_SPECIAL]) +@@ -441,21 +440,35 @@ + if (keyState[KEY_DOWN]) + InputState |= BATTLE_DOWN; + ++ if(direction < 0) ++ { ++ if (keyState[KEY_LEFT]) ++ InputState |= BATTLE_LEFT; ++ if (keyState[KEY_RIGHT]) ++ InputState |= BATTLE_RIGHT; ++ if (keyState[KEY_UP]) ++ InputState |= BATTLE_THRUST; ++ } ++ else ++ { ++ InputState |= GetDirectionalJoystickInput(direction, player); ++ } ++ + return InputState; + } + + BATTLE_INPUT_STATE +-CurrentInputToBattleInput (COUNT player) ++CurrentInputToBattleInput (COUNT player, int direction) + { + return ControlInputToBattleInput( +- CurrentInputState.key[PlayerControls[player]]); ++ CurrentInputState.key[PlayerControls[player]], player, direction); + } + + BATTLE_INPUT_STATE + PulsedInputToBattleInput (COUNT player) + { + return ControlInputToBattleInput( +- PulsedInputState.key[PlayerControls[player]]); ++ PulsedInputState.key[PlayerControls[player]], player, -1); + } + + BOOLEAN +@@ -500,3 +513,144 @@ + return result; + } + ++// Fast arctan2, returns angle in radians as integer, with fractional part in lower 16 bits ++// Stolen from http://www.dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization , precision is said to be 0.07 rads ++ ++#ifndef M_PI ++#define M_PI 3.14159265358979323846 ++#endif ++enum { atan2i_coeff_1 = ((int)(M_PI*65536.0/4)), atan2i_coeff_2 = (3*atan2i_coeff_1), atan2i_PI = (int)(M_PI * 65536.0), SHIP_DIRECTIONS = 16 }; ++ ++static inline int atan2i(int y, int x) ++{ ++ int angle; ++ int abs_y = abs(y); ++ if( abs_y == 0 ) ++ abs_y = 1; ++ if (x>=0) ++ { ++ angle = atan2i_coeff_1 - atan2i_coeff_1 * (x - abs_y) / (x + abs_y); ++ } ++ else ++ { ++ angle = atan2i_coeff_2 - atan2i_coeff_1 * (x + abs_y) / (abs_y - x); ++ } ++ if (y < 0) ++ return(-angle); // negate if in quad III or IV ++ else ++ return(angle); ++} ++ ++BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction, int player) ++{ ++ BATTLE_INPUT_STATE InputState = 0; ++ static BOOLEAN JoystickThrust[NUM_PLAYERS] = { FALSE, FALSE }; ++ static BOOLEAN JoystickTapFlag[NUM_PLAYERS] = { FALSE, FALSE }; ++ static TimeCount JoystickTapTime[NUM_PLAYERS] = { 0, 0 }; ++ ++ if (CurrentInputState.key[PlayerControls[player]][KEY_THRUST]) ++ InputState |= BATTLE_THRUST; ++ ++ if( VControl_GetJoysticksAmount() <= 0 ) ++ { ++ if (CurrentInputState.key[PlayerControls[player]][KEY_LEFT]) ++ InputState |= BATTLE_LEFT; ++ if (CurrentInputState.key[PlayerControls[player]][KEY_RIGHT]) ++ InputState |= BATTLE_RIGHT; ++ if (CurrentInputState.key[PlayerControls[player]][KEY_UP]) ++ InputState |= BATTLE_THRUST; ++ return InputState; ++ } ++ ++ int axisX = VControl_GetJoyAxis(0, player * 2), axisY = VControl_GetJoyAxis(0, player * 2 + 1); ++ ++ if( axisX == 0 && axisY == 0 ) ++ { ++ // Some basic gamepad input support ++ axisX = VControl_GetJoyAxis(2, player * 2); ++ axisY = VControl_GetJoyAxis(2, player * 2 + 1); ++ if( abs( axisX ) > 5000 || abs( axisY ) > 5000 ) // Deadspot at the center ++ { ++ JoystickTapFlag[player] = TRUE; ++ JoystickThrust[player] = FALSE; ++ // Turning thrust with joystick is uncomfortable ++ //if( abs( axisX ) > 25000 || abs( axisY ) > 25000 ) ++ // JoystickThrust[player] = TRUE; ++ } ++ else ++ { ++ axisX = 0; ++ axisY = 0; ++ } ++ } ++ ++ if( axisX == 0 && axisY == 0 ) ++ { ++ // Process keyboard input only when joystick is not used ++ if (CurrentInputState.key[PlayerControls[player]][KEY_LEFT]) ++ InputState |= BATTLE_LEFT; ++ if (CurrentInputState.key[PlayerControls[player]][KEY_RIGHT]) ++ InputState |= BATTLE_RIGHT; ++ if (CurrentInputState.key[PlayerControls[player]][KEY_UP]) ++ InputState |= BATTLE_THRUST; ++ } ++ ++ if( !optDirectionalJoystick ) ++ { ++ if( player == 1 ) ++ { ++ axisX = - axisX; ++ axisY = - axisY; ++ } ++ if( axisX < -10000 ) ++ InputState |= BATTLE_LEFT; ++ if( axisX > 10000 ) ++ InputState |= BATTLE_RIGHT; ++ if( axisY < 0 ) ++ InputState |= BATTLE_THRUST; ++ return InputState; ++ } ++ ++ if( axisX != 0 || axisY != 0 ) ++ { ++ int angle = atan2i(axisY, axisX), diff; ++ // Convert it to 16 directions used by Melee ++ angle += atan2i_PI / SHIP_DIRECTIONS; ++ if( angle < 0 ) ++ angle += atan2i_PI * 2; ++ if( angle > atan2i_PI * 2 ) ++ angle -= atan2i_PI * 2; ++ angle = angle * SHIP_DIRECTIONS / atan2i_PI / 2; ++ ++ diff = angle - direction - SHIP_DIRECTIONS / 4; ++ while( diff >= SHIP_DIRECTIONS ) ++ diff -= SHIP_DIRECTIONS; ++ while( diff < 0 ) ++ diff += SHIP_DIRECTIONS; ++ ++ if( diff < SHIP_DIRECTIONS / 2 ) ++ InputState |= BATTLE_LEFT; ++ if( diff > SHIP_DIRECTIONS / 2 ) ++ InputState |= BATTLE_RIGHT; ++ ++ if( !JoystickTapFlag[player] ) ++ { ++ JoystickTapFlag[player] = TRUE; ++ if( GetTimeCounter() < JoystickTapTime[player] + ONE_SECOND ) ++ JoystickThrust[player] = !JoystickThrust[player]; ++ else ++ JoystickThrust[player] = TRUE; ++ } ++ if( JoystickThrust[player] ) ++ InputState |= BATTLE_THRUST; ++ } ++ else ++ { ++ if( JoystickTapFlag[player] ) ++ { ++ JoystickTapFlag[player] = FALSE; ++ JoystickTapTime[player] = GetTimeCounter(); ++ } ++ } ++ return InputState; ++} +Index: uqm/comm/supox/supoxc.c +=================================================================== +--- uqm/comm/supox/supoxc.c (revision 1353) ++++ uqm/comm/supox/supoxc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../supox/strings.h" + + #include "uqm/build.h" + +Index: uqm/comm/vux/vuxc.c +=================================================================== +--- uqm/comm/vux/vuxc.c (revision 1353) ++++ uqm/comm/vux/vuxc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../vux/strings.h" + + static LOCDATA vux_desc_1x = + { +Index: uqm/comm/zoqfot/zoqfotc.c +=================================================================== +--- uqm/comm/zoqfot/zoqfotc.c (revision 1353) ++++ uqm/comm/zoqfot/zoqfotc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../zoqfot/strings.h" + + #include "uqm/build.h" + #include "uqm/gameev.h" +Index: uqm/comm/shofixt/shofixt.c +=================================================================== +--- uqm/comm/shofixt/shofixt.c (revision 1353) ++++ uqm/comm/shofixt/shofixt.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../shofixt/strings.h" + + #include "uqm/gameev.h" + +Index: uqm/comm/pkunk/pkunkc.c +=================================================================== +--- uqm/comm/pkunk/pkunkc.c (revision 1353) ++++ uqm/comm/pkunk/pkunkc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../pkunk/strings.h" + + #include "uqm/build.h" + #include "uqm/gameev.h" +Index: uqm/comm/rebel/rebel.c +=================================================================== +--- uqm/comm/rebel/rebel.c (revision 1353) ++++ uqm/comm/rebel/rebel.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "../yehat/resinst.h" +-#include "strings.h" ++#include "../rebel/strings.h" + + #include "uqm/build.h" + +Index: uqm/comm/arilou/arilouc.c +=================================================================== +--- uqm/comm/arilou/arilouc.c (revision 1353) ++++ uqm/comm/arilou/arilouc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../arilou/strings.h" + + #include "uqm/gameev.h" + +Index: uqm/comm/spahome/spahome.c +=================================================================== +--- uqm/comm/spahome/spahome.c (revision 1353) ++++ uqm/comm/spahome/spahome.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "../spathi/resinst.h" +-#include "strings.h" ++#include "../spahome/strings.h" + + #include "uqm/build.h" + #include "uqm/gameev.h" +Index: uqm/comm/starbas/starbas.c +=================================================================== +--- uqm/comm/starbas/starbas.c (revision 1353) ++++ uqm/comm/starbas/starbas.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "../comandr/resinst.h" +-#include "strings.h" ++#include "../starbas/strings.h" + + #include "uqm/build.h" + #include "uqm/setup.h" +Index: uqm/comm/utwig/utwigc.c +=================================================================== +--- uqm/comm/utwig/utwigc.c (revision 1353) ++++ uqm/comm/utwig/utwigc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../utwig/strings.h" + + #include "uqm/build.h" + #include "uqm/gameev.h" +Index: uqm/comm/umgah/umgahc.c +=================================================================== +--- uqm/comm/umgah/umgahc.c (revision 1353) ++++ uqm/comm/umgah/umgahc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../umgah/strings.h" + + #include "uqm/build.h" + +Index: uqm/comm/talkpet/talkpet.c +=================================================================== +--- uqm/comm/talkpet/talkpet.c (revision 1353) ++++ uqm/comm/talkpet/talkpet.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../talkpet/strings.h" + + #include "uqm/build.h" + +Index: uqm/comm/thradd/thraddc.c +=================================================================== +--- uqm/comm/thradd/thraddc.c (revision 1353) ++++ uqm/comm/thradd/thraddc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../thradd/strings.h" + + #include "uqm/build.h" + #include "uqm/gameev.h" +Index: uqm/comm/melnorm/melnorm.c +=================================================================== +--- uqm/comm/melnorm/melnorm.c (revision 1353) ++++ uqm/comm/melnorm/melnorm.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../melnorm/strings.h" + + #include "uqm/gameev.h" + #include "uqm/setup.h" +Index: uqm/comm/yehat/yehatc.c +=================================================================== +--- uqm/comm/yehat/yehatc.c (revision 1353) ++++ uqm/comm/yehat/yehatc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../yehat/strings.h" + + #include "uqm/build.h" + #include "uqm/gameev.h" +Index: uqm/comm/orz/orzc.c +=================================================================== +--- uqm/comm/orz/orzc.c (revision 1353) ++++ uqm/comm/orz/orzc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../orz/strings.h" + + #include "uqm/build.h" + +Index: uqm/comm/urquan/urquanc.c +=================================================================== +--- uqm/comm/urquan/urquanc.c (revision 1353) ++++ uqm/comm/urquan/urquanc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../urquan/strings.h" + + static LOCDATA urquan_desc = + { +Index: uqm/comm/slyhome/slyhome.c +=================================================================== +--- uqm/comm/slyhome/slyhome.c (revision 1353) ++++ uqm/comm/slyhome/slyhome.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../slyhome/strings.h" + + #include "uqm/gameev.h" + +Index: uqm/comm/comandr/comandr.c +=================================================================== +--- uqm/comm/comandr/comandr.c (revision 1353) ++++ uqm/comm/comandr/comandr.c (working copy) +@@ -20,7 +20,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../comandr/strings.h" + + #include "uqm/setup.h" + #include "uqm/sis.h" +Index: uqm/comm/blackur/blackurc.c +=================================================================== +--- uqm/comm/blackur/blackurc.c (revision 1353) ++++ uqm/comm/blackur/blackurc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../blackur/strings.h" + + static LOCDATA blackurq_desc = + { +Index: uqm/comm/mycon/myconc.c +=================================================================== +--- uqm/comm/mycon/myconc.c (revision 1353) ++++ uqm/comm/mycon/myconc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../mycon/strings.h" + + #include "uqm/gameev.h" + #include "libs/mathlib.h" +Index: uqm/comm/spathi/spathic.c +=================================================================== +--- uqm/comm/spathi/spathic.c (revision 1353) ++++ uqm/comm/spathi/spathic.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../spathi/strings.h" + + #include "uqm/build.h" + +Index: uqm/comm/druuge/druugec.c +=================================================================== +--- uqm/comm/druuge/druugec.c (revision 1353) ++++ uqm/comm/druuge/druugec.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../druuge/strings.h" + + #include "uqm/build.h" + #include "uqm/setup.h" +Index: uqm/comm/syreen/syreenc.c +=================================================================== +--- uqm/comm/syreen/syreenc.c (revision 1353) ++++ uqm/comm/syreen/syreenc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../syreen/strings.h" + + #include "libs/sound/sound.h" + #include "uqm/build.h" +Index: uqm/comm/chmmr/chmmrc.c +=================================================================== +--- uqm/comm/chmmr/chmmrc.c (revision 1353) ++++ uqm/comm/chmmr/chmmrc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../chmmr/strings.h" + + #include "uqm/build.h" + #include "uqm/hyper.h" +Index: uqm/comm/slyland/slyland.c +=================================================================== +--- uqm/comm/slyland/slyland.c (revision 1353) ++++ uqm/comm/slyland/slyland.c (working copy) +@@ -16,10 +16,10 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++#include "../slyland/strings.h" ++#include + #include "../commall.h" +-#include + #include "resinst.h" +-#include "strings.h" + + #include "options.h" + #include "uqm/battle.h" +Index: uqm/comm/ilwrath/ilwrathc.c +=================================================================== +--- uqm/comm/ilwrath/ilwrathc.c (revision 1353) ++++ uqm/comm/ilwrath/ilwrathc.c (working copy) +@@ -18,7 +18,7 @@ + + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../ilwrath/strings.h" + + #include "uqm/gameev.h" + +Index: uqm/hyper.c +=================================================================== +--- uqm/hyper.c (revision 1353) ++++ uqm/hyper.c (working copy) +@@ -1930,7 +1930,6 @@ + Color OldColor; + CONTEXT OldContext; + MENU_STATE MenuState; +- + UnbatchGraphics (); + + OldContext = SetContext (SpaceContext); +Index: uqm/intro.c +=================================================================== +--- uqm/intro.c (revision 1353) ++++ uqm/intro.c (working copy) +@@ -35,7 +35,7 @@ + + #include + +-static BOOLEAN ShowSlidePresentation (STRING PresStr); ++static BOOLEAN ShowSlidePresentation (STRING PresStr, RESOURCE PresName, BOOLEAN NoMusic); + + typedef struct + { +@@ -52,6 +52,7 @@ + FONT Fonts[MAX_FONTS]; + FRAME Frame; + MUSIC_REF MusicRef; ++ BOOLEAN MusicOverride; + BOOLEAN Batched; + FRAME SisFrame; + FRAME RotatedFrame; +@@ -285,10 +286,10 @@ + } + + static BOOLEAN +-ShowPresentationFile (const char *name) ++ShowPresentationFile (const char *name, BOOLEAN NoMusic) + { + STRING pres = CaptureStringTable (LoadStringTableFile (contentDir, name)); +- BOOLEAN result = ShowSlidePresentation (pres); ++ BOOLEAN result = ShowSlidePresentation (pres, "", NoMusic); + DestroyStringTable (ReleaseStringTable (pres)); + return result; + } +@@ -518,14 +519,17 @@ + } + else if (strcmp (Opcode, "MUSIC") == 0) + { /* set music */ +- utf8StringCopy (pPIS->Buffer, sizeof (pPIS->Buffer), pStr); +- if (pPIS->MusicRef) ++ if (!pPIS->MusicOverride) + { +- StopMusic (); +- DestroyMusic (pPIS->MusicRef); ++ utf8StringCopy (pPIS->Buffer, sizeof (pPIS->Buffer), pStr); ++ if (pPIS->MusicRef) ++ { ++ StopMusic (); ++ DestroyMusic (pPIS->MusicRef); ++ } ++ pPIS->MusicRef = LoadMusicFile (pPIS->Buffer); ++ PlayMusic (pPIS->MusicRef, FALSE, 1); + } +- pPIS->MusicRef = LoadMusicFile (pPIS->Buffer); +- PlayMusic (pPIS->MusicRef, FALSE, 1); + } + else if (strcmp (Opcode, "WAIT") == 0) + { /* wait */ +@@ -817,7 +821,7 @@ + Present_UnbatchGraphics (pPIS, TRUE); + + utf8StringCopy (pPIS->Buffer, sizeof (pPIS->Buffer), pStr); +- ShowPresentationFile (pPIS->Buffer); ++ ShowPresentationFile (pPIS->Buffer, pPIS->MusicOverride); + } + else if (strcmp (Opcode, "LINE") == 0) + { +@@ -880,12 +884,13 @@ + } + + static BOOLEAN +-ShowSlidePresentation (STRING PresStr) ++ShowSlidePresentation (STRING PresStr, RESOURCE PresName, BOOLEAN NoMusic) + { + CONTEXT OldContext; + FONT OldFont; + RECT OldRect; + PRESENTATION_INPUT_STATE pis; ++ char MusicOverrideRes[256]; + int i; + + memset (&pis, 0, sizeof(pis)); +@@ -901,6 +906,24 @@ + OldFont = SetContextFont (NULL); + SetContextBackGroundColor (BLACK_COLOR); + UnlockMutex (GraphicsLock); ++ /* Override intro and ending music with Precursors remix, if it's available */ ++ pis.MusicOverride = NoMusic; ++ if (!NoMusic && strlen(PresName) < sizeof(MusicOverrideRes) - 10) ++ { ++ const char *ResType; ++ strcpy (MusicOverrideRes, PresName); ++ strcat (MusicOverrideRes, ".music"); ++ ResType = res_GetResourceType (MusicOverrideRes); ++ if (ResType != NULL && strcmp(ResType, "MUSICRES") == 0) ++ { ++ pis.MusicRef = LoadMusic (MusicOverrideRes); ++ if (pis.MusicRef) ++ { ++ pis.MusicOverride = TRUE; ++ PlayMusic (pis.MusicRef, FALSE, 1); ++ } ++ } ++ } + + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); + pis.InputFunc = DoPresentation; +@@ -909,7 +932,9 @@ + pis.MovieFrame = -1; + pis.StartTime = GetTimeCounter (); + pis.LastSyncTime = pis.StartTime; ++ TFB_SetOnScreenKeyboard_Hidden (); + DoInput (&pis, TRUE); ++ TFB_SetOnScreenKeyboard_Menu(); + + SleepThreadUntil (FadeMusic (0, ONE_SECOND)); + StopMusic (); +@@ -1001,7 +1026,9 @@ + vis.InputFunc = DoVideoInput; + vis.CurVideo = ref; + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); ++ TFB_SetOnScreenKeyboard_Hidden (); + DoInput (&vis, TRUE); ++ TFB_SetOnScreenKeyboard_Menu (); + + StopLegacyVideo (ref); + FadeClearScreen (); +@@ -1017,10 +1044,11 @@ + { + return FALSE; + } ++ + if (!strcmp (resType, "STRTAB")) + { + STRING pres = CaptureStringTable (LoadStringTable (res)); +- BOOLEAN result = ShowSlidePresentation (pres); ++ BOOLEAN result = ShowSlidePresentation (pres, res, FALSE); + DestroyStringTable (ReleaseStringTable (pres)); + return result; + } +Index: uqm/globdata.c +=================================================================== +--- uqm/globdata.c (revision 1353) ++++ uqm/globdata.c (working copy) +@@ -130,7 +130,7 @@ + OldContext = SetContext (RadarContext); + SetContextFGFrame (Screen); + r.corner.x = RADAR_X; +- r.corner.y = RADAR_Y; ++ r.corner.y = RADAR_Y_LIFTED_UP; + r.extent.width = RADAR_WIDTH; + r.extent.height = RADAR_HEIGHT; + SetContextClipRect (&r); +Index: uqm/shipyard.c +=================================================================== +--- uqm/shipyard.c (revision 1353) ++++ uqm/shipyard.c (working copy) +@@ -212,9 +212,9 @@ + OldContext = SetContext (StatusContext); + GetContextClipRect (&r); + s.origin.x = RADAR_X - r.corner.x; +- s.origin.y = RADAR_Y - r.corner.y; ++ s.origin.y = RADAR_Y_LIFTED_UP - r.corner.y; + r.corner.x = s.origin.x - 1; +- r.corner.y = s.origin.y - RES_CASE(11,24,33); // JMS_GFX ++ r.corner.y = s.origin.y - RES_CASE(1,2,3); // JMS_GFX + r.extent.width = RADAR_WIDTH + 2; + r.extent.height = RES_CASE(11,24,33); // JMS_GFX + BatchGraphics (); +@@ -242,8 +242,6 @@ + hStarShip = GetAvailableRaceFromIndex (NewRaceItem); + NewRaceItem = GetIndexFromStarShip (&GLOBAL (avail_race_q), + hStarShip); +- s.frame = SetAbsFrameIndex (pMS->ModuleFrame, 3 + NewRaceItem); +- DrawStamp (&s); + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + s.frame = FleetPtr->melee_icon; + UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); +@@ -253,6 +251,12 @@ + s.origin.x += (RADAR_WIDTH >> 1); + s.origin.y += (RADAR_HEIGHT >> 1); + DrawStamp (&s); ++ // Draw the ship name, above the ship image. ++ s.origin.x -= (RADAR_WIDTH >> 1); ++ s.origin.y -= (RADAR_HEIGHT >> 2); ++ s.frame = SetAbsFrameIndex (pMS->ModuleFrame, 3 + NewRaceItem); ++ DrawStamp (&s); ++ + t.align = ALIGN_RIGHT; + t.CharCount = (COUNT)~0; + t.pStr = buf; +Index: uqm/confirm.c +=================================================================== +--- uqm/confirm.c (revision 1353) ++++ uqm/confirm.c (working copy) +@@ -34,9 +34,11 @@ + #include + + +-#define CONFIRM_WIN_WIDTH (80 << RESOLUTION_FACTOR) // JMS_GFX ++#define CONFIRM_WIN_WIDTH (160 << RESOLUTION_FACTOR) // JMS_GFX + #define CONFIRM_WIN_HEIGHT (22 << RESOLUTION_FACTOR) // JMS_GFX + ++BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu = FALSE; ++ + static void + DrawConfirmationWindow (BOOLEAN answer) + { +@@ -67,6 +69,8 @@ + font_DrawText (&t); + t.baseline.x += (r.extent.width >> 1); + t.pStr = GAME_STRING (QUITMENU_STRING_BASE + 2); // "No" ++ if (GLOBAL (CurrentActivity) & IN_BATTLE) ++ t.pStr = "Escape unit"; // GAME_STRING (QUITMENU_STRING_BASE + 3); // TODO: modify gamestrings.txt + SetContextForeGroundColor (answer ? MENU_TEXT_COLOR : MENU_HIGHLIGHT_COLOR); + font_DrawText (&t); + +@@ -111,8 +115,16 @@ + + FlushInput (); + done = FALSE; ++ ++ #ifdef ANDROID ++ if ( !(GLOBAL (CurrentActivity) & IN_BATTLE) ) { ++ /* Abort immediately */ ++ response = TRUE; ++ done = TRUE; ++ } ++ #endif + +- do { ++ while (!done) { + // Forbid recursive calls or pausing here! + ExitRequested = FALSE; + GamePaused = FALSE; +@@ -139,7 +151,7 @@ + PlayMenuSound (MENU_SOUND_MOVE); + } + SleepThread (ONE_SECOND / 30); +- } while (!done); ++ } + + // Restore the screen under the confirmation window + DrawStamp (&s); +@@ -152,6 +164,8 @@ + } + else + { ++ if (GLOBAL (CurrentActivity) & IN_BATTLE) ++ EmergencyEscapeWarpUnitActivatedFromMenu = TRUE; + result = FALSE; + } + ExitRequested = FALSE; +Index: uqm/sis.c +=================================================================== +--- uqm/sis.c (revision 1353) ++++ uqm/sis.c (working copy) +@@ -1810,7 +1810,7 @@ + GetContextClipRect (&clip_r); + pRect = &temp_r; + temp_r.corner.x = RADAR_X - clip_r.corner.x; +- temp_r.corner.y = RADAR_Y - clip_r.corner.y; ++ temp_r.corner.y = RADAR_Y_LIFTED_UP - clip_r.corner.y; + temp_r.extent.width = RADAR_WIDTH; + temp_r.extent.height = RADAR_HEIGHT; + SetContext (ScreenContext); +Index: uqm/intel.c +=================================================================== +--- uqm/intel.c (revision 1353) ++++ uqm/intel.c (working copy) +@@ -45,10 +45,10 @@ + // Allow a player to warp-escape in cyborg mode + if (StarShipPtr->playerNr == RPG_PLAYER_NUM) + InputState |= CurrentInputToBattleInput ( +- context->playerNr) & BATTLE_ESCAPE; ++ context->playerNr, -1) & BATTLE_ESCAPE; + } + else +- InputState = CurrentInputToBattleInput (context->playerNr); ++ InputState = CurrentInputToBattleInput (context->playerNr, -1); + } + else if (!(PlayerControl[context->playerNr] & PSYTRON_CONTROL)) + InputState = 0; +Index: uqm/battle.c +=================================================================== +--- uqm/battle.c (revision 1353) ++++ uqm/battle.c (working copy) +@@ -16,6 +16,10 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++#ifdef ANDROID ++#include ++#endif ++ + #include "battle.h" + + #include "battlecontrols.h" +@@ -43,6 +47,8 @@ + #include "libs/graphics/gfx_common.h" + #include "libs/log.h" + #include "libs/mathlib.h" ++#include "globdata.h" ++#include "libs/input/sdl/vcontrol.h" + + + BYTE battle_counter[NUM_SIDES]; +@@ -137,7 +143,8 @@ + frameInputHuman (HumanInputContext *context, STARSHIP *StarShipPtr) + { + (void) StarShipPtr; +- return CurrentInputToBattleInput (context->playerNr); ++ ++ return CurrentInputToBattleInput (context->playerNr, StarShipPtr ? StarShipPtr->ShipFacing : -1); + } + + static void +@@ -207,8 +214,11 @@ + StarShipPtr->ship_input_state |= SPECIAL; + + if (CanRunAway && cur_player == 0 && +- (InputState & BATTLE_ESCAPE)) ++ ((InputState & BATTLE_ESCAPE) || EmergencyEscapeWarpUnitActivatedFromMenu)) ++ { ++ EmergencyEscapeWarpUnitActivatedFromMenu = FALSE; + DoRunAway (StarShipPtr); ++ } + } + } + +@@ -399,6 +409,11 @@ + + LockMutex (GraphicsLock); + ++ TFB_SetOnScreenKeyboard_Melee (); ++ if (PlayerControl[1] & HUMAN_CONTROL) { ++ TFB_SetOnScreenKeyboard_TwoPlayersMelee (); ++ } ++ + #if !(DEMO_MODE || CREATE_JOURNAL) + if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) { + // In Supermelee, the RNG is already initialised. +@@ -512,6 +527,8 @@ + UninitShips (); + FreeBattleSong (); + ++ TFB_SetOnScreenKeyboard_Menu (); ++ + UnlockMutex (GraphicsLock); + + return (BOOLEAN) (num_ships < 0); +Index: uqm/getchar.c +=================================================================== +--- uqm/getchar.c (revision 1353) ++++ uqm/getchar.c (working copy) +@@ -27,7 +27,11 @@ + #include "resinst.h" + #include "nameref.h" + ++#ifdef __ANDROID__ ++#include ++#endif + ++ + // TODO: This may be better done with UniChar at the cost of a tiny bit + // of overhead to convert UniChar back to UTF8 string. This overhead + // will probably be offset by removal of looped string-compare overhead ;) +@@ -141,6 +145,11 @@ + { // init basic vars + int lwlen; + ++#ifdef __ANDROID__ ++ SDL_ANDROID_ToggleScreenKeyboardTextInput (pTES->BaseStr); ++ pTES->BaseStr[0] = 0; ++#endif ++ + pTES->InputFunc = DoTextEntry; + pTES->Success = FALSE; + pTES->Initialized = TRUE; +@@ -198,7 +207,6 @@ + CacheInsPt = pTES->InsPt; + CacheCursorPos = pTES->CursorPos; + memcpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize); +- + // process the pending character buffer + ch = GetNextCharacter (); + if (!ch && PulsedInputState.menu[KEY_MENU_ANY]) +Index: uqm/starcon.c +=================================================================== +--- uqm/starcon.c (revision 1353) ++++ uqm/starcon.c (working copy) +@@ -240,6 +240,7 @@ + if (LastActivity == (CHECK_LOAD | CHECK_RESTART)) + AskNameForCaptainAndShip(); + ++ TFB_SetOnScreenKeyboard_Melee (); + do + { + #ifdef DEBUG +Index: uqm/outfit.c +=================================================================== +--- uqm/outfit.c (revision 1353) ++++ uqm/outfit.c (working copy) +@@ -59,7 +59,7 @@ + OldContext = SetContext (StatusContext); + GetContextClipRect (&r); + s.origin.x = RADAR_X - r.corner.x; +- s.origin.y = RADAR_Y - r.corner.y - 19 * RESOLUTION_FACTOR; // JMS_GFX; ++ s.origin.y = RADAR_Y_LIFTED_UP - r.corner.y + RES_CASE(10,6,12); // JMS_GFX; + r.corner.x = s.origin.x - 1; + r.corner.y = s.origin.y - 11; + r.extent.width = RADAR_WIDTH + 2; +Index: uqm/status.c +=================================================================== +--- uqm/status.c (revision 1353) ++++ uqm/status.c (working copy) +@@ -328,7 +328,7 @@ + StarShipPtr->RaceDescPtr->characteristics.energy_wait; + + DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], +- 0, energy_delta); ++ 0, energy_delta, StarShipPtr->playerNr); + } + + return (retval); +@@ -370,7 +370,7 @@ + } + + DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], +- crew_delta, 0); ++ crew_delta, 0, StarShipPtr->playerNr); + + return (retval); + } +Index: uqm/status.h +=================================================================== +--- uqm/status.h (revision 1353) ++++ uqm/status.h (working copy) +@@ -36,9 +36,15 @@ + #define CAPTAIN_HEIGHT RES_STAT_SCALE(30) // JMS_GFX + #define CAPTAIN_XOFFS ((STATUS_WIDTH - CAPTAIN_WIDTH) >> 1) // JMS_GFX + #define CAPTAIN_YOFFS (SHIP_INFO_HEIGHT + (4 << RESOLUTION_FACTOR)) // JMS_GFX +-#define SHIP_STATUS_HEIGHT (STATUS_HEIGHT >> 1) +-#define BAD_GUY_YOFFS 0 +-#define GOOD_GUY_YOFFS SHIP_STATUS_HEIGHT ++#define SHIP_STATUS_HEIGHT ((STATUS_HEIGHT >> 1) - (17 << RESOLUTION_FACTOR)) ++#define BAD_GUY_YOFFS (-1 << RESOLUTION_FACTOR) ++#define GOOD_GUY_YOFFS (STATUS_HEIGHT - SHIP_STATUS_HEIGHT) ++#define HORIZ_CREW_ENERGY_SIZE (18 << RESOLUTION_FACTOR) ++#define HORIZ_CREW_XOFFS (2 << RESOLUTION_FACTOR) ++#define BAD_GUY_HORIZ_CREW_YOFFS (BAD_GUY_YOFFS + SHIP_STATUS_HEIGHT + (HORIZ_CREW_ENERGY_SIZE >> 1)) ++#define GOOD_GUY_HORIZ_CREW_YOFFS (GOOD_GUY_YOFFS - HORIZ_CREW_ENERGY_SIZE + (1 << RESOLUTION_FACTOR)) ++#define BAD_GUY_HORIZ_ENERGY_YOFFS (BAD_GUY_YOFFS + SHIP_STATUS_HEIGHT) ++#define GOOD_GUY_HORIZ_ENERGY_YOFFS (GOOD_GUY_YOFFS - (HORIZ_CREW_ENERGY_SIZE >> 1) + (1 << RESOLUTION_FACTOR)) + #define STARCON_TEXT_HEIGHT (7 << RESOLUTION_FACTOR) // JMS_GFX + #define TINY_TEXT_HEIGHT (9 << RESOLUTION_FACTOR) // JMS_GFX + #define BATTLE_CREW_X RES_STAT_SCALE(10) // JMS_GFX +@@ -54,7 +60,7 @@ + extern void InitShipStatus (SHIP_INFO *ShipInfoPtr, STARSHIP *StarShipPtr, RECT *pClipRect, BOOLEAN inMeleeMenu); + // StarShipPtr or pClipRect can be NULL + extern void DeltaStatistics (SHIP_INFO *ShipInfoPtr, COORD y_offs, +- SIZE crew_delta, SIZE energy_delta); ++ SIZE crew_delta, SIZE energy_delta, SIZE player_num); + extern void DrawBattleCrewAmount (SHIP_INFO *ShipInfoPtr, COORD y_offs); + + extern void DrawCaptainsWindow (STARSHIP *StarShipPtr); +Index: uqm/controls.h +=================================================================== +--- uqm/controls.h (revision 1353) ++++ uqm/controls.h (working copy) +@@ -32,6 +32,7 @@ + KEY_WEAPON, + KEY_SPECIAL, + KEY_ESCAPE, ++ KEY_THRUST, + NUM_KEYS + }; + enum { +@@ -90,13 +91,14 @@ + #define BATTLE_ESCAPE ((BATTLE_INPUT_STATE)(1 << 5)) + #define BATTLE_DOWN ((BATTLE_INPUT_STATE)(1 << 6)) + +-BATTLE_INPUT_STATE CurrentInputToBattleInput (COUNT player); ++BATTLE_INPUT_STATE CurrentInputToBattleInput (COUNT player, int direction /* = -1 for no directional input */); + BATTLE_INPUT_STATE PulsedInputToBattleInput (COUNT player); + + extern CONTROLLER_INPUT_STATE CurrentInputState; + extern CONTROLLER_INPUT_STATE PulsedInputState; + extern volatile CONTROLLER_INPUT_STATE ImmediateInputState; + extern CONTROL_TEMPLATE PlayerControls[]; ++extern BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu; + + void UpdateInputState (void); + extern void FlushInput (void); +@@ -116,6 +118,8 @@ + BOOLEAN WaitForNoInput (TimePeriod duration, BOOLEAN resetInput); + BOOLEAN WaitForNoInputUntil (TimeCount timeOut, BOOLEAN resetInput); + ++extern BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction, int player); ++ + void DoPopupWindow(const char *msg); + + typedef void (InputFrameCallback) (void); +Index: svnversion.h +=================================================================== +--- svnversion.h (revision 1353) ++++ svnversion.h (working copy) +@@ -1 +1 @@ +-#define UQMHD_SVN_REVISION "1337M" ++#define UQMHD_SVN_REVISION "1351M" +Index: options.c +=================================================================== +--- options.c (revision 1353) ++++ options.c (working copy) +@@ -67,6 +67,7 @@ + BOOLEAN optRotatingIpPlanets; + BOOLEAN optTexturedIpPlanets; + BOOLEAN optCheatMode; ++BOOLEAN optDirectionalJoystick; + + BOOLEAN opt3doMusic; + BOOLEAN optRemixMusic; +@@ -480,6 +481,7 @@ + + for (i = 0; i < dirList->numNames; i++) + { ++ log_add (log_Info, "Mounting ZIP '%s'", dirList->names[i]); + if (uio_mountDir (repository, mountPoint, uio_FSTYPE_ZIP, + dirHandle, dirList->names[i], "/", autoMount, + relativeFlags | uio_MOUNT_RDONLY, +Index: options.h +=================================================================== +--- options.h (revision 1353) ++++ options.h (working copy) +@@ -54,6 +54,7 @@ + extern BOOLEAN optRotatingIpPlanets; + extern BOOLEAN optTexturedIpPlanets; + extern BOOLEAN optCheatMode; ++extern BOOLEAN optDirectionalJoystick; + + extern BOOLEAN opt3doMusic; + extern BOOLEAN optRemixMusic; +Index: uqm.c +=================================================================== +--- uqm.c (revision 1353) ++++ uqm.c (working copy) +@@ -63,6 +63,20 @@ + // Including this is actually necessary on OSX. + #endif + ++#if defined (__ANDROID__) ++# include ++static void AndroidAppPutToBackgroundCallback (void) ++{ ++ SDL_ANDROID_PauseAudioPlayback (); ++ GameActive = FALSE; ++} ++static void SDLCALL AndroidAppRestoredCallback (void) ++{ ++ SDL_ANDROID_ResumeAudioPlayback (); ++ GameActive = TRUE; ++} ++#endif ++ + struct bool_option + { + bool value; +@@ -138,6 +152,7 @@ + DECL_CONFIG_OPTION(bool, rotatingIpPlanets); // JMS + DECL_CONFIG_OPTION(bool, texturedIpPlanets); // JMS + DECL_CONFIG_OPTION(bool, cheatMode); // JMS ++ DECL_CONFIG_OPTION(bool, directionalJoystick); + + #define INIT_CONFIG_OPTION(name, val) \ + { val, false } +@@ -256,8 +271,8 @@ + INIT_CONFIG_OPTION( gamma, 0.0f ), + INIT_CONFIG_OPTION( soundDriver, audio_DRIVER_MIXSDL ), + INIT_CONFIG_OPTION( soundQuality, audio_QUALITY_MEDIUM ), +- INIT_CONFIG_OPTION( use3doMusic, true ), +- INIT_CONFIG_OPTION( useRemixMusic, false ), ++ INIT_CONFIG_OPTION( use3doMusic, false ), ++ INIT_CONFIG_OPTION( useRemixMusic, true ), + INIT_CONFIG_OPTION( whichCoarseScan, OPT_PC ), + INIT_CONFIG_OPTION( whichMenu, OPT_PC ), + INIT_CONFIG_OPTION( whichFonts, OPT_PC ), +@@ -269,17 +284,18 @@ + INIT_CONFIG_OPTION( stereoSFX, false ), + INIT_CONFIG_OPTION( musicVolumeScale, 1.0f ), + INIT_CONFIG_OPTION( sfxVolumeScale, 1.0f ), +- INIT_CONFIG_OPTION( speechVolumeScale, 0.3f ), ++ INIT_CONFIG_OPTION( speechVolumeScale, 0.7f ), + INIT_CONFIG_OPTION( safeMode, false ), +- INIT_CONFIG_OPTION( resolutionFactor, 2 ), ++ INIT_CONFIG_OPTION( resolutionFactor, 1 ), + INIT_CONFIG_OPTION( forceAspectRatio, false ), + INIT_CONFIG_OPTION( loresBlowupScale, 0 ), + INIT_CONFIG_OPTION( mainmenuMusic, true ), +- INIT_CONFIG_OPTION( mineralSubmenu, true ), ++ INIT_CONFIG_OPTION( mineralSubmenu, false ), + INIT_CONFIG_OPTION( nebulae, true ), + INIT_CONFIG_OPTION( rotatingIpPlanets, true), + INIT_CONFIG_OPTION( texturedIpPlanets, true), + INIT_CONFIG_OPTION( cheatMode, false ), ++ INIT_CONFIG_OPTION( directionalJoystick, true ), + }; + struct options_struct defaults = options; + int optionsResult; +@@ -346,6 +362,14 @@ + return optionsResult; + } + ++#if defined (ANDROID) ++ SDL_ANDROID_SetApplicationPutToBackgroundCallback (AndroidAppPutToBackgroundCallback, AndroidAppRestoredCallback); ++ if( !fileExists("config/save") ) { ++ // Copy savegames from UQM non-HD, I'm too lazy to do that properly. ++ system("SAVEDIR=`pwd`/config/save ; mkdir -p $SAVEDIR ; cd ../../../../app-data/com.sourceforge.sc2/config/save || exit 1 ; for f in * ; do cat $f > $SAVEDIR/$f ; done"); ++ } ++#endif ++ + TFB_PreInit (); + mem_init (); + InitThreadSystem (); +@@ -413,6 +437,7 @@ + optRotatingIpPlanets = options.rotatingIpPlanets.value; // JMS + optTexturedIpPlanets = options.texturedIpPlanets.value || optRotatingIpPlanets; // JMS + optCheatMode = options.cheatMode.value; // JMS ++ optDirectionalJoystick = options.directionalJoystick.value; + + prepareContentDir (options.contentDir, options.addonDir, argv[0]); + prepareMeleeDir (); +@@ -696,6 +721,7 @@ + getBoolConfigValue (&options->rotatingIpPlanets, "config.rotatingIpPlanets"); + getBoolConfigValue (&options->texturedIpPlanets, "config.texturedIpPlanets"); + getBoolConfigValue (&options->cheatMode, "config.cheatMode"); ++ getBoolConfigValue (&options->directionalJoystick, "config.directionaljoystick"); + + if (res_IsInteger ("config.player1control")) + { diff --git a/project/jni/shmem b/project/jni/shmem index c2a28f528..c46ed96dc 160000 --- a/project/jni/shmem +++ b/project/jni/shmem @@ -1 +1 @@ -Subproject commit c2a28f528d0b1b2528dda125e8fe8018609e7e9a +Subproject commit c46ed96dc63373ca46ecd026b25817266ce367ba