diff --git a/.github/workflows/build-all.yaml b/.github/workflows/build-all.yaml
index e5d28cc44..a5d0090fb 100644
--- a/.github/workflows/build-all.yaml
+++ b/.github/workflows/build-all.yaml
@@ -279,9 +279,6 @@ jobs:
echo Downloaded: ${{ fromJson(steps.download-doxygen.outputs.downloaded_files)[0] }}
cd oolite
../doxygen/doxygen-*/bin/doxygen
- python3 -m coverxygen --verbose --xml-dir doxygen/xml --src-dir . --output doxygen/coverxygen.info
- mkdir -p doxygen/html/coverage
- genhtml doxygen/coverxygen.info -o doxygen/html/coverage
# This is for debugging only and helps developing the workflow.
- name: Environment Variables 1
diff --git a/ShellScripts/Linux/GNUstep.conf.template b/ShellScripts/Linux/GNUstep.conf.template
new file mode 100644
index 000000000..18734eefe
--- /dev/null
+++ b/ShellScripts/Linux/GNUstep.conf.template
@@ -0,0 +1,37 @@
+GNUSTEP_MAKEFILES=@BASEDIR@/share/GNUstep/Makefiles
+GNUSTEP_SYSTEM_USERS_DIR=/home
+GNUSTEP_NETWORK_USERS_DIR=/home
+GNUSTEP_LOCAL_USERS_DIR=/home
+GNUSTEP_SYSTEM_APPS=@BASEDIR@/lib/GNUstep/Applications
+GNUSTEP_SYSTEM_ADMIN_APPS=@BASEDIR@/lib/GNUstep/Applications
+GNUSTEP_SYSTEM_WEB_APPS=@BASEDIR@/lib/GNUstep/WebApplications
+GNUSTEP_SYSTEM_TOOLS=@BASEDIR@/bin
+GNUSTEP_SYSTEM_ADMIN_TOOLS=@BASEDIR@/sbin
+GNUSTEP_SYSTEM_LIBRARY=@BASEDIR@/lib/GNUstep
+GNUSTEP_SYSTEM_HEADERS=@BASEDIR@/include
+GNUSTEP_SYSTEM_LIBRARIES=@BASEDIR@/lib
+GNUSTEP_SYSTEM_DOC=@BASEDIR@/share/GNUstep/Documentation
+GNUSTEP_SYSTEM_DOC_MAN=@BASEDIR@/share/man
+GNUSTEP_SYSTEM_DOC_INFO=@BASEDIR@/share/info
+GNUSTEP_NETWORK_APPS=@BASEDIR@/lib/GNUstep/Applications
+GNUSTEP_NETWORK_ADMIN_APPS=@BASEDIR@/lib/GNUstep/Applications
+GNUSTEP_NETWORK_WEB_APPS=@BASEDIR@/lib/GNUstep/WebApplications
+GNUSTEP_NETWORK_TOOLS=@BASEDIR@/bin
+GNUSTEP_NETWORK_ADMIN_TOOLS=@BASEDIR@/sbin
+GNUSTEP_NETWORK_LIBRARY=@BASEDIR@/lib/GNUstep
+GNUSTEP_NETWORK_HEADERS=@BASEDIR@/include
+GNUSTEP_NETWORK_LIBRARIES=@BASEDIR@/lib
+GNUSTEP_NETWORK_DOC=@BASEDIR@/share/GNUstep/Documentation
+GNUSTEP_NETWORK_DOC_MAN=@BASEDIR@/share/man
+GNUSTEP_NETWORK_DOC_INFO=@BASEDIR@/share/info
+GNUSTEP_LOCAL_APPS=@BASEDIR@/lib/GNUstep/Applications
+GNUSTEP_LOCAL_ADMIN_APPS=@BASEDIR@/lib/GNUstep/Applications
+GNUSTEP_LOCAL_WEB_APPS=@BASEDIR@/lib/GNUstep/WebApplications
+GNUSTEP_LOCAL_TOOLS=@BASEDIR@/bin
+GNUSTEP_LOCAL_ADMIN_TOOLS=@BASEDIR@/sbin
+GNUSTEP_LOCAL_LIBRARY=@BASEDIR@/lib/GNUstep
+GNUSTEP_LOCAL_HEADERS=@BASEDIR@/include
+GNUSTEP_LOCAL_LIBRARIES=@BASEDIR@/lib
+GNUSTEP_LOCAL_DOC=@BASEDIR@/share/GNUstep/Documentation
+GNUSTEP_LOCAL_DOC_MAN=@BASEDIR@/share/man
+GNUSTEP_LOCAL_DOC_INFO=@BASEDIR@/share/info
diff --git a/ShellScripts/Linux/run_oolite.sh b/ShellScripts/Linux/run_oolite.sh
index 917f55505..623db19d1 100755
--- a/ShellScripts/Linux/run_oolite.sh
+++ b/ShellScripts/Linux/run_oolite.sh
@@ -3,6 +3,16 @@
HERE="$(dirname "$(readlink -f "$0")")"
+SHOW_SPLASH=true
+# Loop through all arguments
+for arg in "$@"; do
+ case "$arg" in
+ -nosplash|--nosplash)
+ SHOW_SPLASH=false
+ ;;
+ esac
+done
+
notify_failure() {
if [[ -n "$FLATPAK_ID" ]]; then
local MSG="$FLATPAK_ID failed to start!\n\nExit Code: $EXIT_CODE"
@@ -33,7 +43,17 @@ notify_failure() {
}
launch_guarded() {
- "$@"
+ if [[ "$1" == "packageinfo" ]]; then
+ cat "$OO_EXEDIR/Resources/manifest.plist"
+ exit 0
+ fi
+ if [[ "$SHOW_SPLASH" == true ]]; then
+ "$OO_EXEDIR/splash-launcher" "$OO_EXEDIR/Resources/Images/splash.bmp" &
+ "$OO_EXEDIR/oolite" "$@" -nosplash
+ else
+ # already has -nosplash
+ "$OO_EXEDIR/oolite" "$@"
+ fi
local EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
@@ -44,41 +64,37 @@ launch_guarded() {
exit $EXIT_CODE
}
-find_exe_launch() {
- if [[ -z "$OO_EXECUTABLE" ]]; then
- OO_EXECUTABLE="$HERE/oolite"
- if [[ ! -f "$OO_EXECUTABLE" ]]; then
- OO_EXECUTABLE="$HERE/oolite.app/oolite"
+find_exedir() {
+ if [[ -z "$OO_EXEDIR" ]]; then
+ OO_EXEDIR="$HERE"
+ if [[ ! -f "$OO_EXEDIR/oolite" ]]; then
+ OO_EXEDIR="$HERE/oolite.app"
fi
fi
- launch_guarded "$OO_EXECUTABLE" "$@"
+}
+
+make_gnustepconf_template() {
+ export GNUSTEP_CONFIG_FILE=$(mktemp -t oolite_gnustep_XXXX --suffix=.conf)
+ sed -e "s|@BASEDIR@|$BASEDIR|g" "$OO_EXEDIR/Resources/GNUstep.conf.template" > "$GNUSTEP_CONFIG_FILE"
}
# Check if we are running inside a Flatpak
if [[ -n "$FLATPAK_ID" ]]; then
- if [[ "$1" == "packageinfo" ]]; then
- cat "/app/bin/Resources/manifest.plist"
- exit 0
- fi
-
+ BASEDIR="/app"
+ OO_EXEDIR="$BASEDIR/bin"
GAME_DATA="$HOME/.var/app/$FLATPAK_ID"
- OO_EXECUTABLE="/app/bin/oolite"
+ make_gnustepconf_template
# Check if we are running inside an AppImage
elif [[ -n "$APPIMAGE" ]]; then
- MANIFEST="$APPDIR/usr/bin/Resources/manifest.plist"
- if [[ "$1" == "packageinfo" ]]; then
- cat "$MANIFEST"
- exit 0
- fi
-
- export LD_LIBRARY_PATH="$APPDIR/usr/lib:$LD_LIBRARY_PATH"
- export PATH="$APPDIR/usr/bin:$PATH"
- OO_EXECUTABLE="$APPDIR/usr/bin/oolite"
+ BASEDIR="$APPDIR/usr"
+ OO_EXEDIR="$BASEDIR/bin"
+ export LD_LIBRARY_PATH="$BASEDIR/lib:$LD_LIBRARY_PATH"
+ export PATH="$OO_EXEDIR:$PATH"
- DEBUG_OXP=$(grep "debug_functionality_support" "$MANIFEST")
+ DEBUG_OXP=$(grep "debug_functionality_support" "$OO_EXEDIR/Resources/manifest.plist")
if [[ "$DEBUG_OXP" == *"yes"* ]]; then
- INTERNAL_ADDONS="$APPDIR/usr/bin/AddOns"
+ INTERNAL_ADDONS="$OO_EXEDIR/AddOns"
export OO_ADDITIONALADDONSDIRS="${OO_ADDITIONALADDONSDIRS}${OO_ADDITIONALADDONSDIRS:+,}$INTERNAL_ADDONS"
fi
@@ -86,34 +102,47 @@ elif [[ -n "$APPIMAGE" ]]; then
if [[ "${OO_DIRTYPE,,}" == "xdg" ]]; then
GAME_DATA="$HOME/.local/share/Oolite"
elif [[ "${OO_DIRTYPE,,}" == "legacy" ]]; then
- launch_guarded "$OO_EXECUTABLE" "$@"
+ launch_guarded "$@"
fi
else
# Get the folder containing the AppImage file
HERE="$(dirname "$APPIMAGE")"
GAME_DATA="$HERE/GameData"
fi
+ make_gnustepconf_template
else
- if [[ "$1" == "packageinfo" ]]; then
- if [ -f "$HERE/Resources/manifest.plist" ]; then
- cat "$HERE/Resources/manifest.plist"
- else
- cat "$HERE/oolite.app/Resources/manifest.plist"
- fi
- exit 0
- fi
-
# Check if OO_DIRTYPE set
if [[ -n "$OO_DIRTYPE" ]]; then
if [[ "${OO_DIRTYPE,,}" == "xdg" ]]; then
GAME_DATA="$HOME/.local/share/Oolite"
elif [[ "${OO_DIRTYPE,,}" == "legacy" ]]; then
- find_exe_launch "$@"
+ find_exedir
+ launch_guarded "$@"
fi
else
# Use script directory
GAME_DATA="$HERE/GameData"
fi
+ # Find the current system configuration file
+ ORIGINAL_CONF=$(gnustep-config --variable=GNUSTEP_CONFIG_FILE)
+
+ # Fallback: If gnustep-config returns nothing, assume standard location
+ if [ -z "$ORIGINAL_CONF" ]; then
+ ORIGINAL_CONF="/etc/GNUstep/GNUstep.conf"
+ fi
+
+ if [ -z "$ORIGINAL_CONF" ]; then
+ ORIGINAL_CONF="/usr/local/etc/GNUstep/GNUstep.conf"
+ fi
+
+ GNUSTEP_CONFIG_FILE=$(mktemp -t oolite_gnustep_XXXX --suffix=.conf)
+ # Copy the original config (if it exists) to the temp file
+ if [ -f "$ORIGINAL_CONF" ]; then
+ cp "$ORIGINAL_CONF" "$GNUSTEP_CONFIG_FILE"
+ else
+ echo "No system config found at $ORIGINAL_CONF. Starting with empty config."
+ touch "$GNUSTEP_CONFIG_FILE"
+ fi
fi
mkdir -p "$GAME_DATA"
@@ -135,6 +164,7 @@ elif [[ -n "$OO_USERADDONSDIR" ]]; then
fi
fi
mkdir -p "$OO_ADDONSEXTRACTDIR"
+# OO_ADDITIONALADDONSDIRS can be used to pass a comma separated list of additional OXP folders
if [ -n "$OO_ADDITIONALADDONSDIRS" ]; then
(IFS=,; mkdir -p $OO_ADDITIONALADDONSDIRS)
fi
@@ -144,47 +174,21 @@ mkdir -p "$OO_GNUSTEPDIR"
OO_GNUSTEPDEFAULTSDIR="${OO_GNUSTEPDEFAULTSDIR:-${GAME_DATA}}"
mkdir -p "$OO_GNUSTEPDEFAULTSDIR"
-# OO_ADDITIONALADDONSDIRS can be used to pass a comma separated list of additional OXP folders
-
-
-# Find the current system configuration file
-ORIGINAL_CONF=$(gnustep-config --variable=GNUSTEP_CONFIG_FILE)
-
-# Fallback: If gnustep-config returns nothing, assume standard location
-if [ -z "$ORIGINAL_CONF" ]; then
- ORIGINAL_CONF="/etc/GNUstep/GNUstep.conf"
-fi
-
-if [ -z "$ORIGINAL_CONF" ]; then
- ORIGINAL_CONF="/usr/local/etc/GNUstep/GNUstep.conf"
-fi
-
-TEMP_CONF=$(mktemp -t oolite_gnustep_XXXX --suffix=.conf)
-
-# Copy the original config to the temp file (if it exists)
-if [ -f "$ORIGINAL_CONF" ]; then
- cp "$ORIGINAL_CONF" "$TEMP_CONF"
-else
- echo "No system config found at $ORIGINAL_CONF. Starting with empty config."
- touch "$TEMP_CONF"
-fi
-
-echo "" >> "$TEMP_CONF"
-echo "# --- Overrides added by launcher script ---" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_APPS=$OO_GNUSTEPDIR/Applications" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_ADMIN_APPS=$OO_GNUSTEPDIR/Applications/Admin" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_WEB_APPS=$OO_GNUSTEPDIR/WebApplications" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_TOOLS=$OO_GNUSTEPDIR/Tools" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_ADMIN_TOOLS=$OO_GNUSTEPDIR/Tools/Admin" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_LIBRARY=$OO_GNUSTEPDIR/Library" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_HEADERS=$OO_GNUSTEPDIR/Library/Headers" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_LIBRARIES=$OO_GNUSTEPDIR/Library/Libraries" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_DOC=$OO_GNUSTEPDIR/Library/Documentation" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_DOC_MAN=$OO_GNUSTEPDIR/Library/Documentation/man" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DIR_DOC_INFO=$OO_GNUSTEPDIR/Library/Documentation/info" >> "$TEMP_CONF"
-echo "GNUSTEP_USER_DEFAULTS_DIR=$OO_GNUSTEPDEFAULTSDIR" >> "$TEMP_CONF"
-
-export GNUSTEP_CONFIG_FILE="$TEMP_CONF"
-
-find_exe_launch "$@"
-rm "$TEMP_CONF"
+echo "" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_CONFIG_FILE=$GNUSTEP_CONFIG_FILE" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_APPS=$OO_GNUSTEPDIR/Applications" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_ADMIN_APPS=$OO_GNUSTEPDIR/Applications/Admin" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_WEB_APPS=$OO_GNUSTEPDIR/WebApplications" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_TOOLS=$OO_GNUSTEPDIR/Tools" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_ADMIN_TOOLS=$OO_GNUSTEPDIR/Tools/Admin" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_LIBRARY=$OO_GNUSTEPDIR/Library" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_HEADERS=$OO_GNUSTEPDIR/Library/Headers" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_LIBRARIES=$OO_GNUSTEPDIR/Library/Libraries" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_DOC=$OO_GNUSTEPDIR/Library/Documentation" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_DOC_MAN=$OO_GNUSTEPDIR/Library/Documentation/man" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DIR_DOC_INFO=$OO_GNUSTEPDIR/Library/Documentation/info" >> "$GNUSTEP_CONFIG_FILE"
+echo "GNUSTEP_USER_DEFAULTS_DIR=$OO_GNUSTEPDEFAULTSDIR" >> "$GNUSTEP_CONFIG_FILE"
+
+find_exedir
+launch_guarded "$@"
+rm "$GNUSTEP_CONFIG_FILE"
diff --git a/ShellScripts/Linux/splash-launcher b/ShellScripts/Linux/splash-launcher
new file mode 100755
index 000000000..e9cb473cb
Binary files /dev/null and b/ShellScripts/Linux/splash-launcher differ
diff --git a/ShellScripts/common/post_build.sh b/ShellScripts/common/post_build.sh
index 2910e77cb..eca068dff 100755
--- a/ShellScripts/common/post_build.sh
+++ b/ShellScripts/common/post_build.sh
@@ -117,6 +117,7 @@ run_script() {
else
# Copy Linux-specific wrapper script
cp -fu ShellScripts/Linux/run_oolite.sh "$PROGDIR"
+ cp -fu ShellScripts/Linux/splash-launcher "$PROGDIR"
fi
echo "✅ Oolite post-build completed successfully"
diff --git a/installers/appimage/create_appimage.sh b/installers/appimage/create_appimage.sh
index f67ab58f5..9953a302c 100755
--- a/installers/appimage/create_appimage.sh
+++ b/installers/appimage/create_appimage.sh
@@ -13,14 +13,19 @@ run_script() {
APPDIR="./Oolite.AppDir"
rm -rf $APPDIR
- mkdir -p $APPDIR/usr/bin
+ APPBIN="$APPDIR/usr/bin"
+ APPLIB="$APPDIR/usr/lib"
+ mkdir -p "$APPBIN"
PROGDIR="../oolite.app"
- cp -rf $PROGDIR/Resources $APPDIR/usr/bin
+ cp -uf "$PROGDIR/splash-launcher" "$APPBIN"
+ cp -rf "$PROGDIR/Resources" "$APPBIN"
+ cp -uf "../ShellScripts/Linux/GNUstep.conf.template" "$APPBIN/Resources"
+
if (( $# == 1 )); then
echo "Including Basic-debug.oxp"
- cp -rf AddOns $APPDIR/usr/bin
+ cp -rf AddOns "$APPBIN"
fi
curl -o linuxdeploy -L https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
diff --git a/installers/flatpak/flatpak_build.sh b/installers/flatpak/flatpak_build.sh
index 62507b3b7..73712c927 100755
--- a/installers/flatpak/flatpak_build.sh
+++ b/installers/flatpak/flatpak_build.sh
@@ -12,7 +12,14 @@ export ADDITIONAL_CFLAGS="-DBUILD_DATE='\"$CPP_DATE\"'"
export ADDITIONAL_OBJCFLAGS="-DBUILD_DATE='\"$CPP_DATE\"'"
make -f Makefile release-deployment -j$FLATPAK_BUILDER_N_JOBS
-cp -r oolite.app/* /app/bin
+PROGDIR="oolite.app"
+APPBIN="/app/bin"
+
+cp -uf "$PROGDIR/run_oolite.sh" "$APPBIN"
+cp -uf "$PROGDIR/oolite" "$APPBIN"
+cp -uf "$PROGDIR/splash-launcher" "$APPBIN"
+cp -rf "$PROGDIR/Resources" "$APPBIN"
+cp -uf "ShellScripts/Linux/GNUstep.conf.template" "/app/bin/Resources"
if [[ -z "$VERSION_OVERRIDE" ]]; then
source ShellScripts/common/get_version.sh
diff --git a/src/Core/OOOXZManager.m b/src/Core/OOOXZManager.m
index d90b2bf00..c24020bf7 100644
--- a/src/Core/OOOXZManager.m
+++ b/src/Core/OOOXZManager.m
@@ -114,6 +114,34 @@
OXZ_GUI_ROW_EXIT = 27
};
+#if OOLITE_LINUX
+#include
+#include
+#include
+
+static BOOL OOIsNetworkAvailable()
+{
+ // Try to connect to a reliable IP (Google DNS) on port 53 (DNS)
+ struct sockaddr_in servaddr;
+ int sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0) return NO;
+
+ bzero(&servaddr, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(53);
+ inet_pton(AF_INET, "8.8.8.8", &servaddr.sin_addr);
+
+ // Set a very short timeout so the UI doesn't hang
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500000; // 0.5 seconds
+ setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
+
+ BOOL reachable = (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0);
+ close(sockfd);
+ return reachable;
+}
+#endif
NSComparisonResult oxzSort(id m1, id m2, void *context);
@@ -237,24 +265,24 @@ - (NSString *) installPath
{
return [NSString stringWithUTF8String:managedAddOnsEnv];
}
- else
- {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES);
- NSString *appPath = [paths objectAtIndex:0];
- if (appPath != nil)
- {
- appPath = [appPath stringByAppendingPathComponent:@"Oolite"];
- #if OOLITE_MAC_OS_X
- appPath = [appPath stringByAppendingPathComponent:@"Managed AddOns"];
- #else
- /* GNUStep uses "ApplicationSupport" rather than "Application
- * Support" so match convention by not putting a space in the
- * path either */
- appPath = [appPath stringByAppendingPathComponent:@"ManagedAddOns"];
- #endif
- return appPath;
- }
- }
+ else
+ {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES);
+ NSString *appPath = [paths objectAtIndex:0];
+ if (appPath != nil)
+ {
+ appPath = [appPath stringByAppendingPathComponent:@"Oolite"];
+ #if OOLITE_MAC_OS_X
+ appPath = [appPath stringByAppendingPathComponent:@"Managed AddOns"];
+ #else
+ /* GNUStep uses "ApplicationSupport" rather than "Application
+ * Support" so match convention by not putting a space in the
+ * path either */
+ appPath = [appPath stringByAppendingPathComponent:@"ManagedAddOns"];
+ #endif
+ return appPath;
+ }
+ }
return nil;
}
@@ -267,10 +295,10 @@ - (NSString *) extractAddOnsPath
{
return [NSString stringWithUTF8String:addOnsExtractEnv];
}
- else
- {
+ else
+ {
#if OOLITE_WINDOWS
- #if OO_GAME_DATA_TO_USER_FOLDER
+ #if OO_GAME_DATA_TO_USER_FOLDER
return [NSString stringWithFormat:@"%s\\Oolite\\AddOns", SDL_getenv("LOCALAPPDATA")];
#else
return @"../AddOns";
@@ -278,19 +306,19 @@ - (NSString *) extractAddOnsPath
#else
return [[NSHomeDirectory() stringByAppendingPathComponent:@".Oolite"] stringByAppendingPathComponent:@"AddOns"];
#endif
- }
+ }
}
/* Add additional AddOns paths */
- (NSArray *) additionalAddOnsPaths
{
- const char *additionalAddOnsEnv = SDL_getenv("OO_ADDITIONALADDONSDIRS");
+ const char *additionalAddOnsEnv = SDL_getenv("OO_ADDITIONALADDONSDIRS");
- if (additionalAddOnsEnv) {
+ if (additionalAddOnsEnv) {
NSString *envStr = [NSString stringWithUTF8String:additionalAddOnsEnv];
return [envStr componentsSeparatedByString:@","];
- }
- return [NSArray array];
+ }
+ return [NSArray array];
}
@@ -450,8 +478,8 @@ - (NSArray *) applyCurrentFilter:(NSArray *)list
}
NSMutableArray *filteredList = [NSMutableArray arrayWithCapacity:[list count]];
- NSDictionary *manifest = nil;
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[self class] instanceMethodSignatureForSelector:filterSelector]];
+ NSDictionary *manifest = nil;
+ NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[self class] instanceMethodSignatureForSelector:filterSelector]];
[invocation setSelector:filterSelector];
[invocation setTarget:self];
if (parameter != nil)
@@ -624,7 +652,6 @@ - (void) setProgressStatus:(NSString *)new
- (BOOL) updateManifests
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self dataURL]]];
- [request setHTTPShouldHandleCookies:NO];
if (_downloadStatus != OXZ_DOWNLOAD_NONE)
{
return NO;
@@ -639,8 +666,17 @@ - (BOOL) updateManifests
- (BOOL) beginDownload:(NSMutableURLRequest *)request
{
+#if OOLITE_LINUX
+ if (!OOIsNetworkAvailable())
+ {
+ OOLog(kOOOXZErrorLog, @"Network unreachable. Aborting download.");
+ _downloadStatus = OXZ_DOWNLOAD_ERROR;
+ return NO;
+ }
+#endif
NSString *userAgent = [NSString stringWithFormat:@"Oolite/%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
[request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
+ [request setHTTPShouldHandleCookies:NO];
NSURLConnection *download = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (download)
{
@@ -880,7 +916,7 @@ - (BOOL) processDownloadedOXZ
{
OOLog(kOOOXZDebugLog,@"Dependency stack: checking %@",[requirement oo_stringForKey:kOOManifestRelationIdentifier]);
if (![ResourceManager manifest:downloadedManifest HasUnmetDependency:requirement logErrors:NO]
- && requires != nil && [requires containsObject:requirement])
+ && requires != nil && [requires containsObject:requirement])
{
// it was unmet, but now it's met
[progress appendFormat:DESC(@"oolite-oxzmanager-progress-now-has-@"),[requirement oo_stringForKey:kOOManifestRelationDescription defaultValue:[requirement oo_stringForKey:kOOManifestRelationIdentifier]]];
@@ -1232,8 +1268,14 @@ - (void) gui
case OXZ_STATE_INSTALLING:
[gui setTitle:DESC(@"oolite-oxzmanager-title-downloading")];
- [gui addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-progress-@-is-@-of-@"),_currentDownloadName,[self humanSize:_downloadProgress],[self humanSize:_downloadExpected]] startingAtRow:OXZ_GUI_ROW_PROGRESS align:GUI_ALIGN_LEFT];
-
+ if (_downloadStatus == OXZ_DOWNLOAD_ERROR)
+ {
+ [gui addLongText:OOExpandKey(@"oolite-oxzmanager-progress-error") startingAtRow:OXZ_GUI_ROW_PROGRESS align:GUI_ALIGN_LEFT];
+ }
+ else
+ {
+ [gui addLongText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-progress-@-is-@-of-@"),_currentDownloadName,[self humanSize:_downloadProgress],[self humanSize:_downloadExpected]] startingAtRow:OXZ_GUI_ROW_PROGRESS align:GUI_ALIGN_LEFT];
+ }
[gui addLongText:_progressStatus startingAtRow:OXZ_GUI_ROW_PROGRESS+2 align:GUI_ALIGN_LEFT];
[gui setText:DESC(@"oolite-oxzmanager-cancel") forRow:OXZ_GUI_ROW_CANCEL align:GUI_ALIGN_CENTER];
@@ -1710,7 +1752,6 @@ - (BOOL) installOXZ:(NSUInteger)item
return NO;
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
- [request setHTTPShouldHandleCookies:NO];
if (_downloadStatus != OXZ_DOWNLOAD_NONE)
{
return NO;
diff --git a/src/SDL/MyOpenGLView.h b/src/SDL/MyOpenGLView.h
index a921841bb..098c6165e 100644
--- a/src/SDL/MyOpenGLView.h
+++ b/src/SDL/MyOpenGLView.h
@@ -135,7 +135,7 @@ enum StringInput
{
gvStringInputNo = 0,
gvStringInputAlpha = 1,
- gvStringInputLoadSave = 2,
+ gvStringInputLoadSave = 2,
gvStringInputAll = 3
};
@@ -196,7 +196,7 @@ extern int debug;
NSMutableString *typedString;
NSPoint virtualJoystickPosition;
-
+
float _mouseVirtualStickSensitivityFactor;
NSSize viewSize;
@@ -227,7 +227,7 @@ extern int debug;
BOOL updateContext;
BOOL saveSize;
BOOL atDesktopResolution;
- unsigned keyboardMap; // *** FLAGGED for deletion
+ unsigned keyboardMap; // *** FLAGGED for deletion
HWND SDL_Window;
MONITORINFOEX monitorInfo;
RECT lastGoodRect;
@@ -240,18 +240,18 @@ extern int debug;
int _sdrToneMapper;
float _colorSaturation;
-
+
BOOL _hdrOutput;
BOOL grabMouseStatus;
NSSize firstScreen;
-
+
OOOpenGLMatrixManager *matrixManager;
// Mouse mode indicator (for mouse movement model)
BOOL mouseInDeltaMode;
-
+
float _mouseWheelDelta;
}
diff --git a/src/SDL/MyOpenGLView.m b/src/SDL/MyOpenGLView.m
index 80c9bdbce..f6f5e23fd 100644
--- a/src/SDL/MyOpenGLView.m
+++ b/src/SDL/MyOpenGLView.m
@@ -149,7 +149,7 @@ - (void) createSurface
if (!surface) {
return;
}
-
+
#if OOLITE_LINUX
// blank the surface / go to fullscreen
[self initialiseGLWithSize: firstScreen];
@@ -211,10 +211,10 @@ - (id) init
{
showSplashScreen = YES;
}
-
+
// if V-sync is disabled at the command line, override the defaults file
if ([arg isEqual:@"-novsync"] || [arg isEqual:@"--novsync"]) vSyncPreference = NO;
-
+
if ([arg isEqual: @"-hdr"]) bitsPerColorComponent = 16;
// build the startup command string so that we can log it
@@ -222,7 +222,7 @@ - (id) init
}
OOLog(@"process.args", @"%@", cmdLineArgsStr);
-
+
matrixManager = [[OOOpenGLMatrixManager alloc] init];
// TODO: This code up to and including stickHandler really ought
@@ -259,13 +259,13 @@ - (id) init
#if OOLITE_WINDOWS
// needed for enabling system window manager events, which is needed for handling window movement messages
SDL_EventState (SDL_SYSWMEVENT, SDL_ENABLE);
-
+
//capture the window handle for later
static SDL_SysWMinfo wInfo;
SDL_VERSION(&wInfo.version);
SDL_GetWMInfo(&wInfo);
SDL_Window = wInfo.window;
-
+
// This must be inited after SDL_Window has been set - we need the main window handle in order to get monitor info
if (![self getCurrentMonitorInfo:&monitorInfo])
{
@@ -273,7 +273,7 @@ - (id) init
}
atDesktopResolution = YES;
-
+
#if USE_UNDOCUMENTED_DARKMODE_API
// dark mode stuff - this is mainly for the winodw titlebar's context menu
HMODULE hUxTheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
@@ -307,9 +307,9 @@ - (id) init
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, bitsPerColorComponent);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
+
_colorSaturation = 1.0f;
-
+
_hdrOutput = NO;
#if OOLITE_WINDOWS
_hdrMaxBrightness = [prefs oo_floatForKey:@"hdr-max-brightness" defaultValue:1000.0f];
@@ -322,13 +322,13 @@ - (id) init
_hdrOutput = YES;
}
#endif
-
+
_sdrToneMapper = OOSDRToneMapperFromString([prefs oo_stringForKey:@"sdr-tone-mapper" defaultValue:@"OOSDR_TONEMAPPER_ACES"]);
-
+
// V-sync settings - we set here, but can only verify after SDL_SetVideoMode has been called.
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vSyncPreference); // V-sync on by default.
OOLog(@"display.initGL", @"V-Sync %@requested.", vSyncPreference ? @"" : @"not ");
-
+
/* Multisampling significantly improves graphics quality with
* basically no extra programming effort on our part, especially
* for curved surfaces like the planet, but is also expensive - in
@@ -354,14 +354,14 @@ - (id) init
// Set up the drawing surface's dimensions.
firstScreen= (fullScreen) ? [self modeAsSize: currentSize] : currentWindowSize;
viewSize = firstScreen; // viewSize must be set prior to splash screen initialization
-
+
#if OOLITE_WINDOWS
ShowWindow(SDL_Window,SW_SHOWMINIMIZED);
#endif
OOLog(@"display.initGL", @"Trying %d-bpcc, 24-bit depth buffer", bitsPerColorComponent);
[self createSurface];
-
+
if (surface == NULL)
{
// Retry with hardcoded 8 bits per color component
@@ -372,7 +372,7 @@ - (id) init
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
[self createSurface];
-
+
if (surface == NULL)
{
// Still not working? One last go...
@@ -405,7 +405,7 @@ - (id) init
}
}
}
-
+
int testAttrib = -1;
OOLog(@"display.initGL", @"%@", @"Achieved color / depth buffer sizes (bits):");
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &testAttrib);
@@ -424,7 +424,7 @@ - (id) init
OOLog(@"display.initGL", @"Pixel format index: %d", GetPixelFormat(GetDC(SDL_Window)));
#endif
-
+
// Verify V-sync successfully set - report it if not
if (vSyncPreference && SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &vSyncValue) == -1)
{
@@ -439,7 +439,7 @@ - (id) init
virtualJoystickPosition = NSMakePoint(0.0,0.0);
mouseWarped = NO;
-
+
_mouseVirtualStickSensitivityFactor = OOClamp_0_1_f([prefs oo_floatForKey:@"mouse-flight-sensitivity" defaultValue:0.95f]);
// ensure no chance of a divide by zero later on
if (_mouseVirtualStickSensitivityFactor < 0.005f) _mouseVirtualStickSensitivityFactor = 0.005f;
@@ -449,7 +449,7 @@ - (id) init
isAlphabetKeyDown = NO;
timeIntervalAtLastClick = timeSinceLastMouseWheel = [NSDate timeIntervalSinceReferenceDate];
-
+
_mouseWheelDelta = 0.0f;
m_glContextInitialized = NO;
@@ -524,7 +524,7 @@ - (void) initKeyMappingData
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// load in our keyboard scancode mappings
-#if OOLITE_WINDOWS
+#if OOLITE_WINDOWS
NSDictionary *kmap = [NSDictionary dictionaryWithDictionary:[ResourceManager dictionaryFromFilesNamed:@"keymappings_windows.plist" inFolder:@"Config" mergeMode:MERGE_BASIC cache:NO]];
#else
NSDictionary *kmap = [NSDictionary dictionaryWithDictionary:[ResourceManager dictionaryFromFilesNamed:@"keymappings_linux.plist" inFolder:@"Config" mergeMode:MERGE_BASIC cache:NO]];
@@ -556,7 +556,7 @@ - (void) dealloc
if (keyMappings_normal)
[keyMappings_normal release];
-
+
if (keyMappings_shifted)
[keyMappings_shifted release];
@@ -715,9 +715,12 @@ - (void) toggleScreenMode
#endif
}
else
+ {
[self initialiseGLWithSize: currentWindowSize];
-
-
+#if OOLITE_LINUX
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+#endif
+ }
// do screen resizing updates
if ([PlayerEntity sharedPlayer])
{
@@ -1044,17 +1047,17 @@ - (void) resetSDLKeyModifiers
//OO_RESET_SDLKEY_MODIFIER(VK_LMENU, KMOD_LALT, SDLK_LALT);
//OO_RESET_SDLKEY_MODIFIER(VK_RMENU, KMOD_RALT, SDLK_RALT);
//opt = (modState & KMOD_LALT || modState & KMOD_RALT);
-
+
//Ctrl key
OO_RESET_SDLKEY_MODIFIER(VK_LCONTROL, KMOD_LCTRL, SDLK_LCTRL);
OO_RESET_SDLKEY_MODIFIER(VK_RCONTROL, KMOD_RCTRL, SDLK_RCTRL);
ctrl = (modState & KMOD_LCTRL || modState & KMOD_RCTRL);
-
+
// Shift key
OO_RESET_SDLKEY_MODIFIER(VK_LSHIFT, KMOD_LSHIFT, SDLK_LSHIFT);
OO_RESET_SDLKEY_MODIFIER(VK_RSHIFT, KMOD_RSHIFT, SDLK_RSHIFT);
shift = (modState & KMOD_LSHIFT || modState & KMOD_RSHIFT);
-
+
// Caps Lock key state
if (GetKeyState(VK_CAPITAL) & 0x0001)
{
@@ -1067,7 +1070,7 @@ - (void) resetSDLKeyModifiers
keyState[SDLK_CAPSLOCK] = SDL_RELEASED;
}
}
-
+
SDL_SetModState(modState);
}
@@ -1075,11 +1078,11 @@ - (void) resetSDLKeyModifiers
- (void) setWindowBorderless:(BOOL)borderless
{
LONG currentWindowStyle = GetWindowLong(SDL_Window, GWL_STYLE);
-
+
// window already has the desired style?
if ((!borderless && (currentWindowStyle & WS_CAPTION)) ||
(borderless && !(currentWindowStyle & WS_CAPTION))) return;
-
+
if (borderless)
{
SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle & ~WS_CAPTION & ~WS_THICKFRAME);
@@ -1105,7 +1108,7 @@ - (BOOL) isDarkModeOn
{
char buffer[4];
DWORD bufferSize = sizeof(buffer);
-
+
// reading a REG_DWORD value from the Registry
HRESULT resultRegGetValue = RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
L"AppsUseLightTheme", RRF_RT_REG_DWORD, NULL, buffer, &bufferSize);
@@ -1113,10 +1116,10 @@ - (BOOL) isDarkModeOn
{
return NO;
}
-
+
// get our 4 obtained bytes into integer little endian format
int i = (int)(buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0]);
-
+
// dark mode is 0, light mode is 1
return i == 0;
}
@@ -1143,18 +1146,18 @@ - (BOOL) isOutputDisplayHDREnabled
LONG tempResult = ERROR_SUCCESS;
BOOL isAdvColorInfo2DetectionSuccess = NO;
BOOL result = NO;
-
+
do
{
// determine how many path and mode structures to allocate
tempResult = GetDisplayConfigBufferSizes(flags, &pathCount, &modeCount);
-
+
if (tempResult != ERROR_SUCCESS)
{
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: %ld", HRESULT_FROM_WIN32(tempResult));
return NO;
}
-
+
// allocate the path and mode arrays
pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(pathCount * sizeof(DISPLAYCONFIG_PATH_INFO));
if (!pPathInfoArray)
@@ -1162,7 +1165,7 @@ - (BOOL) isOutputDisplayHDREnabled
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: -1");
return NO;
}
-
+
pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(modeCount * sizeof(DISPLAYCONFIG_MODE_INFO));
if (!pModeInfoArray)
{
@@ -1171,16 +1174,16 @@ - (BOOL) isOutputDisplayHDREnabled
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: -1");
return NO;
}
-
+
// get all active paths and their modes
tempResult = QueryDisplayConfig(flags, &pathCount, pPathInfoArray, &modeCount, pModeInfoArray, NULL);
-
+
if (tempResult != ERROR_SUCCESS)
{
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: %ld", HRESULT_FROM_WIN32(tempResult));
return NO;
}
-
+
// the function may have returned fewer paths/modes than estimated
pPathInfoArray = realloc(pPathInfoArray, pathCount * sizeof(DISPLAYCONFIG_PATH_INFO));
if (!pPathInfoArray)
@@ -1194,11 +1197,11 @@ - (BOOL) isOutputDisplayHDREnabled
OOLogERR(@"gameView.isOutputDisplayHDREnabled", @"Failed to reallocate pModeInfoArray");
exit (1);
}
-
+
// it's possible that between the call to GetDisplayConfigBufferSizes and QueryDisplayConfig
// that the display state changed, so loop on the case of ERROR_INSUFFICIENT_BUFFER.
} while (tempResult == ERROR_INSUFFICIENT_BUFFER);
-
+
if (tempResult != ERROR_SUCCESS)
{
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: %ld", HRESULT_FROM_WIN32(tempResult));
@@ -1242,9 +1245,9 @@ - (BOOL) isOutputDisplayHDREnabled
}
}
}
-
+
finished:
-
+
for (i = 0; i < pathCount; i++)
{
DISPLAYCONFIG_PATH_INFO *path = &pPathInfoArray[i];
@@ -1255,48 +1258,48 @@ - (BOOL) isOutputDisplayHDREnabled
targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
targetName.header.size = sizeof(targetName);
tempResult = DisplayConfigGetDeviceInfo(&targetName.header);
-
+
if (tempResult != ERROR_SUCCESS)
{
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: %ld", HRESULT_FROM_WIN32(tempResult));
return NO;
}
-
+
// find the advanced color information using the more reliable advanced color info 2 api
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO_2 advColorInfo2 = {};
advColorInfo2.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO_2;
advColorInfo2.header.adapterId = path->targetInfo.adapterId;
advColorInfo2.header.id = path->targetInfo.id;
advColorInfo2.header.size = sizeof(advColorInfo2);
-
+
tempResult = DisplayConfigGetDeviceInfo(&advColorInfo2.header);
-
+
if (tempResult == ERROR_SUCCESS) isAdvColorInfo2DetectionSuccess = YES;
else
{
OOLogWARN(@"gameView.isOutputDisplayHDREnabled", @"Received 0x%08lX while attempting to detect HDR mode using Advanced Color Info 2 API. Retrying detection using legacy API.", HRESULT_FROM_WIN32(tempResult));
// no return, just fall through and try again using standard advanced color info api
}
-
+
// find the advanced color information
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {};
advColorInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
advColorInfo.header.adapterId = path->targetInfo.adapterId;
advColorInfo.header.id = path->targetInfo.id;
advColorInfo.header.size = sizeof(advColorInfo);
-
+
tempResult = DisplayConfigGetDeviceInfo(&advColorInfo.header);
-
+
if (tempResult != ERROR_SUCCESS)
{
OOLog(@"gameView.isOutputDisplayHDREnabled", @"Error! Code: %ld", HRESULT_FROM_WIN32(tempResult));
return NO;
}
-
+
BOOL isPrimaryDisplayDevice = !wcscmp(targetName.monitorDevicePath, wcsPrimaryDeviceID);
// we are starting om the primary device, so check that one for advanced color support
- // we also ensure that wide color gamut SDR displays do not get incorrectly detected as supporting HDR
- if (isPrimaryDisplayDevice &&
+ // we also ensure that wide color gamut SDR displays do not get incorrectly detected as supporting HDR
+ if (isPrimaryDisplayDevice &&
((isAdvColorInfo2DetectionSuccess && advColorInfo2.highDynamicRangeSupported && advColorInfo2.activeColorMode == DISPLAYCONFIG_ADVANCED_COLOR_MODE_HDR) ||
(!isAdvColorInfo2DetectionSuccess && advColorInfo.advancedColorSupported && advColorInfo.advancedColorEnabled && !advColorInfo.wideColorEnforced)))
{
@@ -1304,9 +1307,9 @@ - (BOOL) isOutputDisplayHDREnabled
break;
}
}
-
+
OOLog(@"gameView.isOutputDisplayHDREnabled", @"HDR display output requested - checking availability: %@", result ? @"YES" : @"NO");
-
+
free (pModeInfoArray);
free (pPathInfoArray);
@@ -1325,7 +1328,7 @@ - (void) setHDRMaxBrightness: (float)newMaxBrightness
if (newMaxBrightness < MIN_HDR_MAXBRIGHTNESS) newMaxBrightness = MIN_HDR_MAXBRIGHTNESS;
if (newMaxBrightness > MAX_HDR_MAXBRIGHTNESS) newMaxBrightness = MAX_HDR_MAXBRIGHTNESS;
_hdrMaxBrightness = newMaxBrightness;
-
+
[[NSUserDefaults standardUserDefaults] setFloat:_hdrMaxBrightness forKey:@"hdr-max-brightness"];
}
@@ -1341,7 +1344,7 @@ - (void) setHDRPaperWhiteBrightness: (float)newPaperWhiteBrightness
if (newPaperWhiteBrightness < MIN_HDR_PAPERWHITE) newPaperWhiteBrightness = MIN_HDR_PAPERWHITE;
if (newPaperWhiteBrightness > MAX_HDR_PAPERWHITE) newPaperWhiteBrightness = MAX_HDR_PAPERWHITE;
_hdrPaperWhiteBrightness = newPaperWhiteBrightness;
-
+
[[NSUserDefaults standardUserDefaults] setFloat:_hdrPaperWhiteBrightness forKey:@"hdr-paperwhite-brightness"];
}
@@ -1435,7 +1438,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
viewSize = v_size;
OOLog(@"display.initGL", @"Requested a new surface of %d x %d, %@.", (int)viewSize.width, (int)viewSize.height,(fullScreen ? @"fullscreen" : @"windowed"));
SDL_GL_SwapBuffers(); // clear the buffer before resize
-
+
#if OOLITE_WINDOWS
if (!updateContext) return;
@@ -1443,11 +1446,11 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
settings.dmSize = sizeof(DEVMODE);
settings.dmDriverExtra = 0;
EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &settings);
-
+
WINDOWPLACEMENT windowPlacement;
windowPlacement.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(SDL_Window, &windowPlacement);
-
+
static BOOL lastWindowPlacementMaximized = NO;
if (fullScreen && (windowPlacement.showCmd == SW_SHOWMAXIMIZED))
{
@@ -1456,35 +1459,35 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
lastWindowPlacementMaximized = YES;
}
}
-
+
if (lastWindowPlacementMaximized)
{
windowPlacement.showCmd = SW_SHOWMAXIMIZED;
}
-
- // are we attempting to go to a different screen resolution? Note: this also takes care of secondary monitor situations because
+
+ // are we attempting to go to a different screen resolution? Note: this also takes care of secondary monitor situations because
// by design the only resolution available for fullscreen on a secondary display device is its native one - Nikos 20150605
BOOL changingResolution = [self isRunningOnPrimaryDisplayDevice] &&
((fullScreen && (settings.dmPelsWidth != viewSize.width || settings.dmPelsHeight != viewSize.height)) ||
(wasFullScreen && (settings.dmPelsWidth != [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayWidth] intValue]
|| settings.dmPelsHeight != [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayHeight] intValue])));
-
+
RECT wDC;
if (fullScreen)
{
/*NOTE: If we ever decide to change the default behaviour of launching
- always on primary monitor to launching on the monitor the program was
+ always on primary monitor to launching on the monitor the program was
started on, all that needs to be done is comment out the line below, as
well as the identical one in the else branch further down.
Nikos 20141222
*/
[self getCurrentMonitorInfo: &monitorInfo];
-
+
settings.dmPelsWidth = viewSize.width;
settings.dmPelsHeight = viewSize.height;
settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
-
+
// just before going fullscreen, save the location of the current window. It
// may be needed in case of potential attempts to move our fullscreen window
// in a maximized state (yes, in Windows this is entirely possible).
@@ -1496,7 +1499,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
SetWindowPlacement(SDL_Window, &windowPlacement);
}
else GetWindowRect(SDL_Window, &lastGoodRect);
-
+
// ok, can go fullscreen now
SetForegroundWindow(SDL_Window);
if (changingResolution)
@@ -1510,14 +1513,14 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
atDesktopResolution = settings.dmPelsWidth == [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayWidth] intValue]
&& settings.dmPelsHeight == [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayHeight] intValue];
}
-
+
MoveWindow(SDL_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, (int)viewSize.width, (int)viewSize.height, TRUE);
if(!wasFullScreen)
{
[self setWindowBorderless:YES];
}
}
-
+
else if ( wasFullScreen )
{
if (changingResolution)
@@ -1528,9 +1531,9 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
atDesktopResolution = YES;
}
}
-
+
/*NOTE: If we ever decide to change the default behaviour of launching
- always on primary monitor to launching on the monitor the program was
+ always on primary monitor to launching on the monitor the program was
started on, we need to comment out the line below.
For now, this line is needed for correct positioning of our window in case
we return from a non-native resolution fullscreen and has to come after the
@@ -1538,7 +1541,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
Nikos 20141222
*/
[self getCurrentMonitorInfo: &monitorInfo];
-
+
if (lastWindowPlacementMaximized) CopyRect(&windowPlacement.rcNormalPosition, &lastGoodRect);
SetWindowPlacement(SDL_Window, &windowPlacement);
if (!lastWindowPlacementMaximized)
@@ -1549,13 +1552,13 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
monitorInfo.rcMonitor.top,
(int)viewSize.width, (int)viewSize.height, TRUE);
}
-
+
[self setWindowBorderless:NO];
-
+
lastWindowPlacementMaximized = NO;
ShowWindow(SDL_Window,SW_SHOW);
}
-
+
// stop saveWindowSize from reacting to caption & frame if necessary
saveSize = !wasFullScreen;
@@ -1567,7 +1570,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
// Resize the game window if needed. When we ask for a W x H
// window, we intend that the client area be W x H. The actual
// window itself must become big enough to accomodate an area
- // of such size.
+ // of such size.
if (wasFullScreen) // this is true when switching from full screen or when starting in windowed mode
// after the splash screen has ended
{
@@ -1586,7 +1589,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
// Reset bounds and viewSize to current values
bounds.size.width = viewSize.width = wDC.right - wDC.left;
bounds.size.height = viewSize.height = wDC.bottom - wDC.top;
-
+
if (fullScreen) // bounds on fullscreen coincide with client area, since we are borderless
{
bounds.origin.x = monitorInfo.rcMonitor.left;
@@ -1732,7 +1735,7 @@ - (BOOL) snapShot:(NSString *)filename
{
glReadPixels(0, y, surface->w, 1, GL_RGB, GL_UNSIGNED_BYTE, pixls + off);
}
-
+
tmpSurface=SDL_CreateRGBSurfaceFrom(pixls,surface->w,surface->h,24,surface->w*3,0xFF,0xFF00,0xFF0000,0x0);
#if SNAPSHOTS_PNG_FORMAT
if(![self pngSaveSurface:pathToPic withSurface:tmpSurface])
@@ -1749,21 +1752,21 @@ - (BOOL) snapShot:(NSString *)filename
#endif
SDL_FreeSurface(tmpSurface);
free(pixls);
-
+
// if outputting HDR signal, save also either an .exr or a Radiance .hdr snapshot
if ([self hdrOutput])
{
NSString *fileExtension = [[NSUserDefaults standardUserDefaults] oo_stringForKey:@"hdr-snapshot-format" defaultValue:SNAPSHOTHDR_EXTENSION_DEFAULT];
-
+
// we accept file extension with or without a leading dot; if it is without, insert it at the beginning now
if (![[fileExtension substringToIndex:1] isEqual:@"."]) fileExtension = [@"." stringByAppendingString:fileExtension];
-
+
if (![fileExtension isEqual:SNAPSHOTHDR_EXTENSION_EXR] && ![fileExtension isEqual:SNAPSHOTHDR_EXTENSION_HDR])
{
OOLog(@"screenshotHDR", @"Unrecognized HDR file format requested, defaulting to %@", SNAPSHOTHDR_EXTENSION_DEFAULT);
fileExtension = SNAPSHOTHDR_EXTENSION_DEFAULT;
}
-
+
NSString *pathToPicHDR = [pathToPic stringByReplacingString:@".png" withString:fileExtension];
OOLog(@"screenshot", @"Saving screen shot \"%@\" (%u x %u pixels).", pathToPicHDR, surface->w, surface->h);
GLfloat *pixlsf = (GLfloat *)malloc(pitch * surface->h * sizeof(GLfloat));
@@ -1771,17 +1774,17 @@ - (BOOL) snapShot:(NSString *)filename
{
glReadPixels(0, y, surface->w, 1, GL_RGB, GL_FLOAT, pixlsf + off);
}
-
+
if (([fileExtension isEqual:SNAPSHOTHDR_EXTENSION_EXR] && SaveEXRSnapshot([pathToPicHDR cStringUsingEncoding:NSUTF8StringEncoding], surface->w, surface->h, pixlsf) != 0) //TINYEXR_SUCCESS
|| ([fileExtension isEqual:SNAPSHOTHDR_EXTENSION_HDR] && !stbi_write_hdr([pathToPicHDR cStringUsingEncoding:NSUTF8StringEncoding], surface->w, surface->h, 3, pixlsf)))
{
OOLog(@"screenshotHDR", @"Failed to save %@", pathToPicHDR);
snapShotOK = NO;
}
-
+
free(pixlsf);
}
-
+
// return to the previous directory
[[NSFileManager defaultManager] changeCurrentDirectoryPath:originalDirectory];
return snapShotOK;
@@ -1839,7 +1842,7 @@ - (BOOL) pngSaveSurface:(NSString *)fileName withSurface:(SDL_Surface *)surf
}
png_set_IHDR(pngPtr, infoPtr, surf->w, surf->h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
+
// if we are outputting HDR, our backbuffer is linear, so gamma is 1.0. Make sure our png has this info
// note: some image viewers seem to ignore the gAMA chunk; still, this is better than not having it at all
if ([self hdrOutput]) png_set_gAMA(pngPtr, infoPtr, 1.0f);
@@ -2130,6 +2133,10 @@ - (void)pollControls
NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate];
Uint16 key_id;
int scan_code;
+#if OOLITE_LINUX
+ NSSize newSize;
+ bool resize_pending = false;
+#endif
while (SDL_PollEvent(&event))
{
@@ -2206,9 +2213,9 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
}
keys[gvMouseLeftButton] = NO;
}
- /*
+ /*
Mousewheel handling - just note time since last use here and mark as inactive,
- if needed, at the end of this method. Note that the mousewheel button up event is
+ if needed, at the end of this method. Note that the mousewheel button up event is
kind of special, as in, it is sent at the same time as its corresponding mousewheel
button down one - Nikos 20140809
*/
@@ -2304,7 +2311,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
BOOL special_key = NO;
// translate scancode to unicode equiv
- switch (kbd_event->keysym.sym)
+ switch (kbd_event->keysym.sym)
{
case SDLK_LSHIFT:
case SDLK_RSHIFT:
@@ -2317,7 +2324,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
ctrl = YES;
modifier_pressed = YES;
break;
-
+
case SDLK_LALT:
case SDLK_RALT:
opt = YES;
@@ -2370,7 +2377,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
case SDLK_F12:
key_id = 327;
[self toggleScreenMode];
- special_key = YES;
+ special_key = YES;
break;
case SDLK_ESCAPE:
@@ -2392,25 +2399,25 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
// the keyup event doesn't give us the unicode value, so store it here so it can be retrieved on keyup
// the ctrl key tends to mix up the unicode values, so deal with some special cases
- // we also need (in most cases) to get the character without the impact of caps lock.
- if (((!special_key && (ctrl || key_id == 0)) || ([self isCapsLockOn] && (!special_key && !allowingStringInput))) && !modifier_pressed) //
+ // we also need (in most cases) to get the character without the impact of caps lock.
+ if (((!special_key && (ctrl || key_id == 0)) || ([self isCapsLockOn] && (!special_key && !allowingStringInput))) && !modifier_pressed) //
{
// ctrl changes alpha characters to control codes (1-26)
- if (ctrl && key_id >=1 && key_id <= 26)
+ if (ctrl && key_id >=1 && key_id <= 26)
{
- if (shift)
+ if (shift)
key_id += 64; // A-Z is from 65, offset by -1 for the scancode start point
else
key_id += 96; // a-z is from 97, offset by -1 for the scancode start point
- }
- else
+ }
+ else
{
key_id = 0; // reset the value here to force a lookup from the keymappings data
}
}
// if we get here and we still don't have a key id, grab the unicode value from our keymappings dict
- if (key_id == 0)
+ if (key_id == 0)
{
// get unicode value for keycode from keymappings files
// this handles all the non-functional keys. the function keys are handled in the switch above
@@ -2437,11 +2444,11 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
OOLog(kOOLogKeyDown, @"Keydown scancode = %d, unicode = %i, sym = %i, character = %c, shift = %d, ctrl = %d, alt = %d", scan_code, key_id, kbd_event->keysym.sym, key_id, shift, ctrl, opt);
//OOLog(kOOLogKeyDown, @"Keydown scancode = %d, unicode = %i", kbd_event->keysym.scancode, key_id);
- if (key_id > 0 && key_id <= [self numKeys])
+ if (key_id > 0 && key_id <= [self numKeys])
{
keys[key_id] = YES;
}
- else
+ else
{
//OOLog(@"keys.test", @"Unhandled Keydown scancode/unicode: %d %i", scan_code, key_id);
}
@@ -2467,7 +2474,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
case SDLK_RCTRL:
ctrl = NO;
break;
-
+
case SDLK_LALT:
case SDLK_RALT:
opt = NO;
@@ -2477,9 +2484,9 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
}
OOLog(kOOLogKeyUp, @"Keyup scancode = %d, unicode = %i, sym = %i, character = %c, shift = %d, ctrl = %d, alt = %d", scan_code, key_id, kbd_event->keysym.sym, key_id, shift, ctrl, opt);
//OOLog(kOOLogKeyUp, @"Keyup scancode = %d, shift = %d, ctrl = %d, alt = %d", scan_code, shift, ctrl, opt);
-
+
// translate scancode to unicode equiv
- switch (kbd_event->keysym.sym)
+ switch (kbd_event->keysym.sym)
{
case SDLK_KP0: key_id = (!allowingStringInput ? gvNumberPadKey0 : gvNumberKey0); break;
case SDLK_KP1: key_id = (!allowingStringInput ? gvNumberPadKey1 : gvNumberKey1); break;
@@ -2532,11 +2539,11 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
;
}
- if (key_id > 0 && key_id <= [self numKeys])
+ if (key_id > 0 && key_id <= [self numKeys])
{
keys[key_id] = NO;
}
- else
+ else
{
//OOLog(@"keys.test", @"Unhandled Keyup scancode: %d", kbd_event->keysym.scancode);
}
@@ -2545,8 +2552,8 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
case SDL_VIDEORESIZE:
{
SDL_ResizeEvent *rsevt=(SDL_ResizeEvent *)&event;
- NSSize newSize=NSMakeSize(rsevt->w, rsevt->h);
#if OOLITE_WINDOWS
+ NSSize newSize=NSMakeSize(rsevt->w, rsevt->h);
if (!fullScreen && updateContext)
{
if (saveSize == NO)
@@ -2562,8 +2569,8 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
}
}
#else
- [self initialiseGLWithSize: newSize];
- [self saveWindowSize: newSize];
+ newSize=NSMakeSize(rsevt->w, rsevt->h);
+ resize_pending = true;
#endif
// certain gui screens will require an immediate redraw after
// a resize event - Nikos 20140129
@@ -2573,7 +2580,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
}
break;
}
-
+
#if OOLITE_WINDOWS
// if we minimize the window while in fullscreen (e.g. via
// Win+M or Win+DownArrow), restore the non-borderless window
@@ -2582,14 +2589,14 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call
// top in some cases (seen with some Intel gfx chips).
// N.B. active event gain of zero means app is iconified
case SDL_ACTIVEEVENT:
- {
+ {
if ((event.active.state & SDL_APPACTIVE) && fullScreen)
{
[self setWindowBorderless:event.active.gain];
}
break;
}
-
+
// need to track this because the user may move the game window
// to a secondary monitor, in which case we must potentially
// refresh the information displayed (e.g. Game Options screen)
@@ -2609,11 +2616,11 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
if (fullScreen)
{
RECT rDC;
-
+
/* attempting to move our fullscreen window while in maximized state can freak
Windows out and the window may not return to its original position properly.
Solution: if such a move takes place, first change the window placement to
- normal, move it normally, then restore its placement to maximized again.
+ normal, move it normally, then restore its placement to maximized again.
Additionally, the last good known window position seems to be lost in such
a case. While at it, update also the coordinates of the non-maximized window
so that it can return to its original position - this is why we need lastGoodRect.
@@ -2621,7 +2628,7 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(SDL_Window, &wp);
-
+
GetWindowRect(SDL_Window, &rDC);
if (rDC.left != monitorInfo.rcMonitor.left || rDC.top != monitorInfo.rcMonitor.top)
{
@@ -2632,13 +2639,13 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
wp.showCmd = SW_SHOWNORMAL;
SetWindowPlacement(SDL_Window, &wp);
}
-
+
if (wp.showCmd != SW_SHOWMINIMIZED && wp.showCmd != SW_MINIMIZE)
{
MoveWindow(SDL_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
(int)viewSize.width, (int)viewSize.height, TRUE);
}
-
+
if (fullScreenMaximized)
{
GetWindowPlacement(SDL_Window, &wp);
@@ -2664,11 +2671,11 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
rectangle. Therefore we must check whether to clip the mouse or not inside the newly
updated rectangle, so just let it fall through
*/
-
+
case WM_ACTIVATEAPP:
if(grabMouseStatus) [self grabMouseInsideGameWindow:YES];
break;
-
+
case WM_SETTINGCHANGE:
// TODO: we really should be checking the status of event.syswm.msg->lParam here and run our
// dark / light mode refresh check only if the lParam LPCTSTR matches "ImmersiveColorSet".
@@ -2676,12 +2683,12 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
// mode refresh check runs every time something changes the Windows Registry while the game
// is running. Still, should be OK because our refreshDarKOrLightMode will be transparent in
// such cases, plus we would not practically expect too many events doing things to the Registry
- // while we are running. If in the future we need to respond to a different event which changes
+ // while we are running. If in the future we need to respond to a different event which changes
// system settings in real time, then yes, we will have to find a way to decode lParam properly.
// Nikos, 20230805
[self refreshDarKOrLightMode];
break;
-
+
case WM_SETFOCUS:
/*
` make sure that all modifier keys like Shift, Alt, Ctrl and Caps Lock
@@ -2697,7 +2704,7 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
OOLog(@"wm_setfocus.message", @"Setting thread priority to time critical failed! (error code: %ld)", dwLastError);
}
break;
-
+
case WM_KILLFOCUS:
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL))
{
@@ -2705,7 +2712,7 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
OOLog(@"wm_killfocus.message", @"Setting thread priority to normal failed! (error code: %ld)", dwLastError);
}
break;
-
+
default:
;
}
@@ -2727,6 +2734,14 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i
{
_mouseWheelDelta = 0.0f;
}
+#if OOLITE_LINUX
+ if (resize_pending)
+ {
+ [self initialiseGLWithSize: newSize];
+ [self saveWindowSize: newSize];
+ resize_pending = false;
+ }
+#endif
}