diff --git a/project/java/Settings.java b/project/java/Settings.java index 5d7a25156..8ac1dabcd 100644 --- a/project/java/Settings.java +++ b/project/java/Settings.java @@ -2360,10 +2360,20 @@ class Settings String readmes[] = Globals.ReadmeText.split("\\^"); String lang = new String(Locale.getDefault().getLanguage()) + ":"; String readme = readmes[0]; + String buttonName = "", buttonUrl = ""; for( String r: readmes ) { if( r.startsWith(lang) ) readme = r.substring(lang.length()); + if( r.startsWith("button:") ) + { + buttonName = r.substring("button:".length()); + if( buttonName.indexOf(":") != -1 ) + { + buttonUrl = buttonName.substring(buttonName.indexOf(":") + 1); + buttonName = buttonName.substring(0, buttonName.indexOf(":")); + } + } } readme = readme.trim(); if( readme.length() <= 2 ) @@ -2392,6 +2402,27 @@ class Settings layout.setOrientation(LinearLayout.VERTICAL); layout.addView(scroll); layout.addView(ok); + if( buttonName.length() > 0 ) + { + Button cancel = new Button(p); + cancel.setText(buttonName); + final String url = buttonUrl; + cancel.setOnClickListener(new View.OnClickListener() + { + public void onClick(View v) + { + if( url.length() > 0 ) + { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + p.startActivity(i); + } + alertDismiss[0].cancel(); + System.exit(0); + } + }); + layout.addView(cancel); + } builder.setView(layout); builder.setOnCancelListener(new DialogInterface.OnCancelListener() { diff --git a/project/jni/application/uqm-hd/AndroidAppSettings.cfg b/project/jni/application/uqm-hd/AndroidAppSettings.cfg index 595787892..b55e4d1b7 100644 --- a/project/jni/application/uqm-hd/AndroidAppSettings.cfg +++ b/project/jni/application/uqm-hd/AndroidAppSettings.cfg @@ -23,7 +23,7 @@ InhibitSuspend=n # If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir - # these files are put inside .apk package by build system # Also please avoid 'https://' URLs, many Android devices do not have trust certificates and will fail to connect to SF.net over HTTPS -AppDataDownloadUrl="!UQM music remix pack (240 Mb)|:addons/uqm-remix.uqm:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/uqm-remix.uqm/download^!Voice pack (120 Mb)|:addons/uqm-0.7.0-voice.uqm:http://sourceforge.net/projects/sc2/files/UQM/0.7/uqm-0.7.0-voice.uqm/download^3DO music (20 Mb)|:addons/uqm-0.7.0-3domusic.uqm:http://sourceforge.net/projects/sc2/files/UQM/0.7/uqm-0.7.0-3domusic.uqm/download^Russian translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/russian.zip/download^Deutsch translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/deutsch.zip/download^Spanish translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/spanish.zip/download^Slovak translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/slovak.zip/download^Finnish translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/finnish.zip/download^!!Game data (400 Mb)|:packages/uqm-content.uqm:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/uqm-hd-content-1.uqm/download^!!Game data|data.zip" +AppDataDownloadUrl="!UQM music remix pack (240 Mb)|:addons/uqm-remix.uqm:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/uqm-remix.uqm/download^!Voice pack (120 Mb)|:addons/uqm-0.7.0-voice.uqm:http://sourceforge.net/projects/sc2/files/UQM/0.7/uqm-0.7.0-voice.uqm/download^3DO music (20 Mb)|:addons/uqm-0.7.0-3domusic.uqm:http://sourceforge.net/projects/sc2/files/UQM/0.7/uqm-0.7.0-3domusic.uqm/download^Russian translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/russian.zip/download^Deutsch translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/deutsch.zip/download^Spanish translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/spanish.zip/download^Slovak translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/slovak.zip/download^Finnish translation|:addons/lang/shadow-content/lang.zip:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/translations/2/finnish.zip/download^!!Game data (520 Mb)|:packages/uqm-content.uqm:http://sourceforge.net/projects/libsdl-android/files/Ur-Quan%20Masters/uqm-hd-content-1.uqm/download^!!Game data|data.zip" # Video color depth - 16 BPP is the fastest and supported for all modes, 24 bpp is supported only # with SwVideoMode=y, SDL_OPENGL mode supports everything. (16)/(24)/(32) @@ -194,11 +194,11 @@ AppSubdirsBuild='src src/libs/* src/uqm/*' AppBuildExclude='src/libs/uio/hashtable.c src/libs/uio/memdebug.c src/libs/network/socket/socket_win.c src/libs/network/network_win.c src/libs/network/netmanager/netmanager_win.c src/libs/cdp/cdpapi.c src/libs/cdp/cdp.c src/libs/cdp/windl.c' # Application command line parameters, including app name as 0-th param -AppCmdline='uqm --addon lang -x -r 1280x960 -f --resfactor=2' +AppCmdline='uqm --addon lang -x -f' # Here you may type readme text, which will be shown during startup. Format is: # Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?) -ReadmeText='Tap joystick to turn off engines and rotate ship, tap once more to enable engines.\\\\nSecond screen joystick is available for two-player melee.' +ReadmeText='Tap joystick to turn off engines and rotate ship, tap once more to enable engines.\\\\nSecond screen joystick is available for two-player melee.\\\\nDo not select multiple translations, only one will work.\\\\nIf the game runs slowly - set 640x480 video mode from Setup menu.' # Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens # Minimum screen size that application supports: (s)mall / (m)edium / (l)arge diff --git a/project/jni/application/uqm-hd/android.diff b/project/jni/application/uqm-hd/android.diff index 8d1a83c0a..c462a3e96 100644 --- a/project/jni/application/uqm-hd/android.diff +++ b/project/jni/application/uqm-hd/android.diff @@ -1,777 +1,195 @@ -Index: uqm.c +Index: uqm/hyper.c =================================================================== ---- uqm.c (revision 1307) -+++ uqm.c (working copy) -@@ -63,6 +63,22 @@ - // Including this is actually necessary on OSX. - #endif +--- uqm/hyper.c (revision 1307) ++++ uqm/hyper.c (working copy) +@@ -1930,7 +1930,6 @@ + Color OldColor; + CONTEXT OldContext; + MENU_STATE MenuState; +- + UnbatchGraphics (); -+#if defined (ANDROID) -+# include -+static void AndroidAppPutToBackgroundCallback (void) -+{ -+ SDL_ANDROID_PauseAudioPlayback (); -+ GameActive = FALSE; -+ //GamePaused = TRUE; -+} -+static void SDLCALL AndroidAppRestoredCallback (void) -+{ -+ SDL_ANDROID_ResumeAudioPlayback (); -+ GameActive = TRUE; -+ //GamePaused = FALSE; -+} -+#endif -+ - struct bool_option - { - bool value; -@@ -256,8 +272,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 ), -@@ -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 (); -Index: libs/log/uqmlog.c + OldContext = SetContext (SpaceContext); +Index: uqm/intro.c =================================================================== ---- libs/log/uqmlog.c (revision 1307) -+++ libs/log/uqmlog.c (working copy) -@@ -23,6 +23,9 @@ - #include - #include - #include -+#ifdef ANDROID -+#include -+#endif - #include "libs/threadlib.h" +--- uqm/intro.c (revision 1307) ++++ uqm/intro.c (working copy) +@@ -909,7 +909,9 @@ + pis.MovieFrame = -1; + pis.StartTime = GetTimeCounter (); + pis.LastSyncTime = pis.StartTime; ++ TFB_SetOnScreenKeyboard_Hidden (); + DoInput (&pis, TRUE); ++ TFB_SetOnScreenKeyboard_Menu(); - #ifndef MAX_LOG_ENTRY_SIZE -@@ -190,6 +193,9 @@ - if ((int)level <= maxStreamLevel) + SleepThreadUntil (FadeMusic (0, ONE_SECOND)); + StopMusic (); +@@ -1001,7 +1003,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,6 +1021,7 @@ { - fprintf (streamOut, "%s\n", full_msg); -+#ifdef ANDROID -+ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); -+#endif + return FALSE; } - - if ((int)level <= maxLevel) -@@ -226,6 +232,9 @@ - if ((int)level <= maxStreamLevel) ++ + if (!strcmp (resType, "STRTAB")) { - fprintf (streamOut, "%s\n", full_msg); -+#ifdef ANDROID -+ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); -+#endif - } - - if ((int)level <= maxLevel) -Index: libs/log/msgbox_win.c + STRING pres = CaptureStringTable (LoadStringTable (res)); +Index: uqm/intel.c =================================================================== ---- libs/log/msgbox_win.c (revision 1307) -+++ libs/log/msgbox_win.c (working copy) -@@ -14,6 +14,7 @@ +--- uqm/intel.c (revision 1307) ++++ 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/menu.c +=================================================================== +--- uqm/menu.c (revision 1307) ++++ 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/controls.h +=================================================================== +--- uqm/controls.h (revision 1307) ++++ 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/battle.c +=================================================================== +--- uqm/battle.c (revision 1307) ++++ uqm/battle.c (working copy) +@@ -16,6 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+#ifndef ANDROID - #include "msgbox.h" - #define WIN32_LEAN_AND_MEAN - #include -@@ -64,4 +65,4 @@ - free (swTitle); - free (swMsg); - } -- -+#endif -Index: libs/log/msgbox_stub.c -=================================================================== ---- libs/log/msgbox_stub.c (revision 1307) -+++ libs/log/msgbox_stub.c (working copy) -@@ -16,6 +16,9 @@ - - #include "msgbox.h" - #include "loginternal.h" +#ifdef ANDROID +#include +#endif ++ + #include "battle.h" - 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 1307) -+++ libs/uio/io.c (working copy) -@@ -35,6 +35,7 @@ - #include "mem.h" - #include "uioutils.h" - #include "uioport.h" -+#include "../log.h" - #ifdef uio_MEM_DEBUG - # include "memdebug.h" - #endif -@@ -193,6 +194,7 @@ - errno = EINVAL; - return NULL; - } -+ log_add (log_Info, "uio_open %s", sourcePath); - handle = uio_open(sourceDir, sourcePath, - ((flags & uio_MOUNT_RDONLY) == uio_MOUNT_RDONLY ? - O_RDONLY : O_RDWR) -@@ -201,12 +203,14 @@ - #endif - , 0); - if (handle == NULL) { -+ log_add (log_Info, "uio_open failed for %s", sourcePath); - // errno is set - return NULL; - } - } + #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" - handler = uio_getFileSystemHandler(fsType); -+ log_add (log_Info, "uio_getFileSystemHandler %p", handler); - if (handler == NULL) { - if (handle) - uio_close(handle); -@@ -703,6 +707,7 @@ - &readMountInfo, &readPDirHandle, NULL, - &writeMountInfo, &writePDirHandle, NULL, &name) == -1) { - // errno is set -+ log_add (log_Info, "uio_open: uio_getPhysicalAccess failed for '%s'", path); - return NULL; - } - -@@ -729,6 +734,7 @@ - uio_PDirHandle_unref(readPDirHandle); - uio_PDirHandle_unref(writePDirHandle); - errno = EEXIST; -+ log_add (log_Info, "uio_open: O_CREAT | O_EXCL: file already exists '%s'", name); - return NULL; - } - if ((flags & O_TRUNC) == O_TRUNC) { -@@ -745,6 +751,7 @@ - uio_PDirHandle_unref(readPDirHandle); - uio_PDirHandle_unref(writePDirHandle); - errno = savedErrno; -+ log_add (log_Info, "uio_open: uio_copyFilePhysical failed '%s'", name); - return NULL; + + 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); ++ } } } -@@ -766,6 +773,7 @@ - handle = (pDirHandle->pRoot->handler->open)(pDirHandle, name, flags, mode); - // Also adds a new entry to the physical dir if appropriate. - if (handle == NULL) { -+ log_add (log_Info, "uio_open: open file failed '%s'", name); - int savedErrno = errno; - uio_free(name); - uio_PDirHandle_unref(pDirHandle); -Index: libs/uio/zip/zip.c -=================================================================== ---- libs/uio/zip/zip.c (revision 1307) -+++ libs/uio/zip/zip.c (working copy) -@@ -1366,6 +1366,10 @@ - gPFileData->gid = (uid_t) makeUInt16(buf[12], buf[13]); - break; - } -+ case 0x7875: // 'Unix string UID/GID' -+ // Just skip it -+ break; -+ - default: - #ifdef DEBUG - fprintf(stderr, "Debug: Extra field 0x%04x unsupported, " -Index: libs/md5/md5.c -=================================================================== ---- libs/md5/md5.c (revision 1307) -+++ libs/md5/md5.c (working copy) -@@ -21,7 +21,7 @@ - /* Written by Ulrich Drepper , 1995. */ +@@ -399,6 +409,11 @@ --#include -+#include "config.h" + LockMutex (GraphicsLock); - #include "md5.h" - -Index: libs/input/sdl/vcontrol.c -=================================================================== ---- libs/input/sdl/vcontrol.c (revision 1307) -+++ libs/input/sdl/vcontrol.c (working copy) -@@ -46,6 +46,7 @@ - typedef struct vcontrol_joystick_axis { - keybinding *neg, *pos; - int polarity; -+ int value; - } axis_type; - - typedef struct vcontrol_joystick_hat { -@@ -66,7 +67,7 @@ - - #endif /* HAVE_JOYSTICK */ - --static unsigned int joycount; -+static unsigned int joycount = 0; - static unsigned int num_sdl_keys = 0; - static keybinding **bindings = NULL; - -@@ -141,6 +142,7 @@ - for (j = 0; j < axes; j++) - { - x->axes[j].neg = x->axes[j].pos = NULL; -+ x->axes[j].polarity = x->axes[j].value = 0; - } - for (j = 0; j < hats; j++) - { -@@ -818,6 +820,7 @@ - int t; - if (!joysticks[port].stick) - return; -+ joysticks[port].axes[axis].value = value; - t = joysticks[port].threshold; - if (value > t) - { -@@ -894,6 +897,25 @@ - #endif /* HAVE_JOYSTICK */ - } - -+int -+VControl_GetJoyAxis(int port, int axis) -+{ -+#ifdef HAVE_JOYSTICK -+ if( joycount <= port ) -+ return 0; -+ if (!joysticks[port].stick || joysticks[port].numaxes <= axis ) -+ return 0; -+ return joysticks[port].axes[axis].value; -+#else -+ return 0; -+#endif /* HAVE_JOYSTICK */ -+}; -+ -+int VControl_GetJoysticksAmount() -+{ -+ return joycount; -+}; -+ - void - VControl_ResetInput (void) - { -Index: libs/input/sdl/vcontrol.h -=================================================================== ---- libs/input/sdl/vcontrol.h (revision 1307) -+++ 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); - -Index: libs/input/sdl/input.c -=================================================================== ---- libs/input/sdl/input.c (revision 1307) -+++ libs/input/sdl/input.c (working copy) -@@ -88,6 +88,7 @@ - "weapon", - "special", - "escape", -+ "thrust", - NULL - }; - -@@ -188,7 +189,7 @@ - directory. */ - LoadResourceIndex (contentDir, "uqm.key", "keys."); - } -- -+ - register_flight_controls (); - - return; -Index: libs/resource/filecntl.c -=================================================================== ---- libs/resource/filecntl.c (revision 1307) -+++ libs/resource/filecntl.c (working copy) -@@ -26,6 +26,7 @@ - #include "port.h" - #include "resintrn.h" - #include "libs/uio.h" -+#include "libs/log.h" - - uio_Stream * - res_OpenResFile (uio_DirHandle *dir, const char *filename, const char *mode) -@@ -34,7 +35,10 @@ - struct stat sb; - - if (uio_stat (dir, filename, &sb) == 0 && S_ISDIR(sb.st_mode)) -+ { -+ log_add (log_Debug, "res_OpenResFile('%s', '%s') - cannot open dir as file", filename, mode); - return ((uio_Stream *) ~0); ++ TFB_SetOnScreenKeyboard_Melee (); ++ if (PlayerControl[1] & HUMAN_CONTROL) { ++ TFB_SetOnScreenKeyboard_TwoPlayersMelee (); + } - - fp = uio_fopen (dir, filename, mode); - -Index: libs/sound/decoders/oggaud.c -=================================================================== ---- libs/sound/decoders/oggaud.c (revision 1307) -+++ libs/sound/decoders/oggaud.c (working copy) -@@ -270,7 +270,7 @@ - // this is the closest to a frame there is in ogg vorbis stream - // doesn't seem to be a func to retrive it - #ifdef OVCODEC_TREMOR -- return ova->vf.os->pageno; -+ return ova->vf.os.pageno; - #else - return ova->vf.os.pageno; - #endif /* OVCODEC_TREMOR */ -Index: libs/graphics/gfx_common.h -=================================================================== ---- libs/graphics/gfx_common.h (revision 1307) -+++ libs/graphics/gfx_common.h (working copy) -@@ -119,4 +119,10 @@ - extern int ScreenColorDepth; - extern int GraphicsDriver; - -+void TFB_SetOnScreenKeyboard_Hidden (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 1307) -+++ libs/graphics/sdl/sdl_common.c (working copy) -@@ -34,7 +34,11 @@ - #include "libs/memlib.h" - #include "libs/vidlib.h" - #include SDL_INCLUDE(SDL_thread.h) -+#ifdef ANDROID -+#include -+#endif + #if !(DEMO_MODE || CREATE_JOURNAL) + if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) { + // In Supermelee, the RNG is already initialised. +@@ -512,6 +527,8 @@ + UninitShips (); + FreeBattleSong (); -+ - SDL_Surface *SDL_Video; - SDL_Surface *SDL_Screen; - SDL_Surface *TransitionScreen; -@@ -199,6 +203,8 @@ - - atexit (TFB_UninitGraphics); - -+ TFB_InitOnScreenKeyboard (); -+ - return 0; - } - -@@ -635,3 +641,155 @@ - } - } - -+ -+#ifdef ANDROID -+ -+static SDL_Rect SDL_LeftJoystickRect, SDL_RightJoystickRect, SDL_TextInputRect; -+ -+void -+TFB_InitOnScreenKeyboard (void) -+{ -+ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); -+ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &SDL_RightJoystickRect); -+ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); -+ -+ /* TFB_SetOnScreenKeyboard_Hidden (); */ + TFB_SetOnScreenKeyboard_Menu (); -+} + -+void -+TFB_SetOnScreenKeyboard_Hidden (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ SDL_Rect b; -+ b.w = b.h = b.x = b.y = 0; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &b); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Menu (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ TFB_SetOnScreenKeyboard_Hidden(); -+ SDL_Rect b; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); -+ b.w = SDL_RightJoystickRect.w / 2; -+ b.h = SDL_RightJoystickRect.h / 2; -+ b.x = SDL_RightJoystickRect.x + b.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); -+ b.x = SDL_RightJoystickRect.x; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Starmap (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ TFB_SetOnScreenKeyboard_Menu(); -+ SDL_Rect b; -+ b.h = SDL_RightJoystickRect.h / 2; -+ b.w = SDL_RightJoystickRect.w / 2; -+ b.x = SDL_RightJoystickRect.x - b.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); -+ b.x -= b.w; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Melee (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ /* Make the on-screen buttons slightly overlap, so we can hit them with one finger */ -+ TFB_SetOnScreenKeyboard_Hidden(); -+ SDL_Rect b; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); -+ b.w = SDL_RightJoystickRect.w * 3 / 5; -+ b.h = SDL_RightJoystickRect.h * 3 / 5; -+ b.x = SDL_RightJoystickRect.x + SDL_RightJoystickRect.w - b.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; //SDL_RightJoystickRect.y; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); -+ b.x = SDL_RightJoystickRect.x; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); -+ // Throttle button is replaced by tapping joystick -+ /* -+ b.w = SDL_RightJoystickRect.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); -+ */ -+} -+ -+void -+TFB_SetOnScreenKeyboard_TwoPlayersMelee (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ /* Mirror the buttons */ -+ TFB_SetOnScreenKeyboard_Melee(); -+ SDL_Rect b = SDL_RightJoystickRect; -+ b.y = 0; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); -+ b.w = SDL_RightJoystickRect.w * 3 / 5; -+ b.h = SDL_RightJoystickRect.h * 3 / 5; -+ b.x = 0; -+ b.y = 0; // SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); -+ b.x = SDL_RightJoystickRect.w - b.w; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); -+ // Throttle button is replaced by tapping joystick -+ /* -+ b.w = SDL_RightJoystickRect.w; -+ b.x = 0; -+ b.y = 0; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); -+ */ -+} -+ -+#else -+ -+/* Stubs */ -+void -+TFB_InitOnScreenKeyboard (void) -+{ -+} -+ -+void -+TFB_SetOnScreenKeyboard_Hidden (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.h -=================================================================== ---- libs/graphics/sdl/sdl_common.h (revision 1307) -+++ libs/graphics/sdl/sdl_common.h (working copy) -@@ -50,4 +50,6 @@ - - SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface); - -+void TFB_InitOnScreenKeyboard (void); -+ - #endif -Index: libs/graphics/sdl/pure.c -=================================================================== ---- libs/graphics/sdl/pure.c (revision 1307) -+++ libs/graphics/sdl/pure.c (working copy) -@@ -128,6 +128,7 @@ - { - int i, videomode_flags; - SDL_PixelFormat conv_fmt; -+ int BPP = 32; + UnlockMutex (GraphicsLock); - GraphicsDriver = driver; - -@@ -169,6 +170,14 @@ - } - } - -+#ifdef ANDROID -+ videomode_flags = SDL_SWSURFACE; -+ //ScreenWidthActual = 1280; -+ //ScreenHeightActual = 960; -+ graphics_backend = &pure_unscaled_backend; -+ BPP = 24; -+#endif -+ - videomode_flags |= SDL_ANYFORMAT; - if (flags & TFB_GFXFLAGS_FULLSCREEN) - videomode_flags |= SDL_FULLSCREEN; -@@ -176,7 +185,7 @@ - /* We'll ask for a 32bpp frame, but it doesn't really matter, because we've set - SDL_ANYFORMAT */ - SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual, -- 32, videomode_flags); -+ BPP, videomode_flags); - - if (SDL_Video == NULL) - { -Index: uqm/shipstat.c + return (BOOLEAN) (num_ships < 0); +Index: uqm/supermelee/melee.c =================================================================== ---- uqm/shipstat.c (revision 1307) -+++ 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,20 @@ - 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 = 0; -+ r.corner.y = BAD_GUY_HORIZ_CREW_YOFFS; -+ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) -+ r.corner.y = GOOD_GUY_HORIZ_CREW_YOFFS; -+ r.extent.width = crew_height + 2; -+ r.extent.height = STAT_WIDTH + 2; -+ 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.extent.width = energy_height + 2; -+ DrawCrewEnergyBoxOutline (&r); - } - - if (!StarShipPtr || StarShipPtr->captains_name_index) -@@ -315,7 +368,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 +386,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 +400,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 +475,33 @@ - // Always print a number for the SIS in the full game. - DrawBattleCrewAmount (ShipInfoPtr, y_offs); +--- uqm/supermelee/melee.c (revision 1307) ++++ 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]); } -+ -+ 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 +537,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/gameinp.c =================================================================== --- uqm/gameinp.c (revision 1307) @@ -965,6 +383,60 @@ Index: uqm/gameinp.c + } + return InputState; +} +Index: uqm/status.c +=================================================================== +--- uqm/status.c (revision 1307) ++++ 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 1307) ++++ 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/planets/solarsys.c =================================================================== --- uqm/planets/solarsys.c (revision 1307) @@ -1085,19 +557,6 @@ Index: uqm/planets/lander.c if (!(GLOBAL (CurrentActivity) & CHECK_ABORT)) { -Index: uqm/menu.c -=================================================================== ---- uqm/menu.c (revision 1307) -+++ 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/confirm.c =================================================================== --- uqm/confirm.c (revision 1307) @@ -1160,167 +619,114 @@ Index: uqm/confirm.c result = FALSE; } ExitRequested = FALSE; -Index: uqm/hyper.c +Index: uqm/comm/syreen/syreenc.c =================================================================== ---- uqm/hyper.c (revision 1307) -+++ uqm/hyper.c (working copy) -@@ -1930,7 +1930,6 @@ - Color OldColor; - CONTEXT OldContext; - MENU_STATE MenuState; -- - UnbatchGraphics (); +--- uqm/comm/syreen/syreenc.c (revision 1307) ++++ uqm/comm/syreen/syreenc.c (working copy) +@@ -18,7 +18,7 @@ - OldContext = SetContext (SpaceContext); -Index: uqm/intro.c + #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/intro.c (revision 1307) -+++ uqm/intro.c (working copy) -@@ -909,7 +909,9 @@ - pis.MovieFrame = -1; - pis.StartTime = GetTimeCounter (); - pis.LastSyncTime = pis.StartTime; -+ TFB_SetOnScreenKeyboard_Hidden (); - DoInput (&pis, TRUE); -+ TFB_SetOnScreenKeyboard_Menu(); +--- uqm/comm/chmmr/chmmrc.c (revision 1307) ++++ uqm/comm/chmmr/chmmrc.c (working copy) +@@ -18,7 +18,7 @@ - SleepThreadUntil (FadeMusic (0, ONE_SECOND)); - StopMusic (); -@@ -1001,7 +1003,9 @@ - vis.InputFunc = DoVideoInput; - vis.CurVideo = ref; - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); -+ TFB_SetOnScreenKeyboard_Hidden (); - DoInput (&vis, TRUE); -+ TFB_SetOnScreenKeyboard_Menu (); + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../chmmr/strings.h" - StopLegacyVideo (ref); - FadeClearScreen (); -@@ -1017,6 +1021,7 @@ - { - return FALSE; - } -+ - if (!strcmp (resType, "STRTAB")) - { - STRING pres = CaptureStringTable (LoadStringTable (res)); -Index: uqm/starcon.c + #include "uqm/build.h" + #include "uqm/hyper.h" +Index: uqm/comm/slyland/slyland.c =================================================================== ---- uqm/starcon.c (revision 1307) -+++ uqm/starcon.c (working copy) -@@ -240,6 +240,7 @@ - if (LastActivity == (CHECK_LOAD | CHECK_RESTART)) - AskNameForCaptainAndShip(); - -+ TFB_SetOnScreenKeyboard_Melee (); - do - { - #ifdef DEBUG -Index: uqm/battle.c -=================================================================== ---- uqm/battle.c (revision 1307) -+++ uqm/battle.c (working copy) -@@ -16,6 +16,10 @@ +--- uqm/comm/slyland/slyland.c (revision 1307) ++++ uqm/comm/slyland/slyland.c (working copy) +@@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+#ifdef ANDROID -+#include -+#endif -+ - #include "battle.h" ++#include "../slyland/strings.h" ++#include + #include "../commall.h" +-#include + #include "resinst.h" +-#include "strings.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/controls.h + #include "options.h" + #include "uqm/battle.h" +Index: uqm/comm/ilwrath/ilwrathc.c =================================================================== ---- uqm/controls.h (revision 1307) -+++ 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)) +--- uqm/comm/ilwrath/ilwrathc.c (revision 1307) ++++ uqm/comm/ilwrath/ilwrathc.c (working copy) +@@ -18,7 +18,7 @@ --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); + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../ilwrath/strings.h" - extern CONTROLLER_INPUT_STATE CurrentInputState; - extern CONTROLLER_INPUT_STATE PulsedInputState; - extern volatile CONTROLLER_INPUT_STATE ImmediateInputState; - extern CONTROL_TEMPLATE PlayerControls[]; -+extern BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu; + #include "uqm/gameev.h" - void UpdateInputState (void); - extern void FlushInput (void); -@@ -116,6 +118,8 @@ - BOOLEAN WaitForNoInput (TimePeriod duration, BOOLEAN resetInput); - BOOLEAN WaitForNoInputUntil (TimeCount timeOut, BOOLEAN resetInput); +Index: uqm/comm/supox/supoxc.c +=================================================================== +--- uqm/comm/supox/supoxc.c (revision 1307) ++++ uqm/comm/supox/supoxc.c (working copy) +@@ -18,7 +18,7 @@ -+extern BATTLE_INPUT_STATE GetDirectionalJoystickInput(int direction, int player); -+ - void DoPopupWindow(const char *msg); + #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 1307) ++++ 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 1307) ++++ 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 1307) ++++ 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" - typedef void (InputFrameCallback) (void); Index: uqm/comm/pkunk/pkunkc.c =================================================================== --- uqm/comm/pkunk/pkunkc.c (revision 1307) @@ -1334,19 +740,6 @@ Index: uqm/comm/pkunk/pkunkc.c #include "uqm/build.h" #include "uqm/gameev.h" -Index: uqm/comm/spathi/spathic.c -=================================================================== ---- uqm/comm/spathi/spathic.c (revision 1307) -+++ 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 1307) @@ -1360,19 +753,19 @@ Index: uqm/comm/rebel/rebel.c #include "uqm/build.h" -Index: uqm/comm/druuge/druugec.c +Index: uqm/comm/arilou/arilouc.c =================================================================== ---- uqm/comm/druuge/druugec.c (revision 1307) -+++ uqm/comm/druuge/druugec.c (working copy) +--- uqm/comm/arilou/arilouc.c (revision 1307) ++++ uqm/comm/arilou/arilouc.c (working copy) @@ -18,7 +18,7 @@ #include "../commall.h" #include "resinst.h" -#include "strings.h" -+#include "../druuge/strings.h" ++#include "../arilou/strings.h" + + #include "uqm/gameev.h" - #include "uqm/build.h" - #include "uqm/setup.h" Index: uqm/comm/spahome/spahome.c =================================================================== --- uqm/comm/spahome/spahome.c (revision 1307) @@ -1438,19 +831,19 @@ Index: uqm/comm/talkpet/talkpet.c #include "uqm/build.h" -Index: uqm/comm/syreen/syreenc.c +Index: uqm/comm/thradd/thraddc.c =================================================================== ---- uqm/comm/syreen/syreenc.c (revision 1307) -+++ uqm/comm/syreen/syreenc.c (working copy) +--- uqm/comm/thradd/thraddc.c (revision 1307) ++++ uqm/comm/thradd/thraddc.c (working copy) @@ -18,7 +18,7 @@ #include "../commall.h" #include "resinst.h" -#include "strings.h" -+#include "../syreen/strings.h" ++#include "../thradd/strings.h" - #include "libs/sound/sound.h" #include "uqm/build.h" + #include "uqm/gameev.h" Index: uqm/comm/melnorm/melnorm.c =================================================================== --- uqm/comm/melnorm/melnorm.c (revision 1307) @@ -1490,6 +883,19 @@ Index: uqm/comm/orz/orzc.c #include "uqm/build.h" +Index: uqm/comm/urquan/urquanc.c +=================================================================== +--- uqm/comm/urquan/urquanc.c (revision 1307) ++++ 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 1307) @@ -1503,19 +909,6 @@ Index: uqm/comm/slyhome/slyhome.c #include "uqm/gameev.h" -Index: uqm/comm/zoqfot/zoqfotc.c -=================================================================== ---- uqm/comm/zoqfot/zoqfotc.c (revision 1307) -+++ 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/comandr/comandr.c =================================================================== --- uqm/comm/comandr/comandr.c (revision 1307) @@ -1555,211 +948,225 @@ Index: uqm/comm/mycon/myconc.c #include "uqm/gameev.h" #include "libs/mathlib.h" -Index: uqm/comm/arilou/arilouc.c +Index: uqm/comm/spathi/spathic.c =================================================================== ---- uqm/comm/arilou/arilouc.c (revision 1307) -+++ uqm/comm/arilou/arilouc.c (working copy) +--- uqm/comm/spathi/spathic.c (revision 1307) ++++ uqm/comm/spathi/spathic.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 1307) -+++ 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 1307) -+++ 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 1307) -+++ 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 1307) -+++ 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 1307) -+++ 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 1307) -+++ 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 "../spathi/strings.h" #include "uqm/build.h" -Index: uqm/comm/vux/vuxc.c +Index: uqm/comm/druuge/druugec.c =================================================================== ---- uqm/comm/vux/vuxc.c (revision 1307) -+++ uqm/comm/vux/vuxc.c (working copy) +--- uqm/comm/druuge/druugec.c (revision 1307) ++++ uqm/comm/druuge/druugec.c (working copy) @@ -18,7 +18,7 @@ #include "../commall.h" #include "resinst.h" -#include "strings.h" -+#include "../vux/strings.h" ++#include "../druuge/strings.h" - static LOCDATA vux_desc_1x = - { -Index: uqm/comm/shofixt/shofixt.c + #include "uqm/build.h" + #include "uqm/setup.h" +Index: uqm/shipstat.c =================================================================== ---- uqm/comm/shofixt/shofixt.c (revision 1307) -+++ 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/intel.c -=================================================================== ---- uqm/intel.c (revision 1307) -+++ 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/status.c -=================================================================== ---- uqm/status.c (revision 1307) -+++ 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); +--- uqm/shipstat.c (revision 1307) ++++ uqm/shipstat.c (working copy) +@@ -144,6 +144,45 @@ + DrawFilledRectangle (&r); } -Index: uqm/supermelee/melee.c -=================================================================== ---- uqm/supermelee/melee.c (revision 1307) -+++ 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/status.h -=================================================================== ---- uqm/status.h (revision 1307) -+++ 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) - RES_STAT_SCALE(17)) -+#define BAD_GUY_YOFFS RES_STAT_SCALE(-1) -+#define GOOD_GUY_YOFFS (STATUS_HEIGHT - SHIP_STATUS_HEIGHT) -+#define HORIZ_CREW_ENERGY_SIZE RES_STAT_SCALE(18) -+#define HORIZ_CREW_XOFFS RES_STAT_SCALE(2) -+#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 + RES_STAT_SCALE(1)) -+#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) + RES_STAT_SCALE(1)) - #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); ++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/starcon.c +=================================================================== +--- uqm/starcon.c (revision 1307) ++++ 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 1307) @@ -1772,3 +1179,672 @@ Index: options.c if (uio_mountDir (repository, mountPoint, uio_FSTYPE_ZIP, dirHandle, dirList->names[i], "/", autoMount, relativeFlags | uio_MOUNT_RDONLY, +Index: uqm.c +=================================================================== +--- uqm.c (revision 1307) ++++ uqm.c (working copy) +@@ -63,6 +63,22 @@ + // Including this is actually necessary on OSX. + #endif + ++#if defined (ANDROID) ++# include ++static void AndroidAppPutToBackgroundCallback (void) ++{ ++ SDL_ANDROID_PauseAudioPlayback (); ++ GameActive = FALSE; ++ //GamePaused = TRUE; ++} ++static void SDLCALL AndroidAppRestoredCallback (void) ++{ ++ SDL_ANDROID_ResumeAudioPlayback (); ++ GameActive = TRUE; ++ //GamePaused = FALSE; ++} ++#endif ++ + struct bool_option + { + bool value; +@@ -256,8 +272,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 ), +@@ -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 (); +Index: libs/log/msgbox_stub.c +=================================================================== +--- libs/log/msgbox_stub.c (revision 1307) ++++ 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 1307) ++++ libs/log/uqmlog.c (working copy) +@@ -23,6 +23,9 @@ + #include + #include + #include ++#ifdef ANDROID ++#include ++#endif + #include "libs/threadlib.h" + + #ifndef MAX_LOG_ENTRY_SIZE +@@ -190,6 +193,9 @@ + if ((int)level <= maxStreamLevel) + { + fprintf (streamOut, "%s\n", full_msg); ++#ifdef ANDROID ++ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); ++#endif + } + + if ((int)level <= maxLevel) +@@ -226,6 +232,9 @@ + if ((int)level <= maxStreamLevel) + { + fprintf (streamOut, "%s\n", full_msg); ++#ifdef ANDROID ++ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); ++#endif + } + + if ((int)level <= maxLevel) +Index: libs/log/msgbox_win.c +=================================================================== +--- libs/log/msgbox_win.c (revision 1307) ++++ libs/log/msgbox_win.c (working copy) +@@ -14,6 +14,7 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++#ifndef ANDROID + #include "msgbox.h" + #define WIN32_LEAN_AND_MEAN + #include +@@ -64,4 +65,4 @@ + free (swTitle); + free (swMsg); + } +- ++#endif +Index: libs/resource/filecntl.c +=================================================================== +--- libs/resource/filecntl.c (revision 1307) ++++ libs/resource/filecntl.c (working copy) +@@ -26,6 +26,7 @@ + #include "port.h" + #include "resintrn.h" + #include "libs/uio.h" ++#include "libs/log.h" + + uio_Stream * + res_OpenResFile (uio_DirHandle *dir, const char *filename, const char *mode) +@@ -34,7 +35,10 @@ + struct stat sb; + + if (uio_stat (dir, filename, &sb) == 0 && S_ISDIR(sb.st_mode)) ++ { ++ log_add (log_Debug, "res_OpenResFile('%s', '%s') - cannot open dir as file", filename, mode); + return ((uio_Stream *) ~0); ++ } + + fp = uio_fopen (dir, filename, mode); + +Index: libs/uio/zip/zip.c +=================================================================== +--- libs/uio/zip/zip.c (revision 1307) ++++ libs/uio/zip/zip.c (working copy) +@@ -1366,6 +1366,10 @@ + gPFileData->gid = (uid_t) makeUInt16(buf[12], buf[13]); + break; + } ++ case 0x7875: // 'Unix string UID/GID' ++ // Just skip it ++ break; ++ + default: + #ifdef DEBUG + fprintf(stderr, "Debug: Extra field 0x%04x unsupported, " +Index: libs/uio/io.c +=================================================================== +--- libs/uio/io.c (revision 1307) ++++ libs/uio/io.c (working copy) +@@ -35,6 +35,7 @@ + #include "mem.h" + #include "uioutils.h" + #include "uioport.h" ++#include "../log.h" + #ifdef uio_MEM_DEBUG + # include "memdebug.h" + #endif +@@ -193,6 +194,7 @@ + errno = EINVAL; + return NULL; + } ++ log_add (log_Info, "uio_open %s", sourcePath); + handle = uio_open(sourceDir, sourcePath, + ((flags & uio_MOUNT_RDONLY) == uio_MOUNT_RDONLY ? + O_RDONLY : O_RDWR) +@@ -201,12 +203,14 @@ + #endif + , 0); + if (handle == NULL) { ++ log_add (log_Info, "uio_open failed for %s", sourcePath); + // errno is set + return NULL; + } + } + + handler = uio_getFileSystemHandler(fsType); ++ log_add (log_Info, "uio_getFileSystemHandler %p", handler); + if (handler == NULL) { + if (handle) + uio_close(handle); +@@ -703,6 +707,7 @@ + &readMountInfo, &readPDirHandle, NULL, + &writeMountInfo, &writePDirHandle, NULL, &name) == -1) { + // errno is set ++ log_add (log_Info, "uio_open: uio_getPhysicalAccess failed for '%s'", path); + return NULL; + } + +@@ -729,6 +734,7 @@ + uio_PDirHandle_unref(readPDirHandle); + uio_PDirHandle_unref(writePDirHandle); + errno = EEXIST; ++ log_add (log_Info, "uio_open: O_CREAT | O_EXCL: file already exists '%s'", name); + return NULL; + } + if ((flags & O_TRUNC) == O_TRUNC) { +@@ -745,6 +751,7 @@ + uio_PDirHandle_unref(readPDirHandle); + uio_PDirHandle_unref(writePDirHandle); + errno = savedErrno; ++ log_add (log_Info, "uio_open: uio_copyFilePhysical failed '%s'", name); + return NULL; + } + } +@@ -766,6 +773,7 @@ + handle = (pDirHandle->pRoot->handler->open)(pDirHandle, name, flags, mode); + // Also adds a new entry to the physical dir if appropriate. + if (handle == NULL) { ++ log_add (log_Info, "uio_open: open file failed '%s'", name); + int savedErrno = errno; + uio_free(name); + uio_PDirHandle_unref(pDirHandle); +Index: libs/md5/md5.c +=================================================================== +--- libs/md5/md5.c (revision 1307) ++++ libs/md5/md5.c (working copy) +@@ -21,7 +21,7 @@ + + /* Written by Ulrich Drepper , 1995. */ + +-#include ++#include "config.h" + + #include "md5.h" + +Index: libs/input/sdl/vcontrol.h +=================================================================== +--- libs/input/sdl/vcontrol.h (revision 1307) ++++ 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); + +Index: libs/input/sdl/input.c +=================================================================== +--- libs/input/sdl/input.c (revision 1307) ++++ libs/input/sdl/input.c (working copy) +@@ -88,6 +88,7 @@ + "weapon", + "special", + "escape", ++ "thrust", + NULL + }; + +@@ -188,7 +189,7 @@ + directory. */ + LoadResourceIndex (contentDir, "uqm.key", "keys."); + } +- ++ + register_flight_controls (); + + return; +Index: libs/input/sdl/vcontrol.c +=================================================================== +--- libs/input/sdl/vcontrol.c (revision 1307) ++++ libs/input/sdl/vcontrol.c (working copy) +@@ -46,6 +46,7 @@ + typedef struct vcontrol_joystick_axis { + keybinding *neg, *pos; + int polarity; ++ int value; + } axis_type; + + typedef struct vcontrol_joystick_hat { +@@ -66,7 +67,7 @@ + + #endif /* HAVE_JOYSTICK */ + +-static unsigned int joycount; ++static unsigned int joycount = 0; + static unsigned int num_sdl_keys = 0; + static keybinding **bindings = NULL; + +@@ -141,6 +142,7 @@ + for (j = 0; j < axes; j++) + { + x->axes[j].neg = x->axes[j].pos = NULL; ++ x->axes[j].polarity = x->axes[j].value = 0; + } + for (j = 0; j < hats; j++) + { +@@ -818,6 +820,7 @@ + int t; + if (!joysticks[port].stick) + return; ++ joysticks[port].axes[axis].value = value; + t = joysticks[port].threshold; + if (value > t) + { +@@ -894,6 +897,25 @@ + #endif /* HAVE_JOYSTICK */ + } + ++int ++VControl_GetJoyAxis(int port, int axis) ++{ ++#ifdef HAVE_JOYSTICK ++ if( joycount <= port ) ++ return 0; ++ if (!joysticks[port].stick || joysticks[port].numaxes <= axis ) ++ return 0; ++ return joysticks[port].axes[axis].value; ++#else ++ return 0; ++#endif /* HAVE_JOYSTICK */ ++}; ++ ++int VControl_GetJoysticksAmount() ++{ ++ return joycount; ++}; ++ + void + VControl_ResetInput (void) + { +Index: libs/graphics/gfx_common.h +=================================================================== +--- libs/graphics/gfx_common.h (revision 1307) ++++ libs/graphics/gfx_common.h (working copy) +@@ -119,4 +119,10 @@ + extern int ScreenColorDepth; + extern int GraphicsDriver; + ++void TFB_SetOnScreenKeyboard_Hidden (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/pure.c +=================================================================== +--- libs/graphics/sdl/pure.c (revision 1307) ++++ libs/graphics/sdl/pure.c (working copy) +@@ -128,6 +128,7 @@ + { + int i, videomode_flags; + SDL_PixelFormat conv_fmt; ++ int BPP = 32; + + GraphicsDriver = driver; + +@@ -169,6 +170,14 @@ + } + } + ++#ifdef ANDROID ++ videomode_flags = SDL_SWSURFACE; ++ //ScreenWidthActual = 1280; ++ //ScreenHeightActual = 960; ++ graphics_backend = &pure_unscaled_backend; ++ BPP = 24; ++#endif ++ + videomode_flags |= SDL_ANYFORMAT; + if (flags & TFB_GFXFLAGS_FULLSCREEN) + videomode_flags |= SDL_FULLSCREEN; +@@ -176,7 +185,7 @@ + /* We'll ask for a 32bpp frame, but it doesn't really matter, because we've set + SDL_ANYFORMAT */ + SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual, +- 32, videomode_flags); ++ BPP, videomode_flags); + + if (SDL_Video == NULL) + { +Index: libs/graphics/sdl/sdl_common.c +=================================================================== +--- libs/graphics/sdl/sdl_common.c (revision 1307) ++++ libs/graphics/sdl/sdl_common.c (working copy) +@@ -34,7 +34,11 @@ + #include "libs/memlib.h" + #include "libs/vidlib.h" + #include SDL_INCLUDE(SDL_thread.h) ++#ifdef ANDROID ++#include ++#endif + ++ + SDL_Surface *SDL_Video; + SDL_Surface *SDL_Screen; + SDL_Surface *TransitionScreen; +@@ -199,6 +203,8 @@ + + atexit (TFB_UninitGraphics); + ++ TFB_InitOnScreenKeyboard (); ++ + return 0; + } + +@@ -635,3 +641,155 @@ + } + } + ++ ++#ifdef ANDROID ++ ++static SDL_Rect SDL_LeftJoystickRect, SDL_RightJoystickRect, SDL_TextInputRect; ++ ++void ++TFB_InitOnScreenKeyboard (void) ++{ ++ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); ++ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &SDL_RightJoystickRect); ++ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); ++ ++ /* TFB_SetOnScreenKeyboard_Hidden (); */ ++ TFB_SetOnScreenKeyboard_Menu (); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Hidden (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ SDL_Rect b; ++ b.w = b.h = b.x = b.y = 0; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &b); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Menu (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ TFB_SetOnScreenKeyboard_Hidden(); ++ SDL_Rect b; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); ++ b.w = SDL_RightJoystickRect.w / 2; ++ b.h = SDL_RightJoystickRect.h / 2; ++ b.x = SDL_RightJoystickRect.x + b.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); ++ b.x = SDL_RightJoystickRect.x; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Starmap (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ TFB_SetOnScreenKeyboard_Menu(); ++ SDL_Rect b; ++ b.h = SDL_RightJoystickRect.h / 2; ++ b.w = SDL_RightJoystickRect.w / 2; ++ b.x = SDL_RightJoystickRect.x - b.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); ++ b.x -= b.w; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Melee (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ /* Make the on-screen buttons slightly overlap, so we can hit them with one finger */ ++ TFB_SetOnScreenKeyboard_Hidden(); ++ SDL_Rect b; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); ++ b.w = SDL_RightJoystickRect.w * 3 / 5; ++ b.h = SDL_RightJoystickRect.h * 3 / 5; ++ b.x = SDL_RightJoystickRect.x + SDL_RightJoystickRect.w - b.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; //SDL_RightJoystickRect.y; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); ++ b.x = SDL_RightJoystickRect.x; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); ++ // Throttle button is replaced by tapping joystick ++ /* ++ b.w = SDL_RightJoystickRect.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); ++ */ ++} ++ ++void ++TFB_SetOnScreenKeyboard_TwoPlayersMelee (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ /* Mirror the buttons */ ++ TFB_SetOnScreenKeyboard_Melee(); ++ SDL_Rect b = SDL_RightJoystickRect; ++ b.y = 0; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); ++ b.w = SDL_RightJoystickRect.w * 3 / 5; ++ b.h = SDL_RightJoystickRect.h * 3 / 5; ++ b.x = 0; ++ b.y = 0; // SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); ++ b.x = SDL_RightJoystickRect.w - b.w; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); ++ // Throttle button is replaced by tapping joystick ++ /* ++ b.w = SDL_RightJoystickRect.w; ++ b.x = 0; ++ b.y = 0; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); ++ */ ++} ++ ++#else ++ ++/* Stubs */ ++void ++TFB_InitOnScreenKeyboard (void) ++{ ++} ++ ++void ++TFB_SetOnScreenKeyboard_Hidden (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.h +=================================================================== +--- libs/graphics/sdl/sdl_common.h (revision 1307) ++++ libs/graphics/sdl/sdl_common.h (working copy) +@@ -50,4 +50,6 @@ + + SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface); + ++void TFB_InitOnScreenKeyboard (void); ++ + #endif +Index: libs/sound/decoders/oggaud.c +=================================================================== +--- libs/sound/decoders/oggaud.c (revision 1307) ++++ libs/sound/decoders/oggaud.c (working copy) +@@ -270,7 +270,7 @@ + // this is the closest to a frame there is in ogg vorbis stream + // doesn't seem to be a func to retrive it + #ifdef OVCODEC_TREMOR +- return ova->vf.os->pageno; ++ return ova->vf.os.pageno; + #else + return ova->vf.os.pageno; + #endif /* OVCODEC_TREMOR */ +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 */ ++ diff --git a/project/jni/application/uqm/AndroidAppSettings.cfg b/project/jni/application/uqm/AndroidAppSettings.cfg index 088c63f26..3dfe607e3 100644 --- a/project/jni/application/uqm/AndroidAppSettings.cfg +++ b/project/jni/application/uqm/AndroidAppSettings.cfg @@ -198,7 +198,7 @@ AppCmdline='uqm --addon lang' # Here you may type readme text, which will be shown during startup. Format is: # Text in English, use \\\\n to separate lines^de:Text in Deutsch^ru:Text in Russian, and so on (that's four backslashes, nice isn't it?) -ReadmeText='Change in controls!\\\\nTap joystick to turn off engines and rotate ship, tap once more to enable engines.\\\\nSecond screen joystick added for two-player melee.' +ReadmeText='Change in controls! Tap joystick to turn off engines and rotate ship, tap once more to enable engines.\\\\nSecond screen joystick added for two-player melee.\\\\nUQM HD mod now available, with delicious 720p graphics.\\\\nDo not select multiple translations, only one will work.^button:UQM HD mod:https://play.google.com/store/apps/details?id=com.googlecode.uqm.hd' # Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens # Minimum screen size that application supports: (s)mall / (m)edium / (l)arge diff --git a/project/jni/application/uqm/android.diff b/project/jni/application/uqm/android.diff index cd1c48a38..869630fcb 100644 --- a/project/jni/application/uqm/android.diff +++ b/project/jni/application/uqm/android.diff @@ -1,3 +1,564 @@ +Index: libs/graphics/gfx_common.h +=================================================================== +--- libs/graphics/gfx_common.h (revision 3779) ++++ libs/graphics/gfx_common.h (working copy) +@@ -107,4 +107,10 @@ + extern int ScreenColorDepth; + extern int GraphicsDriver; + ++void TFB_SetOnScreenKeyboard_Hidden (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/pure.c +=================================================================== +--- libs/graphics/sdl/pure.c (revision 3779) ++++ libs/graphics/sdl/pure.c (working copy) +@@ -104,6 +104,7 @@ + { + int i, videomode_flags; + SDL_PixelFormat conv_fmt; ++ int BPP = 32; + + GraphicsDriver = driver; + +@@ -128,6 +129,14 @@ + "under pure SDL, using 640x480", width, height); + } + ++#ifdef ANDROID ++ videomode_flags = SDL_SWSURFACE; ++ ScreenWidthActual = 320; ++ ScreenHeightActual = 240; ++ graphics_backend = &pure_unscaled_backend; ++ BPP = 16; ++#endif ++ + videomode_flags |= SDL_ANYFORMAT; + if (flags & TFB_GFXFLAGS_FULLSCREEN) + videomode_flags |= SDL_FULLSCREEN; +@@ -135,7 +144,7 @@ + /* We'll ask for a 32bpp frame, but it doesn't really matter, because we've set + SDL_ANYFORMAT */ + SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual, +- 32, videomode_flags); ++ BPP, videomode_flags); + + if (SDL_Video == NULL) + { +Index: libs/graphics/sdl/sdl_common.c +=================================================================== +--- libs/graphics/sdl/sdl_common.c (revision 3779) ++++ libs/graphics/sdl/sdl_common.c (working copy) +@@ -34,7 +34,11 @@ + #include "libs/memlib.h" + #include "libs/vidlib.h" + #include SDL_INCLUDE(SDL_thread.h) ++#ifdef ANDROID ++#include ++#endif + ++ + SDL_Surface *SDL_Video; + SDL_Surface *SDL_Screen; + SDL_Surface *TransitionScreen; +@@ -172,6 +176,8 @@ + + TFB_DrawCanvas_Initialize (); + ++ TFB_InitOnScreenKeyboard (); ++ + return 0; + } + +@@ -397,3 +403,155 @@ + SDL_FreeSurface (*screen); + *screen = NULL; + } ++ ++#ifdef ANDROID ++ ++static SDL_Rect SDL_LeftJoystickRect, SDL_RightJoystickRect, SDL_TextInputRect; ++ ++void ++TFB_InitOnScreenKeyboard (void) ++{ ++ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); ++ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &SDL_RightJoystickRect); ++ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); ++ ++ /* TFB_SetOnScreenKeyboard_Hidden (); */ ++ TFB_SetOnScreenKeyboard_Menu (); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Hidden (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ SDL_Rect b; ++ b.w = b.h = b.x = b.y = 0; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &b); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Menu (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ TFB_SetOnScreenKeyboard_Hidden(); ++ SDL_Rect b; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); ++ b.w = SDL_RightJoystickRect.w / 2; ++ b.h = SDL_RightJoystickRect.h / 2; ++ b.x = SDL_RightJoystickRect.x + b.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); ++ b.x = SDL_RightJoystickRect.x; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Starmap (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ TFB_SetOnScreenKeyboard_Menu(); ++ SDL_Rect b; ++ b.h = SDL_RightJoystickRect.h / 2; ++ b.w = SDL_RightJoystickRect.w / 2; ++ b.x = SDL_RightJoystickRect.x - b.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); ++ b.x -= b.w; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); ++} ++ ++void ++TFB_SetOnScreenKeyboard_Melee (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ /* Make the on-screen buttons slightly overlap, so we can hit them with one finger */ ++ TFB_SetOnScreenKeyboard_Hidden(); ++ SDL_Rect b; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); ++ b.w = SDL_RightJoystickRect.w * 3 / 5; ++ b.h = SDL_RightJoystickRect.h * 3 / 5; ++ b.x = SDL_RightJoystickRect.x + SDL_RightJoystickRect.w - b.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; //SDL_RightJoystickRect.y; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); ++ b.x = SDL_RightJoystickRect.x; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); ++ // Throttle button is replaced by tapping joystick ++ /* ++ b.w = SDL_RightJoystickRect.w; ++ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); ++ */ ++} ++ ++void ++TFB_SetOnScreenKeyboard_TwoPlayersMelee (void) ++{ ++ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) ++ return; ++ /* Mirror the buttons */ ++ TFB_SetOnScreenKeyboard_Melee(); ++ SDL_Rect b = SDL_RightJoystickRect; ++ b.y = 0; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); ++ b.w = SDL_RightJoystickRect.w * 3 / 5; ++ b.h = SDL_RightJoystickRect.h * 3 / 5; ++ b.x = 0; ++ b.y = 0; // SDL_RightJoystickRect.h - b.h; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); ++ b.x = SDL_RightJoystickRect.w - b.w; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); ++ // Throttle button is replaced by tapping joystick ++ /* ++ b.w = SDL_RightJoystickRect.w; ++ b.x = 0; ++ b.y = 0; ++ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); ++ */ ++} ++ ++#else ++ ++/* Stubs */ ++void ++TFB_InitOnScreenKeyboard (void) ++{ ++} ++ ++void ++TFB_SetOnScreenKeyboard_Hidden (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.h +=================================================================== +--- libs/graphics/sdl/sdl_common.h (revision 3779) ++++ libs/graphics/sdl/sdl_common.h (working copy) +@@ -52,4 +52,6 @@ + int ReInit_Screen (SDL_Surface **screen, SDL_Surface *templat, int w, int h); + void UnInit_Screen (SDL_Surface **screen); + ++void TFB_InitOnScreenKeyboard (void); ++ + #endif +Index: libs/strings/getstr.c +=================================================================== +--- libs/strings/getstr.c (revision 3779) ++++ libs/strings/getstr.c (working copy) +@@ -72,7 +72,7 @@ + // returns FALSE if and only if the buffer needs to be enlarged but + // memory allocation failed. + static BOOLEAN +-ensureBufSize (char **buf, size_t *curSize, size_t minSize, size_t increment) ++ensureBufSize (char **buf, DWORD *curSize, DWORD minSize, DWORD increment) + { + char *newBuf; + size_t newSize; +Index: libs/input/sdl/vcontrol.h +=================================================================== +--- libs/input/sdl/vcontrol.h (revision 3779) ++++ 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); + +Index: libs/input/sdl/input.c +=================================================================== +--- libs/input/sdl/input.c (revision 3779) ++++ libs/input/sdl/input.c (working copy) +@@ -86,6 +86,7 @@ + "weapon", + "special", + "escape", ++ "thrust", + NULL + }; + +@@ -186,7 +187,7 @@ + directory. */ + LoadResourceIndex (contentDir, "uqm.key", "keys."); + } +- ++ + register_flight_controls (); + + return; +Index: libs/input/sdl/vcontrol.c +=================================================================== +--- libs/input/sdl/vcontrol.c (revision 3779) ++++ libs/input/sdl/vcontrol.c (working copy) +@@ -46,6 +46,7 @@ + typedef struct vcontrol_joystick_axis { + keybinding *neg, *pos; + int polarity; ++ int value; + } axis_type; + + typedef struct vcontrol_joystick_hat { +@@ -66,7 +67,7 @@ + + #endif /* HAVE_JOYSTICK */ + +-static unsigned int joycount; ++static unsigned int joycount = 0; + static unsigned int num_sdl_keys = 0; + static keybinding **bindings = NULL; + +@@ -141,6 +142,7 @@ + for (j = 0; j < axes; j++) + { + x->axes[j].neg = x->axes[j].pos = NULL; ++ x->axes[j].polarity = x->axes[j].value = 0; + } + for (j = 0; j < hats; j++) + { +@@ -818,6 +820,7 @@ + int t; + if (!joysticks[port].stick) + return; ++ joysticks[port].axes[axis].value = value; + t = joysticks[port].threshold; + if (value > t) + { +@@ -894,6 +897,25 @@ + #endif /* HAVE_JOYSTICK */ + } + ++int ++VControl_GetJoyAxis(int port, int axis) ++{ ++#ifdef HAVE_JOYSTICK ++ if( joycount <= port ) ++ return 0; ++ if (!joysticks[port].stick || joysticks[port].numaxes <= axis ) ++ return 0; ++ return joysticks[port].axes[axis].value; ++#else ++ return 0; ++#endif /* HAVE_JOYSTICK */ ++}; ++ ++int VControl_GetJoysticksAmount() ++{ ++ return joycount; ++}; ++ + void + VControl_ResetInput (void) + { +Index: libs/log/uqmlog.c +=================================================================== +--- libs/log/uqmlog.c (revision 3779) ++++ libs/log/uqmlog.c (working copy) +@@ -23,6 +23,9 @@ + #include + #include + #include ++#ifdef ANDROID ++#include ++#endif + #include "libs/threadlib.h" + + #ifndef MAX_LOG_ENTRY_SIZE +@@ -191,6 +194,9 @@ + if ((int)level <= maxStreamLevel) + { + fprintf (streamOut, "%s\n", full_msg); ++#ifdef ANDROID ++ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); ++#endif + } + + if ((int)level <= maxLevel) +@@ -227,6 +233,9 @@ + if ((int)level <= maxStreamLevel) + { + fprintf (streamOut, "%s\n", full_msg); ++#ifdef ANDROID ++ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); ++#endif + } + + if ((int)level <= maxLevel) +Index: libs/log/msgbox_win.c +=================================================================== +--- libs/log/msgbox_win.c (revision 3779) ++++ libs/log/msgbox_win.c (working copy) +@@ -14,6 +14,7 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + ++#ifndef ANDROID + #include "msgbox.h" + #define WIN32_LEAN_AND_MEAN + #include +@@ -64,4 +65,4 @@ + free (swTitle); + free (swMsg); + } +- ++#endif +Index: libs/log/msgbox_stub.c +=================================================================== +--- libs/log/msgbox_stub.c (revision 3779) ++++ 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/zip/zip.c +=================================================================== +--- libs/uio/zip/zip.c (revision 3779) ++++ libs/uio/zip/zip.c (working copy) +@@ -1366,6 +1366,10 @@ + gPFileData->gid = (uid_t) makeUInt16(buf[12], buf[13]); + break; + } ++ case 0x7875: // 'Unix string UID/GID' ++ // Just skip it ++ break; ++ + default: + #ifdef DEBUG + fprintf(stderr, "Debug: Extra field 0x%04x unsupported, " +Index: libs/uio/io.c +=================================================================== +--- libs/uio/io.c (revision 3779) ++++ libs/uio/io.c (working copy) +@@ -35,6 +35,7 @@ + #include "mem.h" + #include "uioutils.h" + #include "uioport.h" ++#include "../log.h" + #ifdef uio_MEM_DEBUG + # include "memdebug.h" + #endif +@@ -193,6 +194,7 @@ + errno = EINVAL; + return NULL; + } ++ log_add (log_Info, "uio_open %s", sourcePath); + handle = uio_open(sourceDir, sourcePath, + ((flags & uio_MOUNT_RDONLY) == uio_MOUNT_RDONLY ? + O_RDONLY : O_RDWR) +@@ -201,12 +203,14 @@ + #endif + , 0); + if (handle == NULL) { ++ log_add (log_Info, "uio_open failed for %s", sourcePath); + // errno is set + return NULL; + } + } + + handler = uio_getFileSystemHandler(fsType); ++ log_add (log_Info, "uio_getFileSystemHandler %p", handler); + if (handler == NULL) { + if (handle) + uio_close(handle); +@@ -800,6 +804,7 @@ + &readMountInfo, &readPDirHandle, NULL, + &writeMountInfo, &writePDirHandle, NULL, &name) == -1) { + // errno is set ++ log_add (log_Info, "uio_open: uio_getPhysicalAccess failed for '%s'", path); + return NULL; + } + +@@ -826,6 +831,7 @@ + uio_PDirHandle_unref(readPDirHandle); + uio_PDirHandle_unref(writePDirHandle); + errno = EEXIST; ++ log_add (log_Info, "uio_open: O_CREAT | O_EXCL: file already exists '%s'", name); + return NULL; + } + if ((flags & O_TRUNC) == O_TRUNC) { +@@ -842,6 +848,7 @@ + uio_PDirHandle_unref(readPDirHandle); + uio_PDirHandle_unref(writePDirHandle); + errno = savedErrno; ++ log_add (log_Info, "uio_open: uio_copyFilePhysical failed '%s'", name); + return NULL; + } + } +@@ -863,6 +870,7 @@ + handle = (pDirHandle->pRoot->handler->open)(pDirHandle, name, flags, mode); + // Also adds a new entry to the physical dir if appropriate. + if (handle == NULL) { ++ log_add (log_Info, "uio_open: open file failed '%s'", name); + int savedErrno = errno; + uio_free(name); + uio_PDirHandle_unref(pDirHandle); +Index: libs/md5/md5.c +=================================================================== +--- libs/md5/md5.c (revision 3779) ++++ libs/md5/md5.c (working copy) +@@ -21,7 +21,7 @@ + + /* Written by Ulrich Drepper , 1995. */ + +-#include ++#include "config.h" + + #include "md5.h" + +Index: libs/resource/filecntl.c +=================================================================== +--- libs/resource/filecntl.c (revision 3779) ++++ libs/resource/filecntl.c (working copy) +@@ -26,6 +26,7 @@ + #include "port.h" + #include "resintrn.h" + #include "libs/uio.h" ++#include "libs/log.h" + + uio_Stream * + res_OpenResFile (uio_DirHandle *dir, const char *filename, const char *mode) +@@ -34,7 +35,10 @@ + struct stat sb; + + if (uio_stat (dir, filename, &sb) == 0 && S_ISDIR(sb.st_mode)) ++ { ++ log_add (log_Debug, "res_OpenResFile('%s', '%s') - cannot open dir as file", filename, mode); + return ((uio_Stream *) ~0); ++ } + + fp = uio_fopen (dir, filename, mode); + +Index: libs/sound/decoders/oggaud.c +=================================================================== +--- libs/sound/decoders/oggaud.c (revision 3779) ++++ libs/sound/decoders/oggaud.c (working copy) +@@ -270,7 +270,7 @@ + // this is the closest to a frame there is in ogg vorbis stream + // doesn't seem to be a func to retrive it + #ifdef OVCODEC_TREMOR +- return ova->vf.os->pageno; ++ return ova->vf.os.pageno; + #else + return ova->vf.os.pageno; + #endif /* OVCODEC_TREMOR */ Index: config_unix.h =================================================================== --- config_unix.h (revision 0) @@ -66,43 +627,19 @@ Index: config_unix.h + +#endif /* _CONFIG_UNIX_H */ + -Index: uqm/controls.h +Index: uqm/menu.c =================================================================== ---- uqm/controls.h (revision 3779) -+++ uqm/controls.h (working copy) -@@ -36,6 +36,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); +--- uqm/menu.c (revision 3779) ++++ uqm/menu.c (working copy) +@@ -503,7 +503,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; ++ r.corner.y = s.origin.y - 40; + r.extent.width = RADAR_WIDTH + 2; + BatchGraphics (); + SetContextForeGroundColor ( Index: uqm/battle.c =================================================================== --- uqm/battle.c (revision 3779) @@ -170,19 +707,382 @@ Index: uqm/battle.c return (BOOLEAN) (num_ships < 0); } -Index: uqm/supermelee/melee.c +Index: uqm/hyper.c =================================================================== ---- uqm/supermelee/melee.c (revision 3779) -+++ uqm/supermelee/melee.c (working copy) -@@ -2074,7 +2074,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]); +--- uqm/hyper.c (revision 3779) ++++ uqm/hyper.c (working copy) +@@ -1685,7 +1685,6 @@ + Color OldColor; + CONTEXT OldContext; + MENU_STATE MenuState; +- + UnbatchGraphics (); + + OldContext = SetContext (SpaceContext); +Index: uqm/intro.c +=================================================================== +--- uqm/intro.c (revision 3779) ++++ uqm/intro.c (working copy) +@@ -751,7 +751,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 (); +@@ -839,7 +841,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 (); +@@ -855,6 +859,7 @@ + { + return FALSE; + } ++ + if (!strcmp (resType, "STRTAB")) + { + STRING pres = CaptureStringTable (LoadStringTable (res)); +Index: uqm/setupmenu.c +=================================================================== +--- uqm/setupmenu.c (revision 3779) ++++ uqm/setupmenu.c (working copy) +@@ -75,7 +75,7 @@ + #endif + + #define MENU_COUNT 8 +-#define CHOICE_COUNT 24 ++#define CHOICE_COUNT 25 + #define SLIDER_COUNT 4 + #define BUTTON_COUNT 10 + #define LABEL_COUNT 4 +@@ -98,7 +98,7 @@ + static int choice_widths[CHOICE_COUNT] = { + 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 2, 2, 3, 3, 2, 3, 3, +- 3, 2, 2, 2 }; ++ 3, 2, 2, 2, 2 }; + + static HANDLER button_handlers[BUTTON_COUNT] = { + quit_main_menu, quit_sub_menu, do_graphics, do_engine, +@@ -157,6 +157,7 @@ + (WIDGET *)(&choices[12]), + (WIDGET *)(&choices[15]), + (WIDGET *)(&choices[16]), ++ (WIDGET *)(&choices[24]), + (WIDGET *)(&buttons[1]), + NULL }; + +@@ -416,6 +417,7 @@ + choices[21].selected = opts.musicremix; + choices[22].selected = opts.speech; + choices[23].selected = opts.keepaspect; ++ choices[24].selected = opts.directionaljoystick; + + sliders[0].value = opts.musicvol; + sliders[1].value = opts.sfxvol; +@@ -450,6 +452,7 @@ + opts.musicremix = choices[21].selected; + opts.speech = choices[22].selected; + opts.keepaspect = choices[23].selected; ++ opts.directionaljoystick = choices[24].selected; + + opts.musicvol = sliders[0].value; + opts.sfxvol = sliders[1].value; +@@ -1277,6 +1280,7 @@ + opts->musicremix = optRemixMusic ? OPTVAL_ENABLED : OPTVAL_DISABLED; + opts->speech = optSpeech ? OPTVAL_ENABLED : OPTVAL_DISABLED; + opts->keepaspect = optKeepAspectRatio ? OPTVAL_ENABLED : OPTVAL_DISABLED; ++ opts->directionaljoystick = optDirectionalJoystick ? OPTVAL_ENABLED : OPTVAL_DISABLED; + switch (snddriver) { + case audio_DRIVER_OPENAL: + opts->adriver = OPTVAL_OPENAL; +@@ -1518,6 +1522,7 @@ + optWhichIntro = (opts->intro == OPTVAL_3DO) ? OPT_3DO : OPT_PC; + optStereoSFX = (opts->stereo == OPTVAL_ENABLED); + optKeepAspectRatio = (opts->keepaspect == OPTVAL_ENABLED); ++ optDirectionalJoystick = (opts->directionaljoystick == OPTVAL_ENABLED) ? TRUE : FALSE; + PlayerControls[0] = opts->player1; + PlayerControls[1] = opts->player2; + +@@ -1532,6 +1537,7 @@ + res_PutBoolean ("config.speech", opts->speech == OPTVAL_ENABLED); + res_PutBoolean ("config.3domovies", opts->intro == OPTVAL_3DO); + res_PutBoolean ("config.showfps", opts->fps == OPTVAL_ENABLED); ++ res_PutBoolean ("config.directionaljoystick", opts->directionaljoystick == OPTVAL_ENABLED); + res_PutBoolean ("config.smoothmelee", opts->meleezoom == OPTVAL_3DO); + res_PutBoolean ("config.positionalsfx", opts->stereo == OPTVAL_ENABLED); + res_PutBoolean ("config.pulseshield", opts->shield == OPTVAL_3DO); +Index: uqm/setupmenu.h +=================================================================== +--- uqm/setupmenu.h (revision 3779) ++++ uqm/setupmenu.h (working copy) +@@ -81,6 +81,7 @@ + OPT_ENABLABLE fullscreen, subtitles, scanlines, fps, stereo; + OPT_ENABLABLE music3do, musicremix, speech; + OPT_ENABLABLE keepaspect; ++ OPT_ENABLABLE directionaljoystick; + OPT_CONSOLETYPE menu, text, cscan, scroll, intro, meleezoom, shield; + CONTROL_TEMPLATE player1, player2; + int speechvol, musicvol, sfxvol; +Index: uqm/status.c +=================================================================== +--- uqm/status.c (revision 3779) ++++ uqm/status.c (working copy) +@@ -323,7 +323,7 @@ + StarShipPtr->RaceDescPtr->characteristics.energy_wait; + + DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], +- 0, energy_delta); ++ 0, energy_delta, StarShipPtr->playerNr); + } + + return (retval); +@@ -365,7 +365,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 3779) ++++ uqm/status.h (working copy) +@@ -38,9 +38,15 @@ + #define CAPTAIN_YOFFS (SHIP_INFO_HEIGHT + 4) + #define CAPTAIN_WIDTH 55 + #define CAPTAIN_HEIGHT 30 +-#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) ++#define BAD_GUY_YOFFS (-1) ++#define GOOD_GUY_YOFFS (STATUS_HEIGHT - SHIP_STATUS_HEIGHT) ++#define HORIZ_CREW_ENERGY_SIZE 18 ++#define HORIZ_CREW_XOFFS 2 ++#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) ++#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) + #define STARCON_TEXT_HEIGHT 7 + #define TINY_TEXT_HEIGHT 9 + +@@ -58,7 +64,7 @@ + RECT *pClipRect); + // 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/intel.c +=================================================================== +--- uqm/intel.c (revision 3779) ++++ 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/shipstat.c +=================================================================== +--- uqm/shipstat.c (revision 3779) ++++ uqm/shipstat.c (working copy) +@@ -132,6 +132,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) + { +@@ -229,6 +268,26 @@ + 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 = 0; ++ r.corner.y = BAD_GUY_HORIZ_CREW_YOFFS; ++ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) ++ r.corner.y = GOOD_GUY_HORIZ_CREW_YOFFS; ++ r.extent.height = STAT_WIDTH + 2; ++ r.extent.width = 1000; ++ SetContextForeGroundColor (BLACK_COLOR); ++ DrawFilledRectangle (&r); ++ r.extent.width = crew_height + 2; ++ 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.extent.width = 1000; ++ SetContextForeGroundColor (BLACK_COLOR); ++ DrawFilledRectangle (&r); ++ r.extent.width = energy_height + 2; ++ DrawCrewEnergyBoxOutline (&r); + } + + if (!StarShipPtr || StarShipPtr->captains_name_index) +@@ -288,7 +347,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 (); +@@ -306,10 +365,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; +@@ -319,13 +379,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); +@@ -392,10 +454,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) +@@ -431,6 +516,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/gameinp.c =================================================================== --- uqm/gameinp.c (revision 3779) @@ -376,242 +1276,149 @@ Index: uqm/gameinp.c + } + return InputState; +} -Index: uqm/status.c +Index: uqm/comm/talkpet/talkpet.c =================================================================== ---- uqm/status.c (revision 3779) -+++ uqm/status.c (working copy) -@@ -323,7 +323,7 @@ - StarShipPtr->RaceDescPtr->characteristics.energy_wait; +--- uqm/comm/talkpet/talkpet.c (revision 3779) ++++ uqm/comm/talkpet/talkpet.c (working copy) +@@ -18,7 +18,7 @@ - DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], -- 0, energy_delta); -+ 0, energy_delta, StarShipPtr->playerNr); - } + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../talkpet/strings.h" - return (retval); -@@ -365,7 +365,7 @@ - } + #include "uqm/build.h" - DeltaStatistics (ShipInfoPtr, status_y_offsets[StarShipPtr->playerNr], -- crew_delta, 0); -+ crew_delta, 0, StarShipPtr->playerNr); - - return (retval); - } -Index: uqm/status.h +Index: uqm/comm/syreen/syreenc.c =================================================================== ---- uqm/status.h (revision 3779) -+++ uqm/status.h (working copy) -@@ -38,9 +38,15 @@ - #define CAPTAIN_YOFFS (SHIP_INFO_HEIGHT + 4) - #define CAPTAIN_WIDTH 55 - #define CAPTAIN_HEIGHT 30 --#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) -+#define BAD_GUY_YOFFS (-1) -+#define GOOD_GUY_YOFFS (STATUS_HEIGHT - SHIP_STATUS_HEIGHT) -+#define HORIZ_CREW_ENERGY_SIZE 18 -+#define HORIZ_CREW_XOFFS 2 -+#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) -+#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) - #define STARCON_TEXT_HEIGHT 7 - #define TINY_TEXT_HEIGHT 9 +--- uqm/comm/syreen/syreenc.c (revision 3779) ++++ uqm/comm/syreen/syreenc.c (working copy) +@@ -18,7 +18,7 @@ -@@ -58,7 +64,7 @@ - RECT *pClipRect); - // 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); + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../syreen/strings.h" - extern void DrawCaptainsWindow (STARSHIP *StarShipPtr); -Index: uqm/planets/lander.c + #include "uqm/build.h" + #include "uqm/setup.h" +Index: uqm/comm/melnorm/melnorm.c =================================================================== ---- uqm/planets/lander.c (revision 3779) -+++ uqm/planets/lander.c (working copy) -@@ -1591,15 +1591,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; +--- uqm/comm/melnorm/melnorm.c (revision 3779) ++++ uqm/comm/melnorm/melnorm.c (working copy) +@@ -18,7 +18,7 @@ -- if (CurrentInputState.key[PlayerControls[0]][KEY_LEFT]) -+ if (InputState & BATTLE_LEFT) - --index; - else - ++index; -@@ -1623,7 +1623,7 @@ - turn_wait = SHUTTLE_TURN_WAIT; - } + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../melnorm/strings.h" -- if (!CurrentInputState.key[PlayerControls[0]][KEY_UP]) -+ if (!(InputState & BATTLE_THRUST)) - { - dx = 0; - dy = 0; -@@ -1938,7 +1938,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 + #include "uqm/gameev.h" + #include "uqm/shipcont.h" +Index: uqm/comm/yehat/yehatc.c =================================================================== ---- uqm/planets/solarsys.c (revision 3779) -+++ uqm/planets/solarsys.c (working copy) -@@ -837,18 +837,19 @@ - static void - ProcessShipControls (void) +--- uqm/comm/yehat/yehatc.c (revision 3779) ++++ 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 3779) ++++ 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 3779) ++++ 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/zoqfot/zoqfotc.c +=================================================================== +--- uqm/comm/zoqfot/zoqfotc.c (revision 3779) ++++ 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/comandr/comandr.c +=================================================================== +--- uqm/comm/comandr/comandr.c (revision 3779) ++++ uqm/comm/comandr/comandr.c (working copy) +@@ -18,7 +18,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 3779) ++++ 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 = { -- 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) -@@ -861,7 +862,6 @@ - else - delta_y = 0; - -- index = GetFrameIndex (GLOBAL (ShipStamp.frame)); - if (pSolarSysState->turn_counter) - --pSolarSysState->turn_counter; - else if (delta_x) -@@ -1739,7 +1739,9 @@ - InitSolarSys (); - SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); - SolarSysState.InputFunc = DoIpFlight; -+ TFB_SetOnScreenKeyboard_Melee (); - DoInput (&SolarSysState, FALSE); -+ TFB_SetOnScreenKeyboard_Menu (); - UninitSolarSys (); - pSolarSysState = 0; - } -@@ -1997,13 +1999,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 +Index: uqm/comm/mycon/myconc.c =================================================================== ---- uqm/planets/pstarmap.c (revision 3779) -+++ uqm/planets/pstarmap.c (working copy) -@@ -1613,7 +1613,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 (); +--- uqm/comm/mycon/myconc.c (revision 3779) ++++ uqm/comm/mycon/myconc.c (working copy) +@@ -18,7 +18,7 @@ -Index: uqm/confirm.c + #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/confirm.c (revision 3779) -+++ uqm/confirm.c (working copy) -@@ -32,9 +32,11 @@ - #include +--- uqm/comm/arilou/arilouc.c (revision 3779) ++++ uqm/comm/arilou/arilouc.c (working copy) +@@ -18,7 +18,7 @@ + #include "../commall.h" + #include "resinst.h" +-#include "strings.h" ++#include "../arilou/strings.h" --#define CONFIRM_WIN_WIDTH 80 -+#define CONFIRM_WIN_WIDTH 160 - #define CONFIRM_WIN_HEIGHT 22 + #include "uqm/gameev.h" -+BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu = FALSE; -+ - static void - DrawConfirmationWindow (BOOLEAN answer) - { -@@ -65,6 +67,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); - -@@ -110,8 +114,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; -@@ -138,7 +150,7 @@ - PlayMenuSound (MENU_SOUND_MOVE); - } - SleepThread (ONE_SECOND / 30); -- } while (!done); -+ } - - // Restore the screen under the confirmation window - DrawStamp (&s); -@@ -151,6 +163,8 @@ - } - else - { -+ if (GLOBAL (CurrentActivity) & IN_BATTLE) -+ EmergencyEscapeWarpUnitActivatedFromMenu = TRUE; - result = FALSE; - } - ExitRequested = FALSE; Index: uqm/comm/chmmr/chmmrc.c =================================================================== --- uqm/comm/chmmr/chmmrc.c (revision 3779) @@ -824,322 +1631,225 @@ Index: uqm/comm/umgah/umgahc.c #include "uqm/build.h" -Index: uqm/comm/talkpet/talkpet.c +Index: uqm/confirm.c =================================================================== ---- uqm/comm/talkpet/talkpet.c (revision 3779) -+++ uqm/comm/talkpet/talkpet.c (working copy) -@@ -18,7 +18,7 @@ +--- uqm/confirm.c (revision 3779) ++++ uqm/confirm.c (working copy) +@@ -32,9 +32,11 @@ + #include - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../talkpet/strings.h" - #include "uqm/build.h" +-#define CONFIRM_WIN_WIDTH 80 ++#define CONFIRM_WIN_WIDTH 160 + #define CONFIRM_WIN_HEIGHT 22 -Index: uqm/comm/syreen/syreenc.c -=================================================================== ---- uqm/comm/syreen/syreenc.c (revision 3779) -+++ 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 "uqm/build.h" - #include "uqm/setup.h" -Index: uqm/comm/melnorm/melnorm.c -=================================================================== ---- uqm/comm/melnorm/melnorm.c (revision 3779) -+++ 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/shipcont.h" -Index: uqm/comm/yehat/yehatc.c -=================================================================== ---- uqm/comm/yehat/yehatc.c (revision 3779) -+++ 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 3779) -+++ 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 3779) -+++ 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/zoqfot/zoqfotc.c -=================================================================== ---- uqm/comm/zoqfot/zoqfotc.c (revision 3779) -+++ 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/comandr/comandr.c -=================================================================== ---- uqm/comm/comandr/comandr.c (revision 3779) -+++ uqm/comm/comandr/comandr.c (working copy) -@@ -18,7 +18,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 3779) -+++ 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 = ++BOOLEAN EmergencyEscapeWarpUnitActivatedFromMenu = FALSE; ++ + static void + DrawConfirmationWindow (BOOLEAN answer) { -Index: uqm/comm/mycon/myconc.c -=================================================================== ---- uqm/comm/mycon/myconc.c (revision 3779) -+++ uqm/comm/mycon/myconc.c (working copy) -@@ -18,7 +18,7 @@ +@@ -65,6 +67,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); - #include "../commall.h" - #include "resinst.h" --#include "strings.h" -+#include "../mycon/strings.h" +@@ -110,8 +114,16 @@ - #include "uqm/gameev.h" - #include "libs/mathlib.h" -Index: uqm/comm/arilou/arilouc.c -=================================================================== ---- uqm/comm/arilou/arilouc.c (revision 3779) -+++ 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/shipstat.c -=================================================================== ---- uqm/shipstat.c (revision 3779) -+++ uqm/shipstat.c (working copy) -@@ -132,6 +132,45 @@ - DrawFilledRectangle (&r); - } - -+static void -+DrawCrewEnergyBoxOutline (RECT *box) -+{ -+ RECT r; + FlushInput (); + done = FALSE; + -+ 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) - { -@@ -229,6 +268,20 @@ - 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 = 0; -+ r.corner.y = BAD_GUY_HORIZ_CREW_YOFFS; -+ if (StarShipPtr && StarShipPtr->playerNr == RPG_PLAYER_NUM) -+ r.corner.y = GOOD_GUY_HORIZ_CREW_YOFFS; -+ r.extent.width = crew_height + 2; -+ r.extent.height = STAT_WIDTH + 2; -+ 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.extent.width = energy_height + 2; -+ DrawCrewEnergyBoxOutline (&r); - } - - if (!StarShipPtr || StarShipPtr->captains_name_index) -@@ -288,7 +341,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 (); -@@ -306,10 +359,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; -@@ -319,13 +373,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); -@@ -392,10 +448,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); ++ #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; +@@ -138,7 +150,7 @@ + PlayMenuSound (MENU_SOUND_MOVE); + } + SleepThread (ONE_SECOND / 30); +- } while (!done); + } - } - if (energy_delta != 0) - { -+ COUNT blockI; - if (energy_delta > 0) + // Restore the screen under the confirmation window + DrawStamp (&s); +@@ -151,6 +163,8 @@ + } + else { - #define FUEL_UNIT_COLOR BUILD_COLOR (MAKE_RGB15 (0x14, 0x00, 0x00), 0x04) -@@ -431,6 +510,26 @@ - --ShipInfoPtr->energy_level; - } while (++energy_delta); ++ if (GLOBAL (CurrentActivity) & IN_BATTLE) ++ EmergencyEscapeWarpUnitActivatedFromMenu = TRUE; + result = FALSE; } -+ -+ 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); -+ } - } - } + ExitRequested = FALSE; +Index: uqm/planets/lander.c +=================================================================== +--- uqm/planets/lander.c (revision 3779) ++++ uqm/planets/lander.c (working copy) +@@ -1591,15 +1591,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; +@@ -1623,7 +1623,7 @@ + turn_wait = SHUTTLE_TURN_WAIT; + } + +- if (!CurrentInputState.key[PlayerControls[0]][KEY_UP]) ++ if (!(InputState & BATTLE_THRUST)) + { + dx = 0; + dy = 0; +@@ -1938,7 +1938,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 3779) ++++ uqm/planets/solarsys.c (working copy) +@@ -837,18 +837,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) +@@ -861,7 +862,6 @@ + else + delta_y = 0; + +- index = GetFrameIndex (GLOBAL (ShipStamp.frame)); + if (pSolarSysState->turn_counter) + --pSolarSysState->turn_counter; + else if (delta_x) +@@ -1739,7 +1739,9 @@ + InitSolarSys (); + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); + SolarSysState.InputFunc = DoIpFlight; ++ TFB_SetOnScreenKeyboard_Melee (); + DoInput (&SolarSysState, FALSE); ++ TFB_SetOnScreenKeyboard_Menu (); + UninitSolarSys (); + pSolarSysState = 0; + } +@@ -1997,13 +1999,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 3779) ++++ uqm/planets/pstarmap.c (working copy) +@@ -1613,7 +1613,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/controls.h +=================================================================== +--- uqm/controls.h (revision 3779) ++++ uqm/controls.h (working copy) +@@ -36,6 +36,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/starcon.c =================================================================== --- uqm/starcon.c (revision 3779) @@ -1152,162 +1862,19 @@ Index: uqm/starcon.c do { #ifdef DEBUG -Index: uqm/hyper.c +Index: uqm/supermelee/melee.c =================================================================== ---- uqm/hyper.c (revision 3779) -+++ uqm/hyper.c (working copy) -@@ -1685,7 +1685,6 @@ - Color OldColor; - CONTEXT OldContext; - MENU_STATE MenuState; -- - UnbatchGraphics (); - - OldContext = SetContext (SpaceContext); -Index: uqm/intro.c -=================================================================== ---- uqm/intro.c (revision 3779) -+++ uqm/intro.c (working copy) -@@ -751,7 +751,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 (); -@@ -839,7 +841,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 (); -@@ -855,6 +859,7 @@ - { - return FALSE; - } -+ - if (!strcmp (resType, "STRTAB")) - { - STRING pres = CaptureStringTable (LoadStringTable (res)); -Index: uqm/intel.c -=================================================================== ---- uqm/intel.c (revision 3779) -+++ 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; +--- uqm/supermelee/melee.c (revision 3779) ++++ uqm/supermelee/melee.c (working copy) +@@ -2074,7 +2074,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]); } - else -- InputState = CurrentInputToBattleInput (context->playerNr); -+ InputState = CurrentInputToBattleInput (context->playerNr, -1); - } - else if (!(PlayerControl[context->playerNr] & PSYTRON_CONTROL)) - InputState = 0; -Index: uqm/setupmenu.c -=================================================================== ---- uqm/setupmenu.c (revision 3779) -+++ uqm/setupmenu.c (working copy) -@@ -75,7 +75,7 @@ - #endif - - #define MENU_COUNT 8 --#define CHOICE_COUNT 24 -+#define CHOICE_COUNT 25 - #define SLIDER_COUNT 4 - #define BUTTON_COUNT 10 - #define LABEL_COUNT 4 -@@ -98,7 +98,7 @@ - static int choice_widths[CHOICE_COUNT] = { - 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 2, 2, 3, 3, 2, 3, 3, -- 3, 2, 2, 2 }; -+ 3, 2, 2, 2, 2 }; - - static HANDLER button_handlers[BUTTON_COUNT] = { - quit_main_menu, quit_sub_menu, do_graphics, do_engine, -@@ -157,6 +157,7 @@ - (WIDGET *)(&choices[12]), - (WIDGET *)(&choices[15]), - (WIDGET *)(&choices[16]), -+ (WIDGET *)(&choices[24]), - (WIDGET *)(&buttons[1]), - NULL }; - -@@ -416,6 +417,7 @@ - choices[21].selected = opts.musicremix; - choices[22].selected = opts.speech; - choices[23].selected = opts.keepaspect; -+ choices[24].selected = opts.directionaljoystick; - - sliders[0].value = opts.musicvol; - sliders[1].value = opts.sfxvol; -@@ -450,6 +452,7 @@ - opts.musicremix = choices[21].selected; - opts.speech = choices[22].selected; - opts.keepaspect = choices[23].selected; -+ opts.directionaljoystick = choices[24].selected; - - opts.musicvol = sliders[0].value; - opts.sfxvol = sliders[1].value; -@@ -1277,6 +1280,7 @@ - opts->musicremix = optRemixMusic ? OPTVAL_ENABLED : OPTVAL_DISABLED; - opts->speech = optSpeech ? OPTVAL_ENABLED : OPTVAL_DISABLED; - opts->keepaspect = optKeepAspectRatio ? OPTVAL_ENABLED : OPTVAL_DISABLED; -+ opts->directionaljoystick = optDirectionalJoystick ? OPTVAL_ENABLED : OPTVAL_DISABLED; - switch (snddriver) { - case audio_DRIVER_OPENAL: - opts->adriver = OPTVAL_OPENAL; -@@ -1518,6 +1522,7 @@ - optWhichIntro = (opts->intro == OPTVAL_3DO) ? OPT_3DO : OPT_PC; - optStereoSFX = (opts->stereo == OPTVAL_ENABLED); - optKeepAspectRatio = (opts->keepaspect == OPTVAL_ENABLED); -+ optDirectionalJoystick = (opts->directionaljoystick == OPTVAL_ENABLED) ? TRUE : FALSE; - PlayerControls[0] = opts->player1; - PlayerControls[1] = opts->player2; - -@@ -1532,6 +1537,7 @@ - res_PutBoolean ("config.speech", opts->speech == OPTVAL_ENABLED); - res_PutBoolean ("config.3domovies", opts->intro == OPTVAL_3DO); - res_PutBoolean ("config.showfps", opts->fps == OPTVAL_ENABLED); -+ res_PutBoolean ("config.directionaljoystick", opts->directionaljoystick == OPTVAL_ENABLED); - res_PutBoolean ("config.smoothmelee", opts->meleezoom == OPTVAL_3DO); - res_PutBoolean ("config.positionalsfx", opts->stereo == OPTVAL_ENABLED); - res_PutBoolean ("config.pulseshield", opts->shield == OPTVAL_3DO); -Index: uqm/setupmenu.h -=================================================================== ---- uqm/setupmenu.h (revision 3779) -+++ uqm/setupmenu.h (working copy) -@@ -81,6 +81,7 @@ - OPT_ENABLABLE fullscreen, subtitles, scanlines, fps, stereo; - OPT_ENABLABLE music3do, musicremix, speech; - OPT_ENABLABLE keepaspect; -+ OPT_ENABLABLE directionaljoystick; - OPT_CONSOLETYPE menu, text, cscan, scroll, intro, meleezoom, shield; - CONTROL_TEMPLATE player1, player2; - int speechvol, musicvol, sfxvol; -Index: uqm/menu.c -=================================================================== ---- uqm/menu.c (revision 3779) -+++ uqm/menu.c (working copy) -@@ -503,7 +503,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; -+ r.corner.y = s.origin.y - 40; - r.extent.width = RADAR_WIDTH + 2; - BatchGraphics (); - SetContextForeGroundColor ( Index: options.c =================================================================== --- options.c (revision 3779) @@ -1421,564 +1988,3 @@ Index: uqm.c getBoolConfigValue (&options->keepAspectRatio, "config.keepaspectratio"); getGammaConfigValue (&options->gamma, "config.gamma"); -Index: libs/sound/decoders/oggaud.c -=================================================================== ---- libs/sound/decoders/oggaud.c (revision 3779) -+++ libs/sound/decoders/oggaud.c (working copy) -@@ -270,7 +270,7 @@ - // this is the closest to a frame there is in ogg vorbis stream - // doesn't seem to be a func to retrive it - #ifdef OVCODEC_TREMOR -- return ova->vf.os->pageno; -+ return ova->vf.os.pageno; - #else - return ova->vf.os.pageno; - #endif /* OVCODEC_TREMOR */ -Index: libs/strings/getstr.c -=================================================================== ---- libs/strings/getstr.c (revision 3779) -+++ libs/strings/getstr.c (working copy) -@@ -72,7 +72,7 @@ - // returns FALSE if and only if the buffer needs to be enlarged but - // memory allocation failed. - static BOOLEAN --ensureBufSize (char **buf, size_t *curSize, size_t minSize, size_t increment) -+ensureBufSize (char **buf, DWORD *curSize, DWORD minSize, DWORD increment) - { - char *newBuf; - size_t newSize; -Index: libs/graphics/sdl/sdl_common.c -=================================================================== ---- libs/graphics/sdl/sdl_common.c (revision 3779) -+++ libs/graphics/sdl/sdl_common.c (working copy) -@@ -34,7 +34,11 @@ - #include "libs/memlib.h" - #include "libs/vidlib.h" - #include SDL_INCLUDE(SDL_thread.h) -+#ifdef ANDROID -+#include -+#endif - -+ - SDL_Surface *SDL_Video; - SDL_Surface *SDL_Screen; - SDL_Surface *TransitionScreen; -@@ -172,6 +176,8 @@ - - TFB_DrawCanvas_Initialize (); - -+ TFB_InitOnScreenKeyboard (); -+ - return 0; - } - -@@ -397,3 +403,155 @@ - SDL_FreeSurface (*screen); - *screen = NULL; - } -+ -+#ifdef ANDROID -+ -+static SDL_Rect SDL_LeftJoystickRect, SDL_RightJoystickRect, SDL_TextInputRect; -+ -+void -+TFB_InitOnScreenKeyboard (void) -+{ -+ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); -+ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &SDL_RightJoystickRect); -+ SDL_ANDROID_GetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); -+ -+ /* TFB_SetOnScreenKeyboard_Hidden (); */ -+ TFB_SetOnScreenKeyboard_Menu (); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Hidden (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ SDL_Rect b; -+ b.w = b.h = b.x = b.y = 0; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &b); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Menu (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ TFB_SetOnScreenKeyboard_Hidden(); -+ SDL_Rect b; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &SDL_TextInputRect); -+ b.w = SDL_RightJoystickRect.w / 2; -+ b.h = SDL_RightJoystickRect.h / 2; -+ b.x = SDL_RightJoystickRect.x + b.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); -+ b.x = SDL_RightJoystickRect.x; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Starmap (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ TFB_SetOnScreenKeyboard_Menu(); -+ SDL_Rect b; -+ b.h = SDL_RightJoystickRect.h / 2; -+ b.w = SDL_RightJoystickRect.w / 2; -+ b.x = SDL_RightJoystickRect.x - b.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); -+ b.x -= b.w; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); -+} -+ -+void -+TFB_SetOnScreenKeyboard_Melee (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ /* Make the on-screen buttons slightly overlap, so we can hit them with one finger */ -+ TFB_SetOnScreenKeyboard_Hidden(); -+ SDL_Rect b; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &SDL_LeftJoystickRect); -+ b.w = SDL_RightJoystickRect.w * 3 / 5; -+ b.h = SDL_RightJoystickRect.h * 3 / 5; -+ b.x = SDL_RightJoystickRect.x + SDL_RightJoystickRect.w - b.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; //SDL_RightJoystickRect.y; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &b); -+ b.x = SDL_RightJoystickRect.x; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &b); -+ // Throttle button is replaced by tapping joystick -+ /* -+ b.w = SDL_RightJoystickRect.w; -+ b.y = SDL_RightJoystickRect.y + SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &b); -+ */ -+} -+ -+void -+TFB_SetOnScreenKeyboard_TwoPlayersMelee (void) -+{ -+ if (SDL_ANDROID_GetScreenKeyboardRedefinedByUser()) -+ return; -+ /* Mirror the buttons */ -+ TFB_SetOnScreenKeyboard_Melee(); -+ SDL_Rect b = SDL_RightJoystickRect; -+ b.y = 0; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD2, &b); -+ b.w = SDL_RightJoystickRect.w * 3 / 5; -+ b.h = SDL_RightJoystickRect.h * 3 / 5; -+ b.x = 0; -+ b.y = 0; // SDL_RightJoystickRect.h - b.h; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &b); -+ b.x = SDL_RightJoystickRect.w - b.w; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &b); -+ // Throttle button is replaced by tapping joystick -+ /* -+ b.w = SDL_RightJoystickRect.w; -+ b.x = 0; -+ b.y = 0; -+ SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &b); -+ */ -+} -+ -+#else -+ -+/* Stubs */ -+void -+TFB_InitOnScreenKeyboard (void) -+{ -+} -+ -+void -+TFB_SetOnScreenKeyboard_Hidden (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.h -=================================================================== ---- libs/graphics/sdl/sdl_common.h (revision 3779) -+++ libs/graphics/sdl/sdl_common.h (working copy) -@@ -52,4 +52,6 @@ - int ReInit_Screen (SDL_Surface **screen, SDL_Surface *templat, int w, int h); - void UnInit_Screen (SDL_Surface **screen); - -+void TFB_InitOnScreenKeyboard (void); -+ - #endif -Index: libs/graphics/sdl/pure.c -=================================================================== ---- libs/graphics/sdl/pure.c (revision 3779) -+++ libs/graphics/sdl/pure.c (working copy) -@@ -104,6 +104,7 @@ - { - int i, videomode_flags; - SDL_PixelFormat conv_fmt; -+ int BPP = 32; - - GraphicsDriver = driver; - -@@ -128,6 +129,14 @@ - "under pure SDL, using 640x480", width, height); - } - -+#ifdef ANDROID -+ videomode_flags = SDL_SWSURFACE; -+ ScreenWidthActual = 320; -+ ScreenHeightActual = 240; -+ graphics_backend = &pure_unscaled_backend; -+ BPP = 16; -+#endif -+ - videomode_flags |= SDL_ANYFORMAT; - if (flags & TFB_GFXFLAGS_FULLSCREEN) - videomode_flags |= SDL_FULLSCREEN; -@@ -135,7 +144,7 @@ - /* We'll ask for a 32bpp frame, but it doesn't really matter, because we've set - SDL_ANYFORMAT */ - SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual, -- 32, videomode_flags); -+ BPP, videomode_flags); - - if (SDL_Video == NULL) - { -Index: libs/graphics/gfx_common.h -=================================================================== ---- libs/graphics/gfx_common.h (revision 3779) -+++ libs/graphics/gfx_common.h (working copy) -@@ -107,4 +107,10 @@ - extern int ScreenColorDepth; - extern int GraphicsDriver; - -+void TFB_SetOnScreenKeyboard_Hidden (void); -+void TFB_SetOnScreenKeyboard_Menu (void); -+void TFB_SetOnScreenKeyboard_Starmap (void); -+void TFB_SetOnScreenKeyboard_Melee (void); -+void TFB_SetOnScreenKeyboard_TwoPlayersMelee (void); -+ - #endif -Index: libs/log/msgbox_win.c -=================================================================== ---- libs/log/msgbox_win.c (revision 3779) -+++ libs/log/msgbox_win.c (working copy) -@@ -14,6 +14,7 @@ - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -+#ifndef ANDROID - #include "msgbox.h" - #define WIN32_LEAN_AND_MEAN - #include -@@ -64,4 +65,4 @@ - free (swTitle); - free (swMsg); - } -- -+#endif -Index: libs/log/msgbox_stub.c -=================================================================== ---- libs/log/msgbox_stub.c (revision 3779) -+++ 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 3779) -+++ libs/log/uqmlog.c (working copy) -@@ -23,6 +23,9 @@ - #include - #include - #include -+#ifdef ANDROID -+#include -+#endif - #include "libs/threadlib.h" - - #ifndef MAX_LOG_ENTRY_SIZE -@@ -191,6 +194,9 @@ - if ((int)level <= maxStreamLevel) - { - fprintf (streamOut, "%s\n", full_msg); -+#ifdef ANDROID -+ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); -+#endif - } - - if ((int)level <= maxLevel) -@@ -227,6 +233,9 @@ - if ((int)level <= maxStreamLevel) - { - fprintf (streamOut, "%s\n", full_msg); -+#ifdef ANDROID -+ __android_log_print( ANDROID_LOG_INFO, "Ur-Quan Masters", "%s", full_msg ); -+#endif - } - - if ((int)level <= maxLevel) -Index: libs/uio/io.c -=================================================================== ---- libs/uio/io.c (revision 3779) -+++ libs/uio/io.c (working copy) -@@ -35,6 +35,7 @@ - #include "mem.h" - #include "uioutils.h" - #include "uioport.h" -+#include "../log.h" - #ifdef uio_MEM_DEBUG - # include "memdebug.h" - #endif -@@ -193,6 +194,7 @@ - errno = EINVAL; - return NULL; - } -+ log_add (log_Info, "uio_open %s", sourcePath); - handle = uio_open(sourceDir, sourcePath, - ((flags & uio_MOUNT_RDONLY) == uio_MOUNT_RDONLY ? - O_RDONLY : O_RDWR) -@@ -201,12 +203,14 @@ - #endif - , 0); - if (handle == NULL) { -+ log_add (log_Info, "uio_open failed for %s", sourcePath); - // errno is set - return NULL; - } - } - - handler = uio_getFileSystemHandler(fsType); -+ log_add (log_Info, "uio_getFileSystemHandler %p", handler); - if (handler == NULL) { - if (handle) - uio_close(handle); -@@ -800,6 +804,7 @@ - &readMountInfo, &readPDirHandle, NULL, - &writeMountInfo, &writePDirHandle, NULL, &name) == -1) { - // errno is set -+ log_add (log_Info, "uio_open: uio_getPhysicalAccess failed for '%s'", path); - return NULL; - } - -@@ -826,6 +831,7 @@ - uio_PDirHandle_unref(readPDirHandle); - uio_PDirHandle_unref(writePDirHandle); - errno = EEXIST; -+ log_add (log_Info, "uio_open: O_CREAT | O_EXCL: file already exists '%s'", name); - return NULL; - } - if ((flags & O_TRUNC) == O_TRUNC) { -@@ -842,6 +848,7 @@ - uio_PDirHandle_unref(readPDirHandle); - uio_PDirHandle_unref(writePDirHandle); - errno = savedErrno; -+ log_add (log_Info, "uio_open: uio_copyFilePhysical failed '%s'", name); - return NULL; - } - } -@@ -863,6 +870,7 @@ - handle = (pDirHandle->pRoot->handler->open)(pDirHandle, name, flags, mode); - // Also adds a new entry to the physical dir if appropriate. - if (handle == NULL) { -+ log_add (log_Info, "uio_open: open file failed '%s'", name); - int savedErrno = errno; - uio_free(name); - uio_PDirHandle_unref(pDirHandle); -Index: libs/uio/zip/zip.c -=================================================================== ---- libs/uio/zip/zip.c (revision 3779) -+++ libs/uio/zip/zip.c (working copy) -@@ -1366,6 +1366,10 @@ - gPFileData->gid = (uid_t) makeUInt16(buf[12], buf[13]); - break; - } -+ case 0x7875: // 'Unix string UID/GID' -+ // Just skip it -+ break; -+ - default: - #ifdef DEBUG - fprintf(stderr, "Debug: Extra field 0x%04x unsupported, " -Index: libs/md5/md5.c -=================================================================== ---- libs/md5/md5.c (revision 3779) -+++ libs/md5/md5.c (working copy) -@@ -21,7 +21,7 @@ - - /* Written by Ulrich Drepper , 1995. */ - --#include -+#include "config.h" - - #include "md5.h" - -Index: libs/input/sdl/input.c -=================================================================== ---- libs/input/sdl/input.c (revision 3779) -+++ libs/input/sdl/input.c (working copy) -@@ -86,6 +86,7 @@ - "weapon", - "special", - "escape", -+ "thrust", - NULL - }; - -@@ -186,7 +187,7 @@ - directory. */ - LoadResourceIndex (contentDir, "uqm.key", "keys."); - } -- -+ - register_flight_controls (); - - return; -Index: libs/input/sdl/vcontrol.c -=================================================================== ---- libs/input/sdl/vcontrol.c (revision 3779) -+++ libs/input/sdl/vcontrol.c (working copy) -@@ -46,6 +46,7 @@ - typedef struct vcontrol_joystick_axis { - keybinding *neg, *pos; - int polarity; -+ int value; - } axis_type; - - typedef struct vcontrol_joystick_hat { -@@ -66,7 +67,7 @@ - - #endif /* HAVE_JOYSTICK */ - --static unsigned int joycount; -+static unsigned int joycount = 0; - static unsigned int num_sdl_keys = 0; - static keybinding **bindings = NULL; - -@@ -141,6 +142,7 @@ - for (j = 0; j < axes; j++) - { - x->axes[j].neg = x->axes[j].pos = NULL; -+ x->axes[j].polarity = x->axes[j].value = 0; - } - for (j = 0; j < hats; j++) - { -@@ -818,6 +820,7 @@ - int t; - if (!joysticks[port].stick) - return; -+ joysticks[port].axes[axis].value = value; - t = joysticks[port].threshold; - if (value > t) - { -@@ -894,6 +897,25 @@ - #endif /* HAVE_JOYSTICK */ - } - -+int -+VControl_GetJoyAxis(int port, int axis) -+{ -+#ifdef HAVE_JOYSTICK -+ if( joycount <= port ) -+ return 0; -+ if (!joysticks[port].stick || joysticks[port].numaxes <= axis ) -+ return 0; -+ return joysticks[port].axes[axis].value; -+#else -+ return 0; -+#endif /* HAVE_JOYSTICK */ -+}; -+ -+int VControl_GetJoysticksAmount() -+{ -+ return joycount; -+}; -+ - void - VControl_ResetInput (void) - { -Index: libs/input/sdl/vcontrol.h -=================================================================== ---- libs/input/sdl/vcontrol.h (revision 3779) -+++ 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); - -Index: libs/resource/filecntl.c -=================================================================== ---- libs/resource/filecntl.c (revision 3779) -+++ libs/resource/filecntl.c (working copy) -@@ -26,6 +26,7 @@ - #include "port.h" - #include "resintrn.h" - #include "libs/uio.h" -+#include "libs/log.h" - - uio_Stream * - res_OpenResFile (uio_DirHandle *dir, const char *filename, const char *mode) -@@ -34,7 +35,10 @@ - struct stat sb; - - if (uio_stat (dir, filename, &sb) == 0 && S_ISDIR(sb.st_mode)) -+ { -+ log_add (log_Debug, "res_OpenResFile('%s', '%s') - cannot open dir as file", filename, mode); - return ((uio_Stream *) ~0); -+ } - - fp = uio_fopen (dir, filename, mode); -