diff --git a/GNUmakefile b/GNUmakefile index b71e2a289..8d3205391 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -35,10 +35,11 @@ ifeq ($(GNUSTEP_HOST_OS),mingw32) LIBPNG_LIBRARY_NAME = png ADDITIONAL_INCLUDE_DIRS += -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip -Isrc/SDL/EXRSnapshotSupport - ADDITIONAL_OBJC_LIBS += -lglu32 -lopengl32 -l$(OPENAL_LIBRARY_NAME).dll -l$(LIBPNG_LIBRARY_NAME).dll -lmingw32 -lSDLmain -lSDL -lvorbisfile.dll -lvorbis.dll -lz -lgnustep-base -l$(JS_IMPORT_LIBRARY) -lnspr4 -lshlwapi -ldwmapi -lwinmm -mwindows + ADDITIONAL_OBJC_LIBS += -lglu32 -lopengl32 -l$(OPENAL_LIBRARY_NAME).dll -l$(LIBPNG_LIBRARY_NAME).dll -lmingw32 -lSDL3 -lvorbisfile.dll -lvorbis.dll -lz -lgnustep-base -l$(JS_IMPORT_LIBRARY) -lnspr4 -lshlwapi -ldwmapi -lwinmm -mwindows ADDITIONAL_CFLAGS += -DWIN32 -DNEED_STRLCPY `sdl-config --cflags` -mtune=generic -DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00 -DNTDDI_VERSION=0x0A00000F # note the vpath stuff above isn't working for me, so adding src/SDL and src/Core explicitly ADDITIONAL_OBJCFLAGS += -DLOADSAVEGUI -DWIN32 -DXP_WIN -Wno-import -std=gnu99 `sdl-config --cflags` -mtune=generic -DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00 -DNTDDI_VERSION=0x0A00000F + oolite_LIB_DIRS += -Ldeps/SDL3/x86_64/lib # oolite_LIB_DIRS += -L$(GNUSTEP_LOCAL_ROOT)/lib -L$(WIN_DEPS_DIR)/lib -L$(JS_LIB_DIR) ifeq ($(ESPEAK),yes) @@ -94,7 +95,7 @@ else ADDITIONAL_LDFLAGS += -ggdb3 ADDITIONAL_INCLUDE_DIRS += -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip - ADDITIONAL_OBJC_LIBS += -lGLU -lGL -lX11 -lSDL -lgnustep-base -l$(LIBJS) -lopenal -lz -lvorbisfile -lpng `nspr-config --libs` -lstdc++ + ADDITIONAL_OBJC_LIBS += -lGLU -lGL -lX11 -lSDL3 -lgnustep-base -l$(LIBJS) -lopenal -lz -lvorbisfile -lpng `nspr-config --libs` -lstdc++ ADDITIONAL_OBJCFLAGS += -DLINUX -DXP_UNIX `sdl-config --cflags` ADDITIONAL_CFLAGS += -DLINUX `sdl-config --cflags` ADDITIONAL_LDFLAGS += -Wl,-rpath,'$$ORIGIN' diff --git a/Resources/Config/keymappings_linux.plist b/Resources/Config/keymappings_linux.plist index 0c2735953..fcb0a0e5f 100644 --- a/Resources/Config/keymappings_linux.plist +++ b/Resources/Config/keymappings_linux.plist @@ -7,276 +7,276 @@ description = "Default (US)"; mapping_normal = { "49" = 96; // ` key - "10" = 49; // 1 key - "11" = 50; // 2 key - "12" = 51; // 3 key - "13" = 52; // 4 key - "14" = 53; // 5 key - "15" = 54; // 6 key - "16" = 55; // 7 key - "17" = 56; // 8 key - "18" = 57; // 9 key - "19" = 48; // 0 key - "20" = 45; // - key - "21" = 61; // = key - "24" = 113; // q key - "25" = 119; // w key - "26" = 101; // e key - "27" = 114; // r key - "28" = 116; // t key - "29" = 121; // y key - "30" = 117; // u key - "31" = 105; // i key - "32" = 111; // o key - "33" = 112; // p key - "34" = 91; // [ key - "35" = 93; // ] key - "51" = 92; // \ key - "38" = 97; // a key - "39" = 115; // s key - "40" = 100; // d key - "41" = 102; // f key - "42" = 103; // g key - "43" = 104; // h key - "44" = 106; // j key - "45" = 107; // k key - "46" = 108; // l key - "47" = 59; // ; key - "48" = 39; // ' key - "52" = 122; // z key - "53" = 120; // x key - "54" = 99; // c key - "55" = 118; // v key - "56" = 98; // b key - "57" = 110; // n key - "58" = 109; // m key - "59" = 44; // , key - "60" = 46; // . key - "106" = 47; // / key + "30" = 49; // 1 key + "31" = 50; // 2 key + "32" = 51; // 3 key + "33" = 52; // 4 key + "34" = 53; // 5 key + "35" = 54; // 6 key + "36" = 55; // 7 key + "37" = 56; // 8 key + "38" = 57; // 9 key + "39" = 48; // 0 key + "45" = 45; // - key + "46" = 61; // = key + "20" = 113; // q key + "26" = 119; // w key + "8" = 101; // e key + "21" = 114; // r key + "23" = 116; // t key + "28" = 121; // y key + "24" = 117; // u key + "12" = 105; // i key + "18" = 111; // o key + "19" = 112; // p key + "47" = 91; // [ key + "48" = 93; // ] key + "49" = 92; // \ key + "4" = 97; // a key + "22" = 115; // s key + "7" = 100; // d key + "9" = 102; // f key + "10" = 103; // g key + "11" = 104; // h key + "13" = 106; // j key + "14" = 107; // k key + "15" = 108; // l key + "51" = 59; // ; key + "52" = 39; // ' key + "29" = 122; // z key + "27" = 120; // x key + "6" = 99; // c key + "25" = 118; // v key + "5" = 98; // b key + "17" = 110; // n key + "16" = 109; // m key + "54" = 44; // , key + "55" = 46; // . key + "56" = 47; // / key // numpad keys - internal number refs - "91" = 324; // . key - "86" = 323; // + key - "82" = 322; // - key - "63" = 321; // * key - "106" = 320; // / key - "90" = 310; //48; // 0 key - "87" = 311; //49; // 1 key - "88" = 312; //50; // 2 key - "89" = 313; //51; // 3 key - "83" = 314; //52; // 4 key - "84" = 315; //53; // 5 key - "85" = 316; //54; // 6 key - "79" = 317; //55; // 7 key - "80" = 318; //56; // 8 key - "81" = 319; //57; // 9 key - "104" = 326; //numpad enter + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; mapping_shifted = { "49" = 126; // ~ key - "10" = 33; // ! key - "11" = 64; // @ key - "12" = 35; // # key - "13" = 36; // $ key - "14" = 37; // % key - "15" = 94; // ^ key - "16" = 38; // & key - "17" = 42; // * key - "18" = 40; // ( key - "19" = 41; // ) key - "20" = 95; // _ key - "21" = 43; // + key - "24" = 81; // Q key - "25" = 87; // W key - "26" = 69; // E key - "27" = 82; // R key - "28" = 84; // T key - "29" = 89; // Y key - "30" = 85; // U key - "31" = 73; // I key - "32" = 79; // O key - "33" = 80; // P key - "34" = 123; // { key - "35" = 125; // } key - "51" = 124; // | key - "38" = 65; // A key - "39" = 83; // S key - "40" = 68; // D key - "41" = 70; // F key - "42" = 71; // G key - "43" = 72; // H key - "44" = 74; // J key - "45" = 75; // K key - "46" = 76; // L key - "47" = 58; // : key - "48" = 34; // " key - "52" = 90; // Z key - "53" = 88; // X key - "54" = 67; // C key - "55" = 86; // V key - "56" = 66; // B key - "57" = 78; // N key - "58" = 77; // M key - "59" = 60; // < key - "60" = 62; // > key - "106" = 63; // ? key + "30" = 33; // ! key + "31" = 64; // @ key + "32" = 35; // # key + "33" = 36; // $ key + "34" = 37; // % key + "35" = 94; // ^ key + "36" = 38; // & key + "37" = 42; // * key + "38" = 40; // ( key + "39" = 41; // ) key + "45" = 95; // _ key + "46" = 43; // + key + "20" = 81; // Q key + "26" = 87; // W key + "8" = 69; // E key + "21" = 82; // R key + "23" = 84; // T key + "28" = 89; // Y key + "24" = 85; // U key + "12" = 73; // I key + "18" = 79; // O key + "19" = 80; // P key + "47" = 123; // { key + "48" = 125; // } key + "49" = 124; // | key + "4" = 65; // A key + "22" = 83; // S key + "7" = 68; // D key + "9" = 70; // F key + "10" = 71; // G key + "11" = 72; // H key + "13" = 74; // J key + "14" = 75; // K key + "15" = 76; // L key + "51" = 58; // : key + "52" = 34; // " key + "29" = 90; // Z key + "27" = 88; // X key + "6" = 67; // C key + "25" = 86; // V key + "5" = 66; // B key + "17" = 78; // N key + "16" = 77; // M key + "54" = 60; // < key + "55" = 62; // > key + "56" = 63; // ? key // numpad keys - internal number refs - "91" = 324; // . key - "86" = 323; // + key - "82" = 322; // - key - "63" = 321; // * key - "106" = 320; // / key - "90" = 310; //48; // 0 key - "87" = 311; //49; // 1 key - "88" = 312; //50; // 2 key - "89" = 313; //51; // 3 key - "83" = 314; //52; // 4 key - "84" = 315; //53; // 5 key - "85" = 316; //54; // 6 key - "79" = 317; //55; // 7 key - "80" = 318; //56; // 8 key - "81" = 319; //57; // 9 key - "104" = 326; //numpad enter + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; }; "gbr" = { description = "UK"; mapping_normal = { - "49" = 96; // ` key - "10" = 49; // 1 key - "11" = 50; // 2 key - "12" = 51; // 3 key - "13" = 52; // 4 key - "14" = 53; // 5 key - "15" = 54; // 6 key - "16" = 55; // 7 key - "17" = 56; // 8 key - "18" = 57; // 9 key - "19" = 48; // 0 key - "20" = 45; // - key - "21" = 61; // = key - "24" = 113; // q key - "25" = 119; // w key - "26" = 101; // e key - "27" = 114; // r key - "28" = 116; // t key - "29" = 121; // y key - "30" = 117; // u key - "31" = 105; // i key - "32" = 111; // o key - "33" = 112; // p key - "34" = 91; // [ key - "35" = 93; // ] key - "51" = 35; // # key - "38" = 97; // a key - "39" = 115; // s key - "40" = 100; // d key - "41" = 102; // f key - "42" = 103; // g key - "43" = 104; // h key - "44" = 106; // j key - "45" = 107; // k key - "46" = 108; // l key - "47" = 59; // ; key - "48" = 39; // ' key - "94" = 92; // \ key - "52" = 122; // z key - "53" = 120; // x key - "54" = 99; // c key - "55" = 118; // v key - "56" = 98; // b key - "57" = 110; // n key - "58" = 109; // m key - "59" = 44; // , key - "60" = 46; // . key - "106" = 47; // / key + "53" = 96; // ` key + "30" = 49; // 1 key + "31" = 50; // 2 key + "32" = 51; // 3 key + "33" = 52; // 4 key + "34" = 53; // 5 key + "35" = 54; // 6 key + "36" = 55; // 7 key + "37" = 56; // 8 key + "38" = 57; // 9 key + "39" = 48; // 0 key + "45" = 45; // - key + "46" = 61; // = key + "20" = 113; // q key + "26" = 119; // w key + "8" = 101; // e key + "21" = 114; // r key + "23" = 116; // t key + "28" = 121; // y key + "24" = 117; // u key + "12" = 105; // i key + "18" = 111; // o key + "19" = 112; // p key + "47" = 91; // [ key + "48" = 93; // ] key + "50" = 35; // # key + "4" = 97; // a key + "22" = 115; // s key + "7" = 100; // d key + "9" = 102; // f key + "10" = 103; // g key + "11" = 104; // h key + "13" = 106; // j key + "14" = 107; // k key + "15" = 108; // l key + "51" = 59; // ; key + "52" = 39; // ' key + "49" = 92; // \ key + "29" = 122; // z key + "27" = 120; // x key + "6" = 99; // c key + "25" = 118; // v key + "5" = 98; // b key + "17" = 110; // n key + "16" = 109; // m key + "54" = 44; // , key + "55" = 46; // . key + "56" = 47; // / key // numpad keys - internal number refs - "91" = 324; // . key - "86" = 323; // + key - "82" = 322; // - key - "63" = 321; // * key - "106" = 320; // / key - "90" = 310; //48; // 0 key - "87" = 311; //49; // 1 key - "88" = 312; //50; // 2 key - "89" = 313; //51; // 3 key - "83" = 314; //52; // 4 key - "84" = 315; //53; // 5 key - "85" = 316; //54; // 6 key - "79" = 317; //55; // 7 key - "80" = 318; //56; // 8 key - "81" = 319; //57; // 9 key - "104" = 326; //numpad enter + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; mapping_shifted = { - "49" = 172; // ¬ key - "10" = 33; // ! key - "11" = 34; // " key - "12" = 163; // £ key - "13" = 36; // $ key - "14" = 37; // % key - "15" = 94; // ^ key - "16" = 38; // & key - "17" = 42; // * key - "18" = 40; // ( key - "19" = 41; // ) key - "20" = 95; // _ key - "21" = 43; // + key - "24" = 81; // Q key - "25" = 87; // W key - "26" = 69; // E key - "27" = 82; // R key - "28" = 84; // T key - "29" = 89; // Y key - "30" = 85; // U key - "31" = 73; // I key - "32" = 79; // O key - "33" = 80; // P key - "34" = 123; // { key - "35" = 125; // } key - "51" = 126; // ~ key - "38" = 65; // A key - "39" = 83; // S key - "40" = 68; // D key - "41" = 70; // F key - "42" = 71; // G key - "43" = 72; // H key - "44" = 74; // J key - "45" = 75; // K key - "46" = 76; // L key - "47" = 58; // : key - "48" = 64; // @ key - "94" = 124; // | key - "52" = 90; // Z key - "53" = 88; // X key - "54" = 67; // C key - "55" = 86; // V key - "56" = 66; // B key - "57" = 78; // N key - "58" = 77; // M key - "59" = 60; // < key - "60" = 62; // > key - "106" = 63; // ? key + "53" = 172; // ¬ key + "30" = 33; // ! key + "31" = 34; // " key + "32" = 163; // £ key + "33" = 36; // $ key + "34" = 37; // % key + "35" = 94; // ^ key + "36" = 38; // & key + "37" = 42; // * key + "38" = 40; // ( key + "39" = 41; // ) key + "45" = 95; // _ key + "46" = 43; // + key + "20" = 81; // Q key + "26" = 87; // W key + "8" = 69; // E key + "21" = 82; // R key + "23" = 84; // T key + "28" = 89; // Y key + "24" = 85; // U key + "12" = 73; // I key + "18" = 79; // O key + "19" = 80; // P key + "47" = 123; // { key + "48" = 125; // } key + "50" = 126; // ~ key + "4" = 65; // A key + "22" = 83; // S key + "7" = 68; // D key + "9" = 70; // F key + "10" = 71; // G key + "11" = 72; // H key + "13" = 74; // J key + "14" = 75; // K key + "15" = 76; // L key + "51" = 58; // : key + "52" = 64; // @ key + "49" = 124; // | key + "29" = 90; // Z key + "27" = 88; // X key + "6" = 67; // C key + "25" = 86; // V key + "5" = 66; // B key + "17" = 78; // N key + "16" = 77; // M key + "54" = 60; // < key + "55" = 62; // > key + "56" = 63; // ? key // numpad keys - internal number refs - "91" = 324; // . key - "86" = 323; // + key - "82" = 322; // - key - "63" = 321; // * key - "106" = 320; // / key - "90" = 310; //48; // 0 key - "87" = 311; //49; // 1 key - "88" = 312; //50; // 2 key - "89" = 313; //51; // 3 key - "83" = 314; //52; // 4 key - "84" = 315; //53; // 5 key - "85" = 316; //54; // 6 key - "79" = 317; //55; // 7 key - "80" = 318; //56; // 8 key - "81" = 319; //57; // 9 key - "104" = 326; //numpad enter + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; }; "deu" = { diff --git a/Resources/Config/keymappings_windows.plist b/Resources/Config/keymappings_windows.plist index 9643a0395..ee5e31980 100644 --- a/Resources/Config/keymappings_windows.plist +++ b/Resources/Config/keymappings_windows.plist @@ -6,205 +6,277 @@ "default" = { description = "Default (US)"; mapping_normal = { - "41" = 96; // ` key - "2" = 49; // 1 key - "3" = 50; // 2 key - "4" = 51; // 3 key - "5" = 52; // 4 key - "6" = 53; // 5 key - "7" = 54; // 6 key - "8" = 55; // 7 key - "9" = 56; // 8 key - "10" = 57; // 9 key - "11" = 48; // 0 key - "12" = 45; // - key - "13" = 61; // = key - "16" = 113; // q key - "17" = 119; // w key - "18" = 101; // e key - "19" = 114; // r key - "20" = 116; // t key - "21" = 121; // y key - "22" = 117; // u key - "23" = 105; // i key - "24" = 111; // o key - "25" = 112; // p key - "26" = 91; // [ key - "27" = 93; // ] key - "43" = 92; // \ key - "30" = 97; // a key - "31" = 115; // s key - "32" = 100; // d key - "33" = 102; // f key - "34" = 103; // g key - "35" = 104; // h key - "36" = 106; // j key - "37" = 107; // k key - "38" = 108; // l key - "39" = 59; // ; key - "40" = 39; // ' key - "44" = 122; // z key - "45" = 120; // x key - "46" = 99; // c key - "47" = 118; // v key - "48" = 98; // b key - "49" = 110; // n key - "50" = 109; // m key - "51" = 44; // , key - "52" = 46; // . key - "53" = 47; // / key + "49" = 96; // ` key + "30" = 49; // 1 key + "31" = 50; // 2 key + "32" = 51; // 3 key + "33" = 52; // 4 key + "34" = 53; // 5 key + "35" = 54; // 6 key + "36" = 55; // 7 key + "37" = 56; // 8 key + "38" = 57; // 9 key + "39" = 48; // 0 key + "45" = 45; // - key + "46" = 61; // = key + "20" = 113; // q key + "26" = 119; // w key + "8" = 101; // e key + "21" = 114; // r key + "23" = 116; // t key + "28" = 121; // y key + "24" = 117; // u key + "12" = 105; // i key + "18" = 111; // o key + "19" = 112; // p key + "47" = 91; // [ key + "48" = 93; // ] key + "49" = 92; // \ key + "4" = 97; // a key + "22" = 115; // s key + "7" = 100; // d key + "9" = 102; // f key + "10" = 103; // g key + "11" = 104; // h key + "13" = 106; // j key + "14" = 107; // k key + "15" = 108; // l key + "51" = 59; // ; key + "52" = 39; // ' key + "29" = 122; // z key + "27" = 120; // x key + "6" = 99; // c key + "25" = 118; // v key + "5" = 98; // b key + "17" = 110; // n key + "16" = 109; // m key + "54" = 44; // , key + "55" = 46; // . key + "56" = 47; // / key + + // numpad keys - internal number refs + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; mapping_shifted = { - "41" = 126; // ~ key - "2" = 33; // ! key - "3" = 64; // @ key - "4" = 35; // # key - "5" = 36; // $ key - "6" = 37; // % key - "7" = 94; // ^ key - "8" = 38; // & key - "9" = 42; // * key - "10" = 40; // ( key - "11" = 41; // ) key - "12" = 95; // _ key - "13" = 43; // + key - "16" = 81; // Q key - "17" = 87; // W key - "18" = 69; // E key - "19" = 82; // R key - "20" = 84; // T key - "21" = 89; // Y key - "22" = 85; // U key - "23" = 73; // I key - "24" = 79; // O key - "25" = 80; // P key - "26" = 123; // { key - "27" = 125; // } key - "43" = 124; // | key - "30" = 65; // A key - "31" = 83; // S key - "32" = 68; // D key - "33" = 70; // F key - "34" = 71; // G key - "35" = 72; // H key - "36" = 74; // J key - "37" = 75; // K key - "38" = 76; // L key - "39" = 58; // : key - "40" = 34; // " key - "44" = 90; // Z key - "45" = 88; // X key - "46" = 67; // C key - "47" = 86; // V key - "48" = 66; // B key - "49" = 78; // N key - "50" = 77; // M key - "51" = 60; // < key - "52" = 62; // > key - "53" = 63; // ? key + "49" = 126; // ~ key + "30" = 33; // ! key + "31" = 64; // @ key + "32" = 35; // # key + "33" = 36; // $ key + "34" = 37; // % key + "35" = 94; // ^ key + "36" = 38; // & key + "37" = 42; // * key + "38" = 40; // ( key + "39" = 41; // ) key + "45" = 95; // _ key + "46" = 43; // + key + "20" = 81; // Q key + "26" = 87; // W key + "8" = 69; // E key + "21" = 82; // R key + "23" = 84; // T key + "28" = 89; // Y key + "24" = 85; // U key + "12" = 73; // I key + "18" = 79; // O key + "19" = 80; // P key + "47" = 123; // { key + "48" = 125; // } key + "49" = 124; // | key + "4" = 65; // A key + "22" = 83; // S key + "7" = 68; // D key + "9" = 70; // F key + "10" = 71; // G key + "11" = 72; // H key + "13" = 74; // J key + "14" = 75; // K key + "15" = 76; // L key + "51" = 58; // : key + "52" = 34; // " key + "29" = 90; // Z key + "27" = 88; // X key + "6" = 67; // C key + "25" = 86; // V key + "5" = 66; // B key + "17" = 78; // N key + "16" = 77; // M key + "54" = 60; // < key + "55" = 62; // > key + "56" = 63; // ? key + + // numpad keys - internal number refs + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; }; "gbr" = { description = "UK"; mapping_normal = { - "41" = 96; // ` key - "2" = 49; // 1 key - "3" = 50; // 2 key - "4" = 51; // 3 key - "5" = 52; // 4 key - "6" = 53; // 5 key - "7" = 54; // 6 key - "8" = 55; // 7 key - "9" = 56; // 8 key - "10" = 57; // 9 key - "11" = 48; // 0 key - "12" = 45; // - key - "13" = 61; // = key - "16" = 113; // q key - "17" = 119; // w key - "18" = 101; // e key - "19" = 114; // r key - "20" = 116; // t key - "21" = 121; // y key - "22" = 117; // u key - "23" = 105; // i key - "24" = 111; // o key - "25" = 112; // p key - "26" = 91; // [ key - "27" = 93; // ] key - "43" = 35; // # key - "30" = 97; // a key - "31" = 115; // s key - "32" = 100; // d key - "33" = 102; // f key - "34" = 103; // g key - "35" = 104; // h key - "36" = 106; // j key - "37" = 107; // k key - "38" = 108; // l key - "39" = 59; // ; key - "40" = 39; // ' key - "86" = 92; // \ key - "44" = 122; // z key - "45" = 120; // x key - "46" = 99; // c key - "47" = 118; // v key - "48" = 98; // b key - "49" = 110; // n key - "50" = 109; // m key - "51" = 44; // , key - "52" = 46; // . key - "53" = 47; // / key + "53" = 96; // ` key + "30" = 49; // 1 key + "31" = 50; // 2 key + "32" = 51; // 3 key + "33" = 52; // 4 key + "34" = 53; // 5 key + "35" = 54; // 6 key + "36" = 55; // 7 key + "37" = 56; // 8 key + "38" = 57; // 9 key + "39" = 48; // 0 key + "45" = 45; // - key + "46" = 61; // = key + "20" = 113; // q key + "26" = 119; // w key + "8" = 101; // e key + "21" = 114; // r key + "23" = 116; // t key + "28" = 121; // y key + "24" = 117; // u key + "12" = 105; // i key + "18" = 111; // o key + "19" = 112; // p key + "47" = 91; // [ key + "48" = 93; // ] key + "50" = 35; // # key + "4" = 97; // a key + "22" = 115; // s key + "7" = 100; // d key + "9" = 102; // f key + "10" = 103; // g key + "11" = 104; // h key + "13" = 106; // j key + "14" = 107; // k key + "15" = 108; // l key + "51" = 59; // ; key + "52" = 39; // ' key + "49" = 92; // \ key + "29" = 122; // z key + "27" = 120; // x key + "6" = 99; // c key + "25" = 118; // v key + "5" = 98; // b key + "17" = 110; // n key + "16" = 109; // m key + "54" = 44; // , key + "55" = 46; // . key + "56" = 47; // / key + + // numpad keys - internal number refs + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; mapping_shifted = { - "41" = 172; // ¬ key - "2" = 33; // ! key - "3" = 34; // " key - "4" = 163; // £ key - "5" = 36; // $ key - "6" = 37; // % key - "7" = 94; // ^ key - "8" = 38; // & key - "9" = 42; // * key - "10" = 40; // ( key - "11" = 41; // ) key - "12" = 95; // _ key - "13" = 43; // + key - "16" = 81; // Q key - "17" = 87; // W key - "18" = 69; // E key - "19" = 82; // R key - "20" = 84; // T key - "21" = 89; // Y key - "22" = 85; // U key - "23" = 73; // I key - "24" = 79; // O key - "25" = 80; // P key - "26" = 123; // { key - "27" = 125; // } key - "43" = 126; // ~ key - "30" = 65; // A key - "31" = 83; // S key - "32" = 68; // D key - "33" = 70; // F key - "34" = 71; // G key - "35" = 72; // H key - "36" = 74; // J key - "37" = 75; // K key - "38" = 76; // L key - "39" = 58; // : key - "40" = 64; // @ key - "86" = 124; // | key - "44" = 90; // Z key - "45" = 88; // X key - "46" = 67; // C key - "47" = 86; // V key - "48" = 66; // B key - "49" = 78; // N key - "50" = 77; // M key - "51" = 60; // < key - "52" = 62; // > key - "53" = 63; // ? key + "53" = 172; // ¬ key + "30" = 33; // ! key + "31" = 34; // " key + "32" = 163; // £ key + "33" = 36; // $ key + "34" = 37; // % key + "35" = 94; // ^ key + "36" = 38; // & key + "37" = 42; // * key + "38" = 40; // ( key + "39" = 41; // ) key + "45" = 95; // _ key + "46" = 43; // + key + "20" = 81; // Q key + "26" = 87; // W key + "8" = 69; // E key + "21" = 82; // R key + "23" = 84; // T key + "28" = 89; // Y key + "24" = 85; // U key + "12" = 73; // I key + "18" = 79; // O key + "19" = 80; // P key + "47" = 123; // { key + "48" = 125; // } key + "50" = 126; // ~ key + "4" = 65; // A key + "22" = 83; // S key + "7" = 68; // D key + "9" = 70; // F key + "10" = 71; // G key + "11" = 72; // H key + "13" = 74; // J key + "14" = 75; // K key + "15" = 76; // L key + "51" = 58; // : key + "52" = 64; // @ key + "49" = 124; // | key + "29" = 90; // Z key + "27" = 88; // X key + "6" = 67; // C key + "25" = 86; // V key + "5" = 66; // B key + "17" = 78; // N key + "16" = 77; // M key + "54" = 60; // < key + "55" = 62; // > key + "56" = 63; // ? key + + // numpad keys - internal number refs + "99" = 324; // . key + "87" = 323; // + key + "86" = 322; // - key + "85" = 321; // * key + "84" = 320; // / key + "98" = 310; //48; // 0 key + "90" = 311; //49; // 1 key + "91" = 312; //50; // 2 key + "92" = 313; //51; // 3 key + "93" = 314; //52; // 4 key + "94" = 315; //53; // 5 key + "95" = 316; //54; // 6 key + "96" = 317; //55; // 7 key + "97" = 318; //56; // 8 key + "98" = 319; //57; // 9 key + "88" = 326; //numpad enter }; }; "deu" = { diff --git a/ShellScripts/Linux/install_package_fn.sh b/ShellScripts/Linux/install_package_fn.sh index e7b2629e4..bb6120be8 100644 --- a/ShellScripts/Linux/install_package_fn.sh +++ b/ShellScripts/Linux/install_package_fn.sh @@ -121,11 +121,11 @@ install_package() { arch) PKG_NAME="glu" ;; esac ;; - "sdl12-compat") + "sdl3") case "$CURRENT_DISTRO" in - debian) PKG_NAME="libsdl1.2-compat-dev" ;; - redhat) PKG_NAME="sdl12-compat-devel" ;; - arch) PKG_NAME="sdl12-compat" ;; + debian) PKG_NAME="libsdl3-dev" ;; + redhat) PKG_NAME="SDL3-devel" ;; + arch) PKG_NAME="sdl3"; esac ;; "x11-dev") diff --git a/ShellScripts/Linux/install_packages_root.sh b/ShellScripts/Linux/install_packages_root.sh index d862238f5..f3aede895 100755 --- a/ShellScripts/Linux/install_packages_root.sh +++ b/ShellScripts/Linux/install_packages_root.sh @@ -114,7 +114,7 @@ run_script() { if ! install_package glu-dev; then return 1 fi - if ! install_package sdl12-compat; then + if ! install_package sdl3; then return 1 fi if ! install_package x11-dev; then diff --git a/ShellScripts/Windows/install_deps.sh b/ShellScripts/Windows/install_deps.sh index e531653f4..e618dda89 100755 --- a/ShellScripts/Windows/install_deps.sh +++ b/ShellScripts/Windows/install_deps.sh @@ -42,10 +42,11 @@ run_script() { pacboy -S uutils-coreutils --noconfirm pacboy -S python-pip --noconfirm pacboy -S mesa --noconfirm + pacboy -S sdl3 --noconfirm cd ../../build/packages echo "Installing common libraries" - local package_names=(spidermonkey SDL) + local package_names=(spidermonkey) for packagename in "${package_names[@]}"; do if ! install $packagename; then return 1 diff --git a/src/Core/Entities/PlayerEntity.h b/src/Core/Entities/PlayerEntity.h index 3d39f9cda..69fc2fcb4 100644 --- a/src/Core/Entities/PlayerEntity.h +++ b/src/Core/Entities/PlayerEntity.h @@ -199,9 +199,6 @@ enum GUI_ROW_GAMEOPTIONS_PROCEDURALLYTEXTUREDPLANETS, #endif GUI_ROW_GAMEOPTIONS_SHADEREFFECTS, -#if OOLITE_SDL - GUI_ROW_GAMEOPTIONS_GAMMA, -#endif GUI_ROW_GAMEOPTIONS_FOV, GUI_ROW_GAMEOPTIONS_COLORBLINDMODE, GUI_ROW_GAMEOPTIONS_SPACER_STICKMAPPER, diff --git a/src/Core/Entities/PlayerEntity.m b/src/Core/Entities/PlayerEntity.m index 5f4ccc3c6..55d113536 100644 --- a/src/Core/Entities/PlayerEntity.m +++ b/src/Core/Entities/PlayerEntity.m @@ -8992,14 +8992,6 @@ - (void) setGuiToGameOptionsScreen [gui setColor:[OOColor grayColor] forRow:GUI_ROW(GAME,VOLUME)]; } -#if OOLITE_SDL - // gamma control - float gamma = [gameView gammaValue]; - int gamma5 = (gamma * 5); - NSString* gammaWordDesc = DESC(@"gameoptions-gamma-value"); - [gui setText:[NSString stringWithFormat:@"%@%@ (%.1f) ", gammaWordDesc, SliderString(gamma5), gamma] forRow:GUI_ROW(GAME,GAMMA) align:GUI_ALIGN_CENTER]; - [gui setKey:GUI_KEY_OK forRow:GUI_ROW(GAME,GAMMA)]; -#endif // field of view control float fov = [gameView fov:NO]; diff --git a/src/Core/Entities/PlayerEntityControls.m b/src/Core/Entities/PlayerEntityControls.m index d3435ec2e..951882061 100644 --- a/src/Core/Entities/PlayerEntityControls.m +++ b/src/Core/Entities/PlayerEntityControls.m @@ -120,9 +120,6 @@ static BOOL leftRightKeyPressed; static BOOL musicModeKeyPressed; static BOOL volumeControlPressed; -#if OOLITE_SDL -static BOOL gammaControlPressed; -#endif static BOOL fovControlPressed; static BOOL hdrMaxBrightnessControlPressed; static BOOL hdrPaperWhiteControlPressed; @@ -3700,34 +3697,6 @@ sets the actual screen resolution (controller just stores } else volumeControlPressed = NO; - -#if OOLITE_SDL - if ((guiSelectedRow == GUI_ROW(GAME,GAMMA)) - &&(([self checkKeyPress:n_key_gui_arrow_right])||([self checkKeyPress:n_key_gui_arrow_left]))) - { - if (!gammaControlPressed) - { - BOOL rightKeyDown = [self checkKeyPress:n_key_gui_arrow_right]; - BOOL leftKeyDown = [self checkKeyPress:n_key_gui_arrow_left]; - float gamma = [gameView gammaValue]; - gamma += (((rightKeyDown && (gamma < 4.0f)) ? 0.2f : 0.0f) - ((leftKeyDown && (gamma > 0.2f)) ? 0.2f : 0.0f)); - if (gamma > 3.95f) gamma = 4.0f; - if (gamma < 0.25f) gamma = 0.2f; - [gameView setGammaValue:gamma]; - int gamma5 = gamma * 5; // avoid rounding errors - NSString* gammaWordDesc = DESC(@"gameoptions-gamma-value"); - NSString* v1_string = @"|||||||||||||||||||||||||"; - NSString* v0_string = @"........................."; - v1_string = [v1_string substringToIndex:gamma5]; - v0_string = [v0_string substringToIndex:20 - gamma5]; - [gui setText:[NSString stringWithFormat:@"%@%@%@ (%.1f) ", gammaWordDesc, v1_string, v0_string, gamma] forRow:GUI_ROW(GAME,GAMMA) align:GUI_ALIGN_CENTER]; - } - gammaControlPressed = YES; - } - else - gammaControlPressed = NO; -#endif - if ((guiSelectedRow == GUI_ROW(GAME,FOV)) &&(([self checkKeyPress:n_key_gui_arrow_right])||([self checkKeyPress:n_key_gui_arrow_left]))) diff --git a/src/Core/NSFileManagerOOExtensions.m b/src/Core/NSFileManagerOOExtensions.m index 8706b5220..979298f06 100644 --- a/src/Core/NSFileManagerOOExtensions.m +++ b/src/Core/NSFileManagerOOExtensions.m @@ -27,7 +27,7 @@ */ #include -#include +#include #import "ResourceManager.h" #import "OOPListParsing.h" #import "GameController.h" diff --git a/src/Core/OOJoystickManager.h b/src/Core/OOJoystickManager.h index 9dec37437..724f40f82 100644 --- a/src/Core/OOJoystickManager.h +++ b/src/Core/OOJoystickManager.h @@ -164,26 +164,25 @@ enum { #if OOLITE_SDL -#import +#import enum { - JOYAXISMOTION = SDL_JOYAXISMOTION, - JOYBUTTONDOWN = SDL_JOYBUTTONDOWN, - JOYBUTTONUP = SDL_JOYBUTTONUP, - JOYBUTTON_PRESSED = SDL_PRESSED, - JOYBUTTON_RELEASED = SDL_RELEASED, - JOYHAT_MOTION = SDL_JOYHATMOTION, - + JOYAXISMOTION = SDL_EVENT_JOYSTICK_AXIS_MOTION, + JOYBUTTONDOWN = SDL_EVENT_JOYSTICK_BUTTON_DOWN, + JOYBUTTONUP = SDL_EVENT_JOYSTICK_BUTTON_UP, + JOYHAT_MOTION = SDL_EVENT_JOYSTICK_HAT_MOTION, JOYHAT_CENTERED = SDL_HAT_CENTERED, - JOYHAT_UP = SDL_HAT_UP, + JOYHAT_UP = SDL_HAT_UP, JOYHAT_RIGHT = SDL_HAT_RIGHT, - JOYHAT_DOWN = SDL_HAT_DOWN, - JOYHAT_LEFT = SDL_HAT_LEFT, + JOYHAT_DOWN = SDL_HAT_DOWN, + JOYHAT_LEFT = SDL_HAT_LEFT, JOYHAT_RIGHTUP = SDL_HAT_RIGHTUP, JOYHAT_RIGHTDOWN = SDL_HAT_RIGHTDOWN, JOYHAT_LEFTUP = SDL_HAT_LEFTUP, JOYHAT_LEFTDOWN = SDL_HAT_LEFTDOWN, + JOYBUTTON_PRESSED, + JOYBUTTON_RELEASED }; typedef SDL_JoyButtonEvent JoyButtonEvent; @@ -202,10 +201,10 @@ enum JOYHAT_MOTION, JOYHAT_CENTERED = 0x00, - JOYHAT_UP = 0x01, + JOYHAT_UP = 0x01, JOYHAT_RIGHT = 0x02, - JOYHAT_DOWN = 0x04, - JOYHAT_LEFT = 0x08, + JOYHAT_DOWN = 0x04, + JOYHAT_LEFT = 0x08, JOYHAT_RIGHTUP = (JOYHAT_RIGHT|JOYHAT_UP), JOYHAT_RIGHTDOWN = (JOYHAT_RIGHT|JOYHAT_DOWN), JOYHAT_LEFTUP = (JOYHAT_LEFT|JOYHAT_UP), @@ -216,24 +215,24 @@ enum typedef struct { uint32_t type; - uint8_t which; + int32_t which; uint8_t axis; - int value; + int16_t value; } JoyAxisEvent; typedef struct { uint32_t type; - uint8_t which; + int32_t which; uint8_t button; - int state; + bool down; } JoyButtonEvent; typedef struct { uint32_t type; - uint8_t which; + int32_t which; uint8_t hat; uint8_t value; uint8_t padding; @@ -263,8 +262,8 @@ typedef struct // the desired function, and the hardware (axis or button etc.) id cbObject; SEL cbSelector; - char cbHardware; - BOOL invertPitch; + char cbHardware; + BOOL invertPitch; } diff --git a/src/Core/OOJoystickManager.m b/src/Core/OOJoystickManager.m index 139aa3fb4..de6a5c0aa 100644 --- a/src/Core/OOJoystickManager.m +++ b/src/Core/OOJoystickManager.m @@ -683,7 +683,7 @@ - (void) decodeHatEvent:(JoyHatEvent *)evt { btn.type = (evt->value & (1 << i)) ? JOYBUTTONDOWN : JOYBUTTONUP; btn.button = MAX_REAL_BUTTONS + i + evt->which * 4; - btn.state = (evt->value & (1 << i)) ? JOYBUTTON_PRESSED : JOYBUTTON_RELEASED; + btn.down = (evt->value & (1 << i)); [self decodeButtonEvent:&btn]; } } diff --git a/src/Core/OOLogOutputHandler.m b/src/Core/OOLogOutputHandler.m index cb65c00ee..950150c63 100644 --- a/src/Core/OOLogOutputHandler.m +++ b/src/Core/OOLogOutputHandler.m @@ -36,7 +36,7 @@ of this software and associated documentation files (the "Software"), to deal #include #import "NSThreadOOExtensions.h" #import "NSFileManagerOOExtensions.h" -#include +#include #undef NSLog // We need to be able to call the real NSLog. diff --git a/src/Core/OOOpenGLExtensionManager.h b/src/Core/OOOpenGLExtensionManager.h index a243ada17..7bff040b7 100644 --- a/src/Core/OOOpenGLExtensionManager.h +++ b/src/Core/OOOpenGLExtensionManager.h @@ -224,10 +224,18 @@ extern PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB; #if OO_SHADERS || OO_MULTITEXTURE +// The SDL3/SDL_opengl.h header file declares glActiveTextureARB symbols as a function, not a function pointer, which means that if we +// try to declare or set glActiveTextureARB we get compiler errors. StackOverflow AI suggests we either use GLEW or we use a declare a different +// name for the symbol. As there are currently only three symbols with this problem, I've gone for the latter approach, creating a macro +// so we can stull use glActiveTexture in the code +// -- kanthoney 2026-05-04 +#define glActiveTextureARB glActiveTextureARBPtr extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; #endif #if OO_MULTITEXTURE +// See note for glActiveTextureARB +#define glClientActiveTextureARB glClientActiveTextureARBPtr extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB; #endif @@ -266,6 +274,8 @@ extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; extern PFNGLUSEPROGRAMPROC glUseProgram; extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; extern PFNGLUNIFORM1IPROC glUniform1i; +// See note for glActiveTextureARB +#define glActiveTexture glActiveTexturePtr extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; extern PFNGLUNIFORM1FPROC glUniform1f; diff --git a/src/Core/OOOpenGLOnly.h b/src/Core/OOOpenGLOnly.h index 367b4fbc7..9d2299ac7 100644 --- a/src/Core/OOOpenGLOnly.h +++ b/src/Core/OOOpenGLOnly.h @@ -55,10 +55,11 @@ MA 02110-1301, USA. #endif // OOLITE_LINUX && !OOLITE_WINDOWS // the standard SDL_opengl.h -#include +#include // include an up-to-date version of glext.h #include +#include #ifdef __DEFINED_GL_GLEXT_PROTOTYPES #undef GL_GLEXT_PROTOTYPES diff --git a/src/Core/ResourceManager.m b/src/Core/ResourceManager.m index 91dd55195..e6cb1c988 100644 --- a/src/Core/ResourceManager.m +++ b/src/Core/ResourceManager.m @@ -467,7 +467,7 @@ + (NSArray *)maskUserNameInPathArray:(NSArray *)inputPathArray { NSString *path = nil; NSMutableArray *maskedArray = [NSMutableArray arrayWithCapacity:[inputPathArray count]]; - char *userNamePathEnvVar = + const char *userNamePathEnvVar = #if OOLITE_WINDOWS SDL_getenv("USERPROFILE"); #else diff --git a/src/Core/Universe.m b/src/Core/Universe.m index 1b7bd4493..9f838e218 100644 --- a/src/Core/Universe.m +++ b/src/Core/Universe.m @@ -609,7 +609,7 @@ - (void) drawTargetTextureIntoDefaultFramebuffer GLhandleARB program = [textureProgram program]; GLhandleARB blur = [blurProgram program]; GLhandleARB final = [finalProgram program]; - NSSize viewSize = [gameView viewSize]; + NSSize viewSize = [gameView backingViewSize]; float fboResolution[2] = {viewSize.width, viewSize.height}; OOGL(glBindFramebuffer(GL_FRAMEBUFFER, passthroughFramebufferID)); @@ -724,7 +724,7 @@ - (id) initWithGameView:(MyOpenGLView *)inGameView [self setDetailLevelDirectly:[prefs oo_intForKey:@"detailLevel" defaultValue:[[OOOpenGLExtensionManager sharedManager] defaultDetailLevel]]]; - [self initTargetFramebufferWithViewSize:[gameView viewSize]]; + [self initTargetFramebufferWithViewSize:[gameView backingViewSize]]; [OOMaterial setUp]; @@ -748,7 +748,6 @@ - (id) initWithGameView:(MyOpenGLView *)inGameView autoSave = [prefs oo_boolForKey:@"autosave" defaultValue:NO]; wireframeGraphics = [prefs oo_boolForKey:@"wireframe-graphics" defaultValue:NO]; doProcedurallyTexturedPlanets = [prefs oo_boolForKey:@"procedurally-textured-planets" defaultValue:YES]; - [inGameView setGammaValue:[prefs oo_floatForKey:@"gamma-value" defaultValue:1.0f]]; [inGameView setMsaa:[prefs oo_boolForKey:@"anti-aliasing" defaultValue:NO]]; OOLog(@"MSAA.setup", @"Multisample anti-aliasing %@requested.", [inGameView msaa] ? @"" : @"not "); [inGameView setFov:OOClamp_0_max_f([prefs oo_floatForKey:@"fov-value" defaultValue:57.2f], MAX_FOV_DEG) fromFraction:NO]; @@ -4519,9 +4518,6 @@ - (NSDictionary *) gameSettings [result oo_setBool:autoSave forKey:@"autosave"]; [result oo_setBool:wireframeGraphics forKey:@"wireframeGraphics"]; [result oo_setBool:doProcedurallyTexturedPlanets forKey:@"procedurallyTexturedPlanets"]; -#if OOLITE_SDL - [result oo_setFloat:[gameView gammaValue] forKey:@"gammaValue"]; -#endif [result oo_setFloat:[gameView fov:NO] forKey:@"fovValue"]; @@ -4548,8 +4544,8 @@ - (NSDictionary *) gameSettings [result setObject:desc forKey:@"musicMode"]; NSDictionary *gameWindow = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithFloat:[gameView viewSize].width], @"width", - [NSNumber numberWithFloat:[gameView viewSize].height], @"height", + [NSNumber numberWithFloat:[gameView backingViewSize].width], @"width", + [NSNumber numberWithFloat:[gameView backingViewSize].height], @"height", [NSNumber numberWithBool:[[self gameController] inFullScreenMode]], @"fullScreen", nil]; [result setObject:gameWindow forKey:@"gameWindow"]; @@ -4828,7 +4824,7 @@ - (void) drawUniverse { int currentPostFX = [self currentPostFX]; BOOL hudSeparateRenderPass = [self useShaders] && (currentPostFX == OO_POSTFX_NONE || ((currentPostFX == OO_POSTFX_CLOAK || currentPostFX == OO_POSTFX_CRTBADSIGNAL) && [self colorblindMode] == OO_POSTFX_NONE)); - NSSize viewSize = [gameView viewSize]; + NSSize viewSize = [gameView backingViewSize]; OOLog(@"universe.profile.draw", @"%@", @"Begin draw"); if (!no_update) @@ -5201,7 +5197,7 @@ - (void) drawUniverse OOCheckOpenGLErrors(@"Universe after drawing entities"); OOLog(@"universe.profile.draw", @"%@", @"Begin HUD"); - GLfloat lineWidth = [gameView viewSize].width / 1024.0; // restore line size + GLfloat lineWidth = [gameView backingViewSize].width / 1024.0; // restore line size if (lineWidth < 1.0) lineWidth = 1.0; if (lineWidth > 1.5) lineWidth = 1.5; // don't overscale; think of ultra-wide screen setups OOGL(GLScaledLineWidth(lineWidth)); @@ -5309,7 +5305,7 @@ - (void) drawUniverse - (void) prepareToRenderIntoDefaultFramebuffer { - NSSize viewSize = [gameView viewSize]; + NSSize viewSize = [gameView backingViewSize]; if([self useShaders]) { if ([gameView msaa]) diff --git a/src/SDL/GameController+SDLFullScreen.m b/src/SDL/GameController+SDLFullScreen.m index 175e0b458..a1c7c0fe7 100644 --- a/src/SDL/GameController+SDLFullScreen.m +++ b/src/SDL/GameController+SDLFullScreen.m @@ -59,10 +59,20 @@ - (void) setUpDisplayModes continue; [displayModes addObject: mode]; } - - NSSize fsmSize = [gameView currentScreenSize]; - width = fsmSize.width; - height = fsmSize.height; + + NSDictionary *currentMode = [gameView currentScreenMode]; + if (currentMode) + { + width = [[currentMode objectForKey: kOODisplayWidth] intValue]; + height = [[currentMode objectForKey: kOODisplayHeight] intValue]; + refresh = [[currentMode objectForKey: kOODisplayRefreshRate] intValue]; + } + else + { + NSSize fsmSize = [gameView currentScreenSize]; + width = fsmSize.width; + height = fsmSize.height; + } } diff --git a/src/SDL/MyOpenGLView.h b/src/SDL/MyOpenGLView.h index f695e76d4..a7decd753 100644 --- a/src/SDL/MyOpenGLView.h +++ b/src/SDL/MyOpenGLView.h @@ -28,7 +28,7 @@ MA 02110-1301, USA. #import "OOOpenGLMatrixManager.h" -#include +#include #define WINDOW_SIZE_DEFAULT_WIDTH 1280 #define WINDOW_SIZE_DEFAULT_HEIGHT 720 @@ -179,7 +179,7 @@ extern int debug; BOOL suppressKeys; // DJS BOOL opt, ctrl, command, shift, lastKeyShifted; - BOOL allowingStringInput; + enum StringInput allowingStringInput; BOOL isAlphabetKeyDown; int keycodetrans[255]; @@ -206,7 +206,6 @@ extern int debug; double squareX,squareY; NSRect bounds; - float _gamma; float _fov; BOOL _msaa; @@ -217,9 +216,13 @@ extern int debug; // Windowed mode NSSize currentWindowSize; - SDL_Surface *surface; BOOL showSplashScreen; + SDL_Window *splashWindow; + SDL_Window *window; + SDL_GLContext glContext; + int bitsPerColorComponent; + BOOL vSyncPreference; #if OOLITE_WINDOWS @@ -228,7 +231,7 @@ extern int debug; BOOL saveSize; BOOL atDesktopResolution; unsigned keyboardMap; // *** FLAGGED for deletion - HWND SDL_Window; + HWND windowHandle; MONITORINFOEX monitorInfo; RECT lastGoodRect; float _hdrMaxBrightness; @@ -261,6 +264,8 @@ extern int debug; */ - (id) init; +- (NSString*) getWindowCaption; +- (void) createWindowWithSize: (NSSize) size; - (void) initSplashScreen; - (void) endSplashScreen; - (void) autoShowMouse; @@ -318,12 +323,10 @@ extern int debug; - (void) display; - (BOOL) snapShot:(NSString *)filename; -#if SNAPSHOTS_PNG_FORMAT -- (BOOL) pngSaveSurface:(NSString *)fileName withSurface:(SDL_Surface *)surf; -#endif - (NSRect) bounds; -+ (NSMutableDictionary *) getNativeSize; +- (SDL_DisplayID) getDisplayId; +- (NSMutableDictionary *) getNativeSize; - (void) setFullScreenMode:(BOOL)fsm; - (BOOL) inFullScreenMode; @@ -341,6 +344,7 @@ extern int debug; - (int) findDisplayModeForWidth: (unsigned int) d_width Height:(unsigned int) d_height Refresh: (unsigned int)d_refresh; - (NSSize) currentScreenSize; +- (NSDictionary*) currentScreenMode; - (void) pollControls; @@ -372,9 +376,6 @@ extern int debug; - (void) setMouseInDeltaMode: (BOOL) inDelta; -- (void) setGammaValue: (float) value; -- (float) gammaValue; - - (void) setFov:(float)value fromFraction:(BOOL)fromFraction; - (float) fov:(BOOL)inFraction; diff --git a/src/SDL/MyOpenGLView.m b/src/SDL/MyOpenGLView.m index a65944e9b..f959399ae 100644 --- a/src/SDL/MyOpenGLView.m +++ b/src/SDL/MyOpenGLView.m @@ -28,7 +28,6 @@ #import "GameController.h" #import "Universe.h" #import "OOSDLJoystickManager.h" -#import "SDL_syswm.h" #import "OOSound.h" #import "NSFileManagerOOExtensions.h" // to find savedir #import "PlayerEntity.h" @@ -85,25 +84,50 @@ - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event keyID:(Uint16)key_id @implementation MyOpenGLView -+ (NSMutableDictionary *) getNativeSize +- (SDL_DisplayID) getDisplayId +{ + SDL_DisplayID displayId = 0; + if (window) + { + displayId = SDL_GetDisplayForWindow(window); + } + else + { + int displayCount; + SDL_DisplayID *displayIds = SDL_GetDisplays(&displayCount); + if (displayIds) + { + displayId = displayIds[0]; + } + else + { + OOLog(@"sdl.display_id", @"Could not get list of displays. Error was: %s", SDL_GetError()); + } + SDL_free(displayIds); + } + return displayId; +} + +- (NSMutableDictionary *) getNativeSize { NSMutableDictionary *mode=[[NSMutableDictionary alloc] init]; int nativeDisplayWidth = 1024; int nativeDisplayHeight = 768; #if OOLITE_LINUX - SDL_SysWMinfo dpyInfo; - SDL_VERSION(&dpyInfo.version); - if(SDL_GetWMInfo(&dpyInfo)) - { - nativeDisplayWidth = DisplayWidth(dpyInfo.info.x11.display, 0); - nativeDisplayHeight = DisplayHeight(dpyInfo.info.x11.display, 0); - OOLog(@"display.mode.list.native", @"X11 native resolution detected: %d x %d", nativeDisplayWidth, nativeDisplayHeight); + SDL_DisplayID displayId = [self getDisplayId]; + SDL_Rect boundsRect; + if (displayId && SDL_GetDisplayUsableBounds(displayId, &boundsRect)) + { + nativeDisplayWidth = boundsRect.w; + nativeDisplayHeight = boundsRect.h; + OOLog(@"display.mode.list.native", @"Native display resolution detected: %d x %d", nativeDisplayWidth, nativeDisplayHeight); } else { OOLog(@"display.mode.list.native.failed", @"%@", @"SDL_GetWMInfo failed, defaulting to 1024x768 for native size"); } + #elif OOLITE_WINDOWS nativeDisplayWidth = GetSystemMetrics(SM_CXSCREEN); nativeDisplayHeight = GetSystemMetrics(SM_CYSCREEN); @@ -118,73 +142,214 @@ + (NSMutableDictionary *) getNativeSize return [mode autorelease]; } +- (NSString*) getWindowCaption +{ +#ifdef BUILD_DATE + NSString *caption = [NSString stringWithFormat:@"Oolite v%@ - %s", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"], BUILD_DATE]; +#else + NSString *caption = [NSString stringWithFormat:@"Oolite v%@ - %s", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"], __DATE__]; +#endif + return [[caption retain] autorelease]; +} -- (void) createSurface +- (void) createWindowWithSize: (NSSize) size { - // Changing these flags can trigger texture bugs. - const int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL | SDL_RESIZABLE; + Uint32 colorkey; + SDL_Surface *icon=NULL; + NSString *imagesDir; + + NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; - if (showSplashScreen) + OOLog(@"display.initGL", @"Trying %d-bpcc, 24-bit depth buffer", bitsPerColorComponent); + if (bitsPerColorComponent > 8) { -#if OOLITE_WINDOWS - updateContext = NO; //don't update the (splash screen) window yet! + SDL_GL_SetAttribute(SDL_GL_FLOATBUFFERS, 1); + _hdrOutput = YES; + } + else + { + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, bitsPerColorComponent); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, bitsPerColorComponent); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, bitsPerColorComponent); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, bitsPerColorComponent); + _hdrOutput = NO; + } + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + /* 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 + * the worst case the entire scene must be rendered four + * times. For now it can be a hidden setting. If early testing + * doesn't give any problems (other than speed on low-end graphics + * cards) a game options entry might be useful. - CIM, 24 Aug 2013*/ - // Initialise the SDL surface. (need custom SDL.dll) - surface = SDL_SetVideoMode(firstScreen.width, firstScreen.height, 32, videoModeFlags); + if ([prefs oo_boolForKey:@"anti-aliasing" defaultValue:NO]) + { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); + } -#else - // Changing the flags can trigger texture bugs. - surface = SDL_SetVideoMode(8, 8, 32, videoModeFlags); -#endif - if (!surface) { - return; - } + NSString *windowCaption = [self getWindowCaption]; + int windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY; + window = SDL_CreateWindow([windowCaption UTF8String], size.width, size.height, windowFlags); + if (!window) + { + OOLog(@"display.initGL", @"%@", @"Trying 8-bpcc, 24-bit depth buffer"); + SDL_GL_SetAttribute(SDL_GL_FLOATBUFFERS, 0); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + window = SDL_CreateWindow([windowCaption UTF8String], size.width, size.height, windowFlags); + _hdrOutput = NO; } - else + + if (!window) { + OOLog(@"display.initGL", @"%@", @"Trying 5-bpcc, 16-bit depth buffer"); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + // and if it's this bad, forget even trying to multisample! + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + window = SDL_CreateWindow([windowCaption UTF8String], size.width, size.height, windowFlags); + } + + if (!window) + { + const char * errStr = SDL_GetError(); + OOLogERR(@"display.mode.error", @"Could not create window: %s", errStr); + exit(1); + } + glContext = SDL_GL_CreateContext(window); + if (!glContext) + { + OOLog(@"sdl.create_context", @"%@", @"Could not create OpenGL context"); + exit(1); + } + SDL_Surface *surface = SDL_GetWindowSurface(window); + if (!SDL_SetSurfaceColorspace(surface, SDL_COLORSPACE_SRGB_LINEAR)) + { + OOLogWARN(@"sdl.use_edr_surface", @"%@ %s", @"Failed to set SDR linear surface - falling back to SDR. Error was:", SDL_GetError()); + SDL_SetSurfaceColorspace(surface, SDL_COLORSPACE_SRGB); + } + #if OOLITE_WINDOWS - updateContext = YES; -#endif - surface = SDL_SetVideoMode(firstScreen.width, firstScreen.height, 32, videoModeFlags); - if (!surface) { - return; - } + //capture the window handle for later + SDL_PropertiesID windowPropertiesId = SDL_GetWindowProperties(window); + windowHandle = SDL_GetPointerProperty(windowPropertiesId, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + if (!windowHandle) + { + OOLog(@"sdl.window_handle", @"%@", @"Failed to retrieve window handle"); + exit(1); + } + + // This must be inited after windowHandle has been set - we need the main window handle in order to get monitor info + if (![self getCurrentMonitorInfo:&monitorInfo]) + { + OOLogWARN(@"display.initGL.monitorInfoWarning", @"Could not get current monitor information."); + } -#if OOLITE_LINUX - // blank the surface / go to fullscreen - [self initialiseGLWithSize: firstScreen]; + 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); + if (hUxTheme) + { + // hack alert! ordinal 135 is undocumented and could change in a future version of Windows + pfnSetPreferredAppMode SetPreferredAppMode = (pfnSetPreferredAppMode)GetProcAddress(hUxTheme, MAKEINTRESOURCEA(135)); + if (SetPreferredAppMode) SetPreferredAppMode(AllowDark); + FreeLibrary(hUxTheme); + } + [self refreshDarKOrLightMode]; #endif +#endif //OOLITE_WINDOWS + + imagesDir = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Images"]; + icon = SDL_LoadBMP([[imagesDir stringByAppendingPathComponent:@"WMicon.bmp"] UTF8String]); + + if (icon != NULL) + { + const SDL_PixelFormatDetails *pixelFormat = SDL_GetPixelFormatDetails(icon->format); + const SDL_Palette *palette = SDL_GetSurfacePalette(icon); + colorkey = SDL_MapRGB(pixelFormat, palette, 128, 0, 128); + SDL_SetSurfaceColorKey(icon, YES, colorkey); + SDL_SetWindowIcon(window, icon); } + SDL_DestroySurface(icon); - _gamma = 1.0f; - if (SDL_SetGamma(_gamma, _gamma, _gamma) < 0 ) + _colorSaturation = 1.0f; + +#if OOLITE_WINDOWS + _hdrMaxBrightness = [prefs oo_floatForKey:@"hdr-max-brightness" defaultValue:1000.0f]; + _hdrPaperWhiteBrightness = [prefs oo_floatForKey:@"hdr-paperwhite-brightness" defaultValue:200.0f]; + _hdrToneMapper = OOHDRToneMapperFromString([prefs oo_stringForKey:@"hdr-tone-mapper" defaultValue:@"OOHDR_TONEMAPPER_ACES_APPROX"]); +#endif + + _sdrToneMapper = OOSDRToneMapperFromString([prefs oo_stringForKey:@"sdr-tone-mapper" defaultValue:@"OOSDR_TONEMAPPER_ACES"]); + + SDL_SetWindowSurfaceVSync(window, vSyncPreference); + OOLog(@"display.initGL", @"V-Sync %@requested.", vSyncPreference ? @"" : @"not "); + + int testAttrib = -1; + OOLog(@"display.initGL", @"%@", @"Achieved color / depth buffer sizes (bits):"); + SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &testAttrib); + OOLog(@"display.initGL", @"Red: %d", testAttrib); + SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &testAttrib); + OOLog(@"display.initGL", @"Green: %d", testAttrib); + SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &testAttrib); + OOLog(@"display.initGL", @"Blue: %d", testAttrib); + SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &testAttrib); + OOLog(@"display.initGL", @"Alpha: %d", testAttrib); + SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &testAttrib); + OOLog(@"display.initGL", @"Depth Buffer: %d", testAttrib); + + SDL_GL_GetAttribute(SDL_GL_FLOATBUFFERS, &testAttrib); + OOLog(@"display.initGL", @"Pixel type is float : %d", testAttrib); + +#if OOLITE_WINDOWS + OOLog(@"display.initGL", @"Pixel format index: %d", GetPixelFormat(GetDC(windowHandle))); +#endif + + // Verify V-sync successfully set - report it if not + + int hasVsync; + if (vSyncPreference && (!SDL_GetWindowSurfaceVSync(window, &hasVsync) || !hasVsync)) { - char * errStr = SDL_GetError(); - OOLogWARN(@"gamma.set.failed", @"Could not set gamma: %s", errStr); - // CIM: this doesn't seem to necessarily be fatal. Gamma settings - // mostly work on mine despite this function failing. - // exit(1); + OOLogWARN(@"display.initGL", @"Could not enable V-Sync. Please check that your graphics driver supports the %@_swap_control extension.", + OOLITE_WINDOWS ? @"WGL_EXT" : @"[GLX_SGI/GLX_MESA]"); + } + else + { + OOLog(@"display.initGL", @"%@", @"V-Sync set"); } - SDL_EnableUNICODE(1); -} + int width, height; + SDL_GetWindowSizeInPixels(window, &width, &height); + bounds.size.width = width; + bounds.size.height = height; + + return; +} - (id) init { self = [super init]; - Uint32 colorkey; - SDL_Surface *icon=NULL; - NSString *imagesDir; NSString *cmdLineArgsStr = @"Startup command: "; // SDL splash screen settings NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; showSplashScreen = [prefs oo_boolForKey:@"splash-screen" defaultValue:YES]; - BOOL vSyncPreference = [prefs oo_boolForKey:@"v-sync" defaultValue:YES]; - int bitsPerColorComponent = [prefs oo_boolForKey:@"hdr" defaultValue:NO] ? 16 : 8; - int vSyncValue; + vSyncPreference = [prefs oo_boolForKey:@"v-sync" defaultValue:YES]; + bitsPerColorComponent = [prefs oo_boolForKey:@"hdr" defaultValue:NO] ? 16 : 8; NSArray *arguments = nil; NSEnumerator *argEnum = nil; @@ -222,20 +387,31 @@ - (id) init } OOLog(@"process.args", @"%@", cmdLineArgsStr); - + matrixManager = [[OOOpenGLMatrixManager alloc] init]; // TODO: This code up to and including stickHandler really ought // not to be in this class. OOLog(@"sdl.init", @"%@", @"initialising SDL"); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { OOLog(@"sdl.init.failed", @"Unable to init SDL: %s\n", SDL_GetError()); [self dealloc]; return nil; } - SDL_putenv ("SDL_VIDEO_WINDOW_POS=center"); + [self populateFullScreenModelist]; + SDL_SetEnvironmentVariable(SDL_GetEnvironment(), "SDL_VIDEO_WINDOW_POS", "center", YES); + + // Find what the full screen and windowed settings are. + fullScreen = NO; + currentSize = 0; + [self loadWindowSize]; + [self loadFullscreenSettings]; + + // Set up the drawing surface's dimensions. + firstScreen = (fullScreen) ? [self modeAsSize: currentSize] : currentWindowSize; + viewSize = firstScreen; // viewSize must be set prior to splash screen initialization [OOJoystickManager setStickHandlerClass:[OOSDLJoystickManager class]]; // end TODO @@ -243,197 +419,22 @@ - (id) init [OOSound setUp]; if (![OOSound isSoundOK]) OOLog(@"sound.init", @"%@", @"Sound system disabled."); - // Generate the window caption, containing the version number and the date the executable was compiled. - static char windowCaption[128]; - NSString *versionString = [NSString stringWithFormat:@"Oolite v%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]; - - strcpy (windowCaption, [versionString UTF8String]); - strcat(windowCaption, " - "); -#ifdef BUILD_DATE - strcat(windowCaption, BUILD_DATE); -#else - strcat(windowCaption, __DATE__); -#endif - SDL_WM_SetCaption (windowCaption, "Oolite"); // Set window title. - -#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]) - { - OOLogWARN(@"display.initGL.monitorInfoWarning", @"Could not get current monitor information."); - } - - 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); - if (hUxTheme) - { - // hack alert! ordinal 135 is undocumented and could change in a future version of Windows - pfnSetPreferredAppMode SetPreferredAppMode = (pfnSetPreferredAppMode)GetProcAddress(hUxTheme, MAKEINTRESOURCEA(135)); - if (SetPreferredAppMode) SetPreferredAppMode(AllowDark); - FreeLibrary(hUxTheme); - } - [self refreshDarKOrLightMode]; -#endif -#endif //OOLITE_WINDOWS - grabMouseStatus = NO; - imagesDir = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Images"]; - icon = SDL_LoadBMP([[imagesDir stringByAppendingPathComponent:@"WMicon.bmp"] UTF8String]); - - if (icon != NULL) - { - colorkey = SDL_MapRGB(icon->format, 128, 0, 128); - SDL_SetColorKey(icon, SDL_SRCCOLORKEY, colorkey); - SDL_WM_SetIcon(icon, NULL); - } - SDL_FreeSurface(icon); - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, bitsPerColorComponent); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, bitsPerColorComponent); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, bitsPerColorComponent); - 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]; - _hdrPaperWhiteBrightness = [prefs oo_floatForKey:@"hdr-paperwhite-brightness" defaultValue:200.0f]; - _hdrToneMapper = OOHDRToneMapperFromString([prefs oo_stringForKey:@"hdr-tone-mapper" defaultValue:@"OOHDR_TONEMAPPER_ACES_APPROX"]); - if (bitsPerColorComponent == 16) - { - // SDL.dll built specifically for Oolite required - SDL_GL_SetAttribute(SDL_GL_PIXEL_TYPE_FLOAT, 1); - _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 - * the worst case the entire scene must be rendered four - * times. For now it can be a hidden setting. If early testing - * doesn't give any problems (other than speed on low-end graphics - * cards) a game options entry might be useful. - CIM, 24 Aug 2013*/ - if ([prefs oo_boolForKey:@"anti-aliasing" defaultValue:NO]) - { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); - } - OOLog(@"display.mode.list", @"%@", @"CREATING MODE LIST"); - [self populateFullScreenModelist]; - currentSize = 0; - // Find what the full screen and windowed settings are. - fullScreen = NO; - [self loadFullscreenSettings]; - [self loadWindowSize]; - // 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) + ShowWindow(windowHandle,SW_SHOWMINIMIZED); + updateContext = !showSplashScreen; +#elif OOLITE_LINUX + if (!showSplashScreen) { - // Retry with hardcoded 8 bits per color component - OOLog(@"display.initGL", @"%@", @"Trying 8-bpcc, 32-bit depth buffer"); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - 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... - // Retry, allowing 16-bit contexts. - OOLog(@"display.initGL", @"%@", @"Trying 5-bpcc, 16-bit depth buffer"); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - // and if it's this bad, forget even trying to multisample! - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); - - [self createSurface]; - - if (surface == NULL) - { - char * errStr = SDL_GetError(); - OOLogERR(@"display.mode.error", @"Could not create display surface: %s", errStr); -#if OOLITE_WINDOWS - if (showSplashScreen) - { - [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"splash-screen"]; - [[NSUserDefaults standardUserDefaults] synchronize]; - OOLogWARN(@"display.mode.conflict",@"Possible incompatibility between the splash screen and video drivers detected."); - OOLogWARN(@"display.mode.conflict",@"Oolite will start without showing the splash screen from now on. Override with 'oolite.exe -splash'"); - } -#endif - exit(1); - } - } + // blank the surface / go to fullscreen + [self initialiseGLWithSize: firstScreen]; } - - int testAttrib = -1; - OOLog(@"display.initGL", @"%@", @"Achieved color / depth buffer sizes (bits):"); - SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &testAttrib); - OOLog(@"display.initGL", @"Red: %d", testAttrib); - SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &testAttrib); - OOLog(@"display.initGL", @"Green: %d", testAttrib); - SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &testAttrib); - OOLog(@"display.initGL", @"Blue: %d", testAttrib); - SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &testAttrib); - OOLog(@"display.initGL", @"Alpha: %d", testAttrib); - SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &testAttrib); - OOLog(@"display.initGL", @"Depth Buffer: %d", testAttrib); -#if OOLITE_WINDOWS - SDL_GL_GetAttribute(SDL_GL_PIXEL_TYPE_FLOAT, &testAttrib); - OOLog(@"display.initGL", @"Pixel type is float : %d", testAttrib); - - 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) - { - OOLogWARN(@"display.initGL", @"Could not enable V-Sync. Please check that your graphics driver supports the %@_swap_control extension.", - OOLITE_WINDOWS ? @"WGL_EXT" : @"[GLX_SGI/GLX_MESA]"); - } - - bounds.size.width = surface->w; - bounds.size.height = surface->h; [self autoShowMouse]; @@ -475,26 +476,14 @@ - (void) endSplashScreen wasFullScreen = !fullScreen; updateContext = YES; - ShowWindow(SDL_Window,SW_RESTORE); + ShowWindow(windowHandle,SW_RESTORE); [self initialiseGLWithSize: firstScreen]; #else if (!showSplashScreen) return; - int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL; - - videoModeFlags |= (fullScreen) ? SDL_FULLSCREEN : SDL_RESIZABLE; - surface = SDL_SetVideoMode(firstScreen.width, firstScreen.height, 32, videoModeFlags); - - if (!surface && fullScreen == YES) - { - [self setFullScreenMode: NO]; - videoModeFlags &= ~SDL_FULLSCREEN; - videoModeFlags |= SDL_RESIZABLE; - surface = SDL_SetVideoMode(currentWindowSize.width, currentWindowSize.height, 32, videoModeFlags); - } - - SDL_putenv ("SDL_VIDEO_WINDOW_POS=none"); //stop linux from auto centering on resize + SDL_SetWindowSize(window, firstScreen.width, firstScreen.height); + SDL_SetWindowFullscreen(window, fullScreen); /* MKW 2011.11.11 * Eat all SDL events to gobble up any resize events while the @@ -547,10 +536,14 @@ - (void) dealloc if (screenSizes) [screenSizes release]; - if (surface != 0) + if (window) + { + SDL_DestroyWindow(window); + } + + if (glContext) { - SDL_FreeSurface(surface); - surface = 0; + SDL_GL_DestroyContext(glContext); } if (keyMappings_normal) @@ -574,13 +567,13 @@ - (void) autoShowMouse //don't touch the 'please wait...' cursor. if (fullScreen) { - if (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) - SDL_ShowCursor(SDL_DISABLE); + if (SDL_CursorVisible()) + SDL_HideCursor(); } else { - if (SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE) - SDL_ShowCursor(SDL_ENABLE); + if (!SDL_CursorVisible()) + SDL_ShowCursor(); } } @@ -636,7 +629,7 @@ - (NSSize) viewSize - (NSSize) backingViewSize { - return viewSize; + return bounds.size; } @@ -717,7 +710,7 @@ - (void) toggleScreenMode { [self initialiseGLWithSize: currentWindowSize]; #if OOLITE_LINUX - SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_SetWindowMouseGrab(window, NO); #endif } // do screen resizing updates @@ -778,18 +771,22 @@ - (void) updateScreen - (void) drawRect:(NSRect)rect { + SDL_SetWindowSize(window, (int)NSWidth(rect), (int)NSHeight(rect)); [self updateScreenWithVideoMode:YES]; } - (void) updateScreenWithVideoMode:(BOOL) v_mode { - if ((viewSize.width != surface->w)||(viewSize.height != surface->h)) // resized + SDL_Surface* surface = SDL_GetWindowSurface(window); + int windowWidth, windowHeight; + SDL_GetWindowSize(window, &windowWidth, &windowHeight); + if ((viewSize.width != windowWidth)||(viewSize.height != windowHeight)) // resized { #if OOLITE_LINUX m_glContextInitialized = NO; //probably not needed #endif - viewSize.width = surface->w; - viewSize.height = surface->h; + viewSize.width = windowWidth; + viewSize.height = windowHeight; } if (m_glContextInitialized == NO) @@ -802,7 +799,10 @@ - (void) updateScreenWithVideoMode:(BOOL) v_mode // do all the drawing! // - if (UNIVERSE) [UNIVERSE drawUniverse]; + if (UNIVERSE) + { + [UNIVERSE drawUniverse]; + } else { // not set up yet, draw a black screen @@ -810,7 +810,7 @@ - (void) updateScreenWithVideoMode:(BOOL) v_mode glClear( GL_COLOR_BUFFER_BIT); } - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(window); } - (void) initSplashScreen @@ -827,7 +827,7 @@ - (void) initSplashScreen if (image == NULL) { - SDL_FreeSurface(image); + SDL_DestroySurface(image); OOLogWARN(@"sdl.gameStart", @"%@", @"image 'splash.bmp' not found!"); [self endSplashScreen]; return; @@ -838,38 +838,31 @@ - (void) initSplashScreen dest.w = image->w; dest.h = image->h; + [self createWindowWithSize: NSMakeSize(image->w, image->h)]; #if OOLITE_WINDOWS dest.x = (GetSystemMetrics(SM_CXSCREEN)- dest.w)/2; dest.y = (GetSystemMetrics(SM_CYSCREEN)-dest.h)/2; - SetWindowLong(SDL_Window,GWL_STYLE,GetWindowLong(SDL_Window,GWL_STYLE) & ~WS_CAPTION & ~WS_THICKFRAME); - ShowWindow(SDL_Window,SW_RESTORE); - MoveWindow(SDL_Window,dest.x,dest.y,dest.w,dest.h,TRUE); - - #else - - /* MKW 2011.11.11 - * According to Marc using the NOFRAME flag causes trouble under Ubuntu 8.04. - * - * The current Ubuntu LTS is 10.04, which doesn't seem to have that problem. - * 12.04 LTS is going to be released soon, also without apparent problems. - * Changed to SDL_NOFRAME, throwing caution to the wind - Kaks 2012.03.23 - * Took SDL_NOFRAME out, since it still causes strange problems here - cim 2012.04.09 - */ - surface = SDL_SetVideoMode(dest.w, dest.h, 32, SDL_HWSURFACE | SDL_OPENGL); - + SetWindowLong(windowHandle,GWL_STYLE,GetWindowLong(windowHandle,GWL_STYLE) & ~WS_CAPTION & ~WS_THICKFRAME); + ShowWindow(windowHandle,SW_RESTORE); + MoveWindow(windowHandle,dest.x,dest.y,dest.w,dest.h,TRUE); #endif OOSetOpenGLState(OPENGL_STATE_OVERLAY); + float pixelDensity = SDL_GetWindowPixelDensity(window); + if (pixelDensity == 0.0f) + { + pixelDensity = 1.0f; + } - glViewport( 0, 0, dest.w, dest.h); + glViewport( 0, 0, dest.w * pixelDensity, dest.h * pixelDensity); glEnable( GL_TEXTURE_2D ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); [matrixManager resetProjection]; - [matrixManager orthoLeft: 0.0f right: dest.w bottom: dest.h top: 0.0 near: -1.0 far: 1.0]; + [matrixManager orthoLeft: 0.0f right: 1.0f bottom: 1.0f top: 0.0f near: -1.0f far: 1.0f]; [matrixManager syncProjection]; [matrixManager resetModelView]; @@ -880,22 +873,23 @@ - (void) initSplashScreen GLint nOfColors; // get the number of channels in the SDL image - nOfColors = image->format->BytesPerPixel; + const SDL_PixelFormatDetails *pixelFormat = SDL_GetPixelFormatDetails(image->format); + nOfColors = pixelFormat->bytes_per_pixel; if (nOfColors == 4) // contains an alpha channel { - if (image->format->Rmask == 0x000000ff) + if (pixelFormat->Rmask == 0x000000ff) texture_format = GL_RGBA; else texture_format = GL_BGRA; } else if (nOfColors == 3) // no alpha channel { - if (image->format->Rmask == 0x000000ff) + if (pixelFormat->Rmask == 0x000000ff) texture_format = GL_RGB; else texture_format = GL_BGR; } else { - SDL_FreeSurface(image); + SDL_DestroySurface(image); OOLog(@"Sdl.GameStart", @"%@", @"----- Encoding error within image 'splash.bmp'"); [self endSplashScreen]; return; @@ -918,25 +912,29 @@ - (void) initSplashScreen glTexCoord2i( 0, 0 ); glVertex2i( 0, 0 ); glTexCoord2i( 1, 0 ); - glVertex2i( dest.w, 0 ); + glVertex2i( 1, 0 ); glTexCoord2i( 1, 1 ); - glVertex2i( dest.w, dest.h ); + glVertex2i( 1, 1 ); glTexCoord2i( 0, 1 ); - glVertex2i( 0, dest.h ); + glVertex2i( 0, 1 ); glEnd(); + glFinish(); - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(window); [matrixManager resetModelView]; [matrixManager syncModelView]; if ( image ) { - SDL_FreeSurface( image ); + SDL_DestroySurface( image ); } glDeleteTextures(1, &texture); glDisable( GL_TEXTURE_2D ); OOVerifyOpenGLState(); + + SDL_DestroySurface(image); + return; } @@ -949,7 +947,7 @@ - (MONITORINFOEX) currentMonitorInfo - (BOOL) getCurrentMonitorInfo:(MONITORINFOEX *)mInfo { - HMONITOR hMon = MonitorFromWindow(SDL_Window, MONITOR_DEFAULTTOPRIMARY); + HMONITOR hMon = MonitorFromWindow(windowHandle, MONITOR_DEFAULTTOPRIMARY); ZeroMemory(mInfo, sizeof(MONITORINFOEX)); mInfo->cbSize = sizeof(MONITORINFOEX); if (GetMonitorInfo (hMon, (LPMONITORINFO)mInfo)) @@ -977,7 +975,7 @@ - (void) grabMouseInsideGameWindow:(BOOL) value if(value) { RECT gameWindowRect; - GetWindowRect(SDL_Window, &gameWindowRect); + GetWindowRect(windowHandle, &gameWindowRect); ClipCursor(&gameWindowRect); } else @@ -1018,10 +1016,11 @@ - (void) stringToClipboard:(NSString *)stringToCopy - (void) resetSDLKeyModifiers { + /* kanthoney - looks like SDL3 won't allow us to change the keyboard state - try without to see if it's needed // this is used when we regain focus to ensure that all // modifier keys are reset to their correct status - SDLMod modState = SDL_GetModState(); - Uint8 *keyState = SDL_GetKeyState(NULL); + SDL_Keymod modState = SDL_GetModState(); + const BOOL *keyState = SDL_GetKeyboardState(NULL); BYTE keyboardStatus[256]; #define OO_RESET_SDLKEY_MODIFIER(vkCode, kModCode, sdlkCode) do {\ if (keyboardStatus[vkCode] & 0x0080) \ @@ -1071,12 +1070,13 @@ - (void) resetSDLKeyModifiers } SDL_SetModState(modState); + */ } - (void) setWindowBorderless:(BOOL)borderless { - LONG currentWindowStyle = GetWindowLong(SDL_Window, GWL_STYLE); + LONG currentWindowStyle = GetWindowLong(windowHandle, GWL_STYLE); // window already has the desired style? if ((!borderless && (currentWindowStyle & WS_CAPTION)) || @@ -1084,22 +1084,22 @@ - (void) setWindowBorderless:(BOOL)borderless if (borderless) { - SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle & ~WS_CAPTION & ~WS_THICKFRAME); + SetWindowLong(windowHandle, GWL_STYLE, currentWindowStyle & ~WS_CAPTION & ~WS_THICKFRAME); } else { - SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle | + SetWindowLong(windowHandle, GWL_STYLE, currentWindowStyle | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX ); [self refreshDarKOrLightMode]; } - SetWindowPos(SDL_Window, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); + SetWindowPos(windowHandle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); } - (void) refreshDarKOrLightMode { int shouldSetDarkMode = [self isDarkModeOn]; - DwmSetWindowAttribute (SDL_Window, DWMWA_USE_IMMERSIVE_DARK_MODE, &shouldSetDarkMode, sizeof(shouldSetDarkMode)); + DwmSetWindowAttribute (windowHandle, DWMWA_USE_IMMERSIVE_DARK_MODE, &shouldSetDarkMode, sizeof(shouldSetDarkMode)); } @@ -1431,12 +1431,13 @@ - (void) initialiseGLWithSize:(NSSize) v_size - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode { -#if OOLITE_LINUX - NSSize oldViewSize = viewSize; -#endif + if (!window) + { + [self createWindowWithSize: v_size]; + } 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 + SDL_GL_SwapWindow(window); // clear the buffer before resize #if OOLITE_WINDOWS if (!updateContext) return; @@ -1448,7 +1449,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode WINDOWPLACEMENT windowPlacement; windowPlacement.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(SDL_Window, &windowPlacement); + GetWindowPlacement(windowHandle, &windowPlacement); static BOOL lastWindowPlacementMaximized = NO; if (fullScreen && (windowPlacement.showCmd == SW_SHOWMAXIMIZED)) @@ -1495,12 +1496,12 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode CopyRect(&lastGoodRect, &windowPlacement.rcNormalPosition); // if maximized, switch to normal placement before going full screen windowPlacement.showCmd = SW_SHOWNORMAL; - SetWindowPlacement(SDL_Window, &windowPlacement); + SetWindowPlacement(windowHandle, &windowPlacement); } - else GetWindowRect(SDL_Window, &lastGoodRect); + else GetWindowRect(windowHandle, &lastGoodRect); // ok, can go fullscreen now - SetForegroundWindow(SDL_Window); + SetForegroundWindow(windowHandle); if (changingResolution) { if (ChangeDisplaySettingsEx(monitorInfo.szDevice, &settings, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) @@ -1513,7 +1514,7 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode && settings.dmPelsHeight == [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayHeight] intValue]; } - MoveWindow(SDL_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, (int)viewSize.width, (int)viewSize.height, TRUE); + MoveWindow(windowHandle, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, (int)viewSize.width, (int)viewSize.height, TRUE); if(!wasFullScreen) { [self setWindowBorderless:YES]; @@ -1542,10 +1543,10 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode [self getCurrentMonitorInfo: &monitorInfo]; if (lastWindowPlacementMaximized) CopyRect(&windowPlacement.rcNormalPosition, &lastGoodRect); - SetWindowPlacement(SDL_Window, &windowPlacement); + SetWindowPlacement(windowHandle, &windowPlacement); if (!lastWindowPlacementMaximized) { - MoveWindow(SDL_Window, (monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left - (int)viewSize.width)/2 + + MoveWindow(windowHandle, (monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left - (int)viewSize.width)/2 + monitorInfo.rcMonitor.left, (monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top - (int)viewSize.height)/2 + monitorInfo.rcMonitor.top, @@ -1555,13 +1556,13 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode [self setWindowBorderless:NO]; lastWindowPlacementMaximized = NO; - ShowWindow(SDL_Window,SW_SHOW); + ShowWindow(windowHandle,SW_SHOW); } // stop saveWindowSize from reacting to caption & frame if necessary saveSize = !wasFullScreen; - GetClientRect(SDL_Window, &wDC); + GetClientRect(windowHandle, &wDC); if (!fullScreen && (bounds.size.width != wDC.right - wDC.left || bounds.size.height != wDC.bottom - wDC.top)) @@ -1574,13 +1575,13 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode //after the splash screen has ended { RECT desiredClientRect; - GetWindowRect(SDL_Window, &desiredClientRect); + GetWindowRect(windowHandle, &desiredClientRect); AdjustWindowRect(&desiredClientRect, WS_CAPTION | WS_THICKFRAME, FALSE); - SetWindowPos(SDL_Window, NULL, desiredClientRect.left, desiredClientRect.top, + SetWindowPos(windowHandle, NULL, desiredClientRect.left, desiredClientRect.top, desiredClientRect.right - desiredClientRect.left, desiredClientRect.bottom - desiredClientRect.top, 0); } - GetClientRect(SDL_Window, &wDC); + GetClientRect(windowHandle, &wDC); viewSize.width = wDC.right - wDC.left; viewSize.height = wDC.bottom - wDC.top; } @@ -1598,36 +1599,10 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode #else //OOLITE_LINUX - int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL; - - if (v_mode == NO) - videoModeFlags |= SDL_NOFRAME; - if (fullScreen == YES) - { - videoModeFlags |= SDL_FULLSCREEN; - } - else - { - videoModeFlags |= SDL_RESIZABLE; - } - surface = SDL_SetVideoMode((int)viewSize.width, (int)viewSize.height, 32, videoModeFlags); - - if (!surface && fullScreen == YES) - { - [self setFullScreenMode: NO]; - viewSize = oldViewSize; - videoModeFlags &= ~SDL_FULLSCREEN; - videoModeFlags |= SDL_RESIZABLE; - surface = SDL_SetVideoMode((int)viewSize.width, (int)viewSize.height, 32, videoModeFlags); - } - - if (!surface) - { - // we should always have a valid surface, but in case we don't - OOLogERR(@"display.mode.error",@"Unable to change display mode: %s",SDL_GetError()); - exit(1); - } - + SDL_SetWindowBordered(window, v_mode); + SDL_SetWindowFullscreen(window, fullScreen); + SDL_SetWindowSize(window, viewSize.width, viewSize.height); + SDL_Surface *surface = SDL_GetWindowSurface(window); bounds.size.width = surface->w; bounds.size.height = surface->h; @@ -1644,12 +1619,13 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode y_offset = 320.0 * bounds.size.height/bounds.size.width; } - if (surface != 0) SDL_FreeSurface(surface); - [self autoShowMouse]; - [[self gameController] setUpBasicOpenGLStateWithSize:viewSize]; - SDL_GL_SwapBuffers(); + int pixelWidth, pixelHeight; + SDL_GetWindowSizeInPixels(window, &pixelWidth, &pixelHeight); + NSSize pixelSize = NSMakeSize(pixelWidth, pixelHeight); + [[self gameController] setUpBasicOpenGLStateWithSize:pixelSize]; + SDL_GL_SwapWindow(window); squareX = 0.0f; m_glContextInitialized = YES; @@ -1721,9 +1697,10 @@ - (BOOL) snapShot:(NSString *)filename imageNo = tmpImageNo; } + SDL_Surface *surface = SDL_GetWindowSurface(window); OOLog(@"screenshot", @"Saving screen shot \"%@\" (%u x %u pixels).", pathToPic, surface->w, surface->h); - int pitch = surface->w * 3; + int pitch = surface->pitch; unsigned char *pixls = malloc(pitch * surface->h); int y; int off; @@ -1732,24 +1709,24 @@ - (BOOL) snapShot:(NSString *)filename else glPixelStorei(GL_PACK_ALIGNMENT,4); for (y=surface->h-1, off=0; y>=0; y--, off+=pitch) { - glReadPixels(0, y, surface->w, 1, GL_RGB, GL_UNSIGNED_BYTE, pixls + off); + glReadPixels(0, y, surface->w, 1, GL_BGRA, GL_UNSIGNED_BYTE, pixls + off); } - tmpSurface=SDL_CreateRGBSurfaceFrom(pixls,surface->w,surface->h,24,surface->w*3,0xFF,0xFF00,0xFF0000,0x0); + tmpSurface = SDL_CreateSurfaceFrom(surface->w, surface->h, surface->format, pixls, surface->pitch); #if SNAPSHOTS_PNG_FORMAT - if(![self pngSaveSurface:pathToPic withSurface:tmpSurface]) + if(!SDL_SavePNG(tmpSurface, [pathToPic UTF8String])) { OOLog(@"screenshotPNG", @"Failed to save %@", pathToPic); snapShotOK = NO; } #else - if (SDL_SaveBMP(tmpSurface, [pathToPic UTF8String]) == -1) + if (!SDL_SaveBMP(tmpSurface, [pathToPic UTF8String])) { OOLog(@"screenshotBMP", @"Failed to save %@", pathToPic); snapShotOK = NO; } #endif - SDL_FreeSurface(tmpSurface); + SDL_DestroySurface(tmpSurface); free(pixls); // if outputting HDR signal, save also either an .exr or a Radiance .hdr snapshot @@ -1791,77 +1768,13 @@ - (BOOL) snapShot:(NSString *)filename #if SNAPSHOTS_PNG_FORMAT -// This method is heavily based on 'Mars, Land of No Mercy' SDL examples, by Angelo "Encelo" Theodorou, see http://encelo.netsons.org/programming/sdl - (BOOL) pngSaveSurface:(NSString *)fileName withSurface:(SDL_Surface *)surf { - FILE *fp; - png_structp pngPtr; - png_infop infoPtr; - int i, colorType; - png_bytep *rowPointers; - - fp = fopen([fileName UTF8String], "wb"); - if (fp == NULL) + if (!SDL_SavePNG(surf, [fileName UTF8String])) { OOLog(@"pngSaveSurface.fileCreate.failed", @"Failed to create output screenshot file %@", fileName); return NO; } - - // initialize png structures (no callbacks) - pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (pngPtr == NULL) - { - return NO; - } - - infoPtr = png_create_info_struct(pngPtr); - if (infoPtr == NULL) { - png_destroy_write_struct(&pngPtr, (png_infopp)NULL); - OOLog(@"pngSaveSurface.info_struct.failed", @"%@", @"png_create_info_struct error"); - exit(-1); - } - - if (setjmp(png_jmpbuf(pngPtr))) - { - png_destroy_write_struct(&pngPtr, &infoPtr); - fclose(fp); - exit(-1); - } - - png_init_io(pngPtr, fp); - - colorType = PNG_COLOR_MASK_COLOR; /* grayscale not supported */ - if (surf->format->palette) - { - colorType |= PNG_COLOR_MASK_PALETTE; - } - else if (surf->format->Amask) - { - colorType |= PNG_COLOR_MASK_ALPHA; - } - - 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); - - // write the image - png_write_info(pngPtr, infoPtr); - png_set_packing(pngPtr); - - rowPointers = (png_bytep*) malloc(sizeof(png_bytep)*surf->h); - for (i = 0; i < surf->h; i++) - { - rowPointers[i] = (png_bytep)(Uint8 *)surf->pixels + i*surf->pitch; - } - png_write_image(pngPtr, rowPointers); - png_write_end(pngPtr, infoPtr); - - free(rowPointers); - png_destroy_write_struct(&pngPtr, &infoPtr); - fclose(fp); - return YES; } #endif // SNAPSHOTS_PNG_FORMAT @@ -1990,7 +1903,7 @@ - (void) resetMouse [self setVirtualJoystick:0.0 :0.0]; if ([[PlayerEntity sharedPlayer] isMouseControlOn]) { - SDL_WarpMouse([self viewSize].width / 2, [self viewSize].height / 2); + SDL_WarpMouseInWindow(window, viewSize.width / 2, viewSize.height / 2); mouseWarped = YES; } } @@ -2064,7 +1977,7 @@ - (BOOL) isCapsLockOn to existing controls, depending on the state of Caps Lock. - Nikos 20160304 */ - return (SDL_GetModState() & KMOD_CAPS) == KMOD_CAPS; + return (SDL_GetModState() & SDL_KMOD_CAPS) == SDL_KMOD_CAPS; } @@ -2126,13 +2039,17 @@ - (void)pollControls SDL_KeyboardEvent *kbd_event; SDL_MouseButtonEvent *mbtn_event; SDL_MouseMotionEvent *mmove_event; - int mxdelta, mydelta; + SDL_MouseWheelEvent *mw_event; + float mxdelta, mydelta; float mouseVirtualStickSensitivityX = viewSize.width * _mouseVirtualStickSensitivityFactor; float mouseVirtualStickSensitivityY = viewSize.height * _mouseVirtualStickSensitivityFactor; NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate]; - Uint16 key_id; - int scan_code; -#if OOLITE_LINUX + Uint16 key_id; + SDL_Scancode scan_code; + float inDelta; +#if OOLITE_WINDOWS + DWORD dwLastError = 0; +#elif OOLITE_LINUX NSSize newSize; bool resize_pending = false; #endif @@ -2140,21 +2057,19 @@ - (void)pollControls while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_JOYAXISMOTION: - case SDL_JOYBUTTONUP: - case SDL_JOYBUTTONDOWN: - case SDL_JOYHATMOTION: + case SDL_EVENT_JOYSTICK_AXIS_MOTION: + case SDL_EVENT_JOYSTICK_BUTTON_UP: + case SDL_EVENT_JOYSTICK_BUTTON_DOWN: + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + case SDL_EVENT_GAMEPAD_BUTTON_UP: + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: + case SDL_EVENT_JOYSTICK_HAT_MOTION: [(OOSDLJoystickManager*)[OOJoystickManager sharedStickHandler] handleSDLEvent: &event]; break; - case SDL_MOUSEBUTTONDOWN: + case SDL_EVENT_MOUSE_BUTTON_DOWN: mbtn_event = (SDL_MouseButtonEvent*)&event; -#if OOLITE_LINUX - short inDelta = 0; -#else - // specially built SDL.dll is required for this - short inDelta = mbtn_event->wheelDelta; -#endif + switch(mbtn_event->button) { case SDL_BUTTON_LEFT: @@ -2171,35 +2086,11 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call [self resetMouse]; // Will set mouseWarped to YES break; // mousewheel stuff -#if OOLITE_LINUX - case SDL_BUTTON_WHEELUP: - inDelta = OOMOUSEWHEEL_DELTA; - // allow fallthrough - case SDL_BUTTON_WHEELDOWN: - if (inDelta == 0) inDelta = -OOMOUSEWHEEL_DELTA; -#else - case SDL_BUTTON_WHEELUP: - case SDL_BUTTON_WHEELDOWN: -#endif - if (inDelta > 0) - { - if (_mouseWheelDelta >= 0.0f) - _mouseWheelDelta += inDelta; - else - _mouseWheelDelta = 0.0f; - } - else if (inDelta < 0) - { - if (_mouseWheelDelta <= 0.0f) - _mouseWheelDelta += inDelta; - else - _mouseWheelDelta = 0.0f; - } - break; + } break; - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_UP: mbtn_event = (SDL_MouseButtonEvent*)&event; NSTimeInterval timeBetweenClicks = timeNow - timeIntervalAtLastClick; timeIntervalAtLastClick += timeBetweenClicks; @@ -2212,20 +2103,37 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } keys[gvMouseLeftButton] = NO; } + break; + + case SDL_EVENT_MOUSE_WHEEL: + mw_event = (SDL_MouseWheelEvent*)&event; + + inDelta = mw_event->y; + if (inDelta > 0) + { + if (_mouseWheelDelta >= 0.0f) + _mouseWheelDelta += inDelta; + else + _mouseWheelDelta = 0.0f; + } + else if (inDelta < 0) + { + if (_mouseWheelDelta <= 0.0f) + _mouseWheelDelta += inDelta; + else + _mouseWheelDelta = 0.0f; + } /* 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 kind of special, as in, it is sent at the same time as its corresponding mousewheel button down one - Nikos 20140809 */ - if (mbtn_event->button == SDL_BUTTON_WHEELUP || mbtn_event->button == SDL_BUTTON_WHEELDOWN) - { - NSTimeInterval timeBetweenMouseWheels = timeNow - timeSinceLastMouseWheel; - timeSinceLastMouseWheel += timeBetweenMouseWheels; - } + NSTimeInterval timeBetweenMouseWheels = timeNow - timeSinceLastMouseWheel; + timeSinceLastMouseWheel += timeBetweenMouseWheels; break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: { // Delta mode is set when the game is in 'flight' mode. // In this mode, the mouse movement delta is used rather @@ -2271,8 +2179,8 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call // mouse pointer. mmove_event = (SDL_MouseMotionEvent*)&event; - int w=bounds.size.width; - int h=bounds.size.height; + int w=viewSize.width; + int h=viewSize.height; if (!mouseWarped) // standard event, handle it { @@ -2299,47 +2207,42 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } break; } - case SDL_KEYDOWN: + case SDL_EVENT_KEY_DOWN: kbd_event = (SDL_KeyboardEvent*)&event; - key_id = (Uint16)kbd_event->keysym.unicode; - scan_code = kbd_event->keysym.scancode; + key_id = SDL_GetKeyFromScancode(kbd_event->scancode, kbd_event->mod, YES); + scan_code = kbd_event->scancode; //char *keychar = SDL_GetKeyName(kbd_event->keysym.sym); // deal with modifiers first BOOL modifier_pressed = NO; BOOL special_key = NO; + shift = (kbd_event->mod & SDL_KMOD_SHIFT) != 0; + ctrl = (kbd_event->mod & SDL_KMOD_CTRL) != 0; + opt = (kbd_event->mod & SDL_KMOD_ALT) != 0; + // translate scancode to unicode equiv - switch (kbd_event->keysym.sym) + switch (kbd_event->key) { case SDLK_LSHIFT: case SDLK_RSHIFT: - shift = YES; - modifier_pressed = YES; - break; - case SDLK_LCTRL: case SDLK_RCTRL: - ctrl = YES; - modifier_pressed = YES; - break; - case SDLK_LALT: case SDLK_RALT: - opt = YES; modifier_pressed = YES; break; - case SDLK_KP0: key_id = (!allowingStringInput ? gvNumberPadKey0 : gvNumberKey0); special_key = YES; break; - case SDLK_KP1: key_id = (!allowingStringInput ? gvNumberPadKey1 : gvNumberKey1); special_key = YES; break; - case SDLK_KP2: key_id = (!allowingStringInput ? gvNumberPadKey2 : gvNumberKey2); special_key = YES; break; - case SDLK_KP3: key_id = (!allowingStringInput ? gvNumberPadKey3 : gvNumberKey3); special_key = YES; break; - case SDLK_KP4: key_id = (!allowingStringInput ? gvNumberPadKey4 : gvNumberKey4); special_key = YES; break; - case SDLK_KP5: key_id = (!allowingStringInput ? gvNumberPadKey5 : gvNumberKey5); special_key = YES; break; - case SDLK_KP6: key_id = (!allowingStringInput ? gvNumberPadKey6 : gvNumberKey6); special_key = YES; break; - case SDLK_KP7: key_id = (!allowingStringInput ? gvNumberPadKey7 : gvNumberKey7); special_key = YES; break; - case SDLK_KP8: key_id = (!allowingStringInput ? gvNumberPadKey8 : gvNumberKey8); special_key = YES; break; - case SDLK_KP9: key_id = (!allowingStringInput ? gvNumberPadKey9 : gvNumberKey9); special_key = YES; break; + case SDLK_KP_0: key_id = (!allowingStringInput ? gvNumberPadKey0 : gvNumberKey0); special_key = YES; break; + case SDLK_KP_1: key_id = (!allowingStringInput ? gvNumberPadKey1 : gvNumberKey1); special_key = YES; break; + case SDLK_KP_2: key_id = (!allowingStringInput ? gvNumberPadKey2 : gvNumberKey2); special_key = YES; break; + case SDLK_KP_3: key_id = (!allowingStringInput ? gvNumberPadKey3 : gvNumberKey3); special_key = YES; break; + case SDLK_KP_4: key_id = (!allowingStringInput ? gvNumberPadKey4 : gvNumberKey4); special_key = YES; break; + case SDLK_KP_5: key_id = (!allowingStringInput ? gvNumberPadKey5 : gvNumberKey5); special_key = YES; break; + case SDLK_KP_6: key_id = (!allowingStringInput ? gvNumberPadKey6 : gvNumberKey6); special_key = YES; break; + case SDLK_KP_7: key_id = (!allowingStringInput ? gvNumberPadKey7 : gvNumberKey7); special_key = YES; break; + case SDLK_KP_8: key_id = (!allowingStringInput ? gvNumberPadKey8 : gvNumberKey8); special_key = YES; break; + case SDLK_KP_9: key_id = (!allowingStringInput ? gvNumberPadKey9 : gvNumberKey9); special_key = YES; break; case SDLK_KP_PERIOD: key_id = (!allowingStringInput ? gvNumberPadKeyPeriod : 46); special_key = YES; break; case SDLK_KP_DIVIDE: key_id = (!allowingStringInput ? gvNumberPadKeyDivide : 47); special_key = YES; break; case SDLK_KP_MULTIPLY: key_id = (!allowingStringInput ? gvNumberPadKeyMultiply : 42); special_key = YES; break; @@ -2382,7 +2285,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call case SDLK_ESCAPE: if (shift) { - SDL_FreeSurface(surface); + SDL_DestroyWindow(window); [gameController exitAppWithContext:@"Shift-escape pressed"]; } else @@ -2396,9 +2299,19 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call ; } + if (!special_key) + { + if (shift && !ctrl) + { + NSString *keyShifted = [keyMappings_shifted objectForKey:[NSString stringWithFormat:@"%d", scan_code]]; + if (keyShifted) key_id = [keyShifted integerValue]; + + } + } // 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) // { // ctrl changes alpha characters to control codes (1-26) @@ -2411,11 +2324,15 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } else { - key_id = 0; // reset the value here to force a lookup from the keymappings data + // SDL3 - the key_id should contain the correct unicode value, so we shouldn't need to run the key mapping + // - kanthoney + //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 + // SDL3 - as per comment above, we shouldn't need to run keymappings using SDL3, so commenting this out to confirm +#if 0 if (key_id == 0) { // get unicode value for keycode from keymappings files @@ -2431,16 +2348,16 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call if (keyShifted) key_id = [keyShifted integerValue]; } } - +#endif // if we've got the unicode value, we can store it in our array now if (key_id > 0) scancode2Unicode[scan_code] = key_id; - if(allowingStringInput) + if(allowingStringInput && !modifier_pressed) { [self handleStringInput:kbd_event keyID:key_id]; } - 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, character = %c, shift = %d, ctrl = %d, alt = %d", scan_code, key_id, 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]) @@ -2453,16 +2370,20 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } break; - case SDL_KEYUP: + case SDL_EVENT_KEY_UP: suppressKeys = NO; // DJS kbd_event = (SDL_KeyboardEvent*)&event; - scan_code = kbd_event->keysym.scancode; + scan_code = kbd_event->scancode; + + shift = kbd_event->mod & SDL_KMOD_SHIFT; + ctrl = kbd_event->mod & SDL_KMOD_CTRL; + opt = kbd_event->mod & SDL_KMOD_ALT; // all the work should have been down on the keydown event, so all we need to do is get the unicode value from the array key_id = scancode2Unicode[scan_code]; // deal with modifiers first - switch (kbd_event->keysym.sym) + switch (kbd_event->key) { case SDLK_LSHIFT: case SDLK_RSHIFT: @@ -2481,22 +2402,22 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call default: ; } - 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, unicode = %i, character = %c, shift = %d, ctrl = %d, alt = %d", scan_code, key_id, 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->key) { - case SDLK_KP0: key_id = (!allowingStringInput ? gvNumberPadKey0 : gvNumberKey0); break; - case SDLK_KP1: key_id = (!allowingStringInput ? gvNumberPadKey1 : gvNumberKey1); break; - case SDLK_KP2: key_id = (!allowingStringInput ? gvNumberPadKey2 : gvNumberKey2); break; - case SDLK_KP3: key_id = (!allowingStringInput ? gvNumberPadKey3 : gvNumberKey3); break; - case SDLK_KP4: key_id = (!allowingStringInput ? gvNumberPadKey4 : gvNumberKey4); break; - case SDLK_KP5: key_id = (!allowingStringInput ? gvNumberPadKey5 : gvNumberKey5); break; - case SDLK_KP6: key_id = (!allowingStringInput ? gvNumberPadKey6 : gvNumberKey6); break; - case SDLK_KP7: key_id = (!allowingStringInput ? gvNumberPadKey7 : gvNumberKey7); break; - case SDLK_KP8: key_id = (!allowingStringInput ? gvNumberPadKey8 : gvNumberKey8); break; - case SDLK_KP9: key_id = (!allowingStringInput ? gvNumberPadKey9 : gvNumberKey9); break; + case SDLK_KP_0: key_id = (!allowingStringInput ? gvNumberPadKey0 : gvNumberKey0); break; + case SDLK_KP_1: key_id = (!allowingStringInput ? gvNumberPadKey1 : gvNumberKey1); break; + case SDLK_KP_2: key_id = (!allowingStringInput ? gvNumberPadKey2 : gvNumberKey2); break; + case SDLK_KP_3: key_id = (!allowingStringInput ? gvNumberPadKey3 : gvNumberKey3); break; + case SDLK_KP_4: key_id = (!allowingStringInput ? gvNumberPadKey4 : gvNumberKey4); break; + case SDLK_KP_5: key_id = (!allowingStringInput ? gvNumberPadKey5 : gvNumberKey5); break; + case SDLK_KP_6: key_id = (!allowingStringInput ? gvNumberPadKey6 : gvNumberKey6); break; + case SDLK_KP_7: key_id = (!allowingStringInput ? gvNumberPadKey7 : gvNumberKey7); break; + case SDLK_KP_8: key_id = (!allowingStringInput ? gvNumberPadKey8 : gvNumberKey8); break; + case SDLK_KP_9: key_id = (!allowingStringInput ? gvNumberPadKey9 : gvNumberKey9); break; case SDLK_KP_PERIOD: key_id = (!allowingStringInput ? gvNumberPadKeyPeriod : 46); break; case SDLK_KP_DIVIDE: key_id = (!allowingStringInput ? gvNumberPadKeyDivide : 47); break; case SDLK_KP_MULTIPLY: key_id = (!allowingStringInput ? gvNumberPadKeyMultiply : 42); break; @@ -2548,11 +2469,11 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } break; - case SDL_VIDEORESIZE: + case SDL_EVENT_WINDOW_RESIZED: { - SDL_ResizeEvent *rsevt=(SDL_ResizeEvent *)&event; + SDL_WindowEvent *rsevt=(SDL_WindowEvent *)&event; #if OOLITE_WINDOWS - NSSize newSize=NSMakeSize(rsevt->w, rsevt->h); + NSSize newSize=NSMakeSize(rsevt->data1, rsevt->data2); if (!fullScreen && updateContext) { if (saveSize == NO) @@ -2568,7 +2489,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } } #else - newSize=NSMakeSize(rsevt->w, rsevt->h); + newSize=NSMakeSize(rsevt->data1, rsevt->data2); resize_pending = true; #endif // certain gui screens will require an immediate redraw after @@ -2579,152 +2500,120 @@ 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 - // style before minimuzing and reset it when we return, otherwise - // there might be issues with the game window remaining stuck on - // 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) + case SDL_EVENT_WINDOW_MINIMIZED: + { + if (fullScreen) { - [self setWindowBorderless:event.active.gain]; + [self setWindowBorderless: NO]; } 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) - // Nikos - 20140920 - case SDL_SYSWMEVENT: + + case SDL_EVENT_WINDOW_RESTORED: { - DWORD dwLastError = 0; - switch (event.syswm.msg->msg) + if (fullScreen) { - case WM_MOVE: - /* if we are in fullscreen mode we normally don't worry about having the window moved. - However, when using multiple monitors, one can use hotkey combinations to make the - window "jump" from one monitor to the next. We don't want this to happen, so if we - detect that our (fullscreen) window has moved, we immediately bring it back to its - original position. Nikos - 20140922 - */ - 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. - 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. - */ - 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) - { - BOOL fullScreenMaximized = NO; - if (wp.showCmd == SW_SHOWMAXIMIZED && !fullScreenMaximized) - { - fullScreenMaximized = YES; - 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); - wp.showCmd = SW_SHOWMAXIMIZED; - CopyRect(&wp.rcNormalPosition, &lastGoodRect); - SetWindowPlacement(SDL_Window, &wp); - } - } - else if (wp.showCmd == SW_SHOWMAXIMIZED) - { - CopyRect(&wp.rcNormalPosition, &lastGoodRect); - SetWindowPlacement(SDL_Window, &wp); - } - } - // it is important that this gets done after we've dealt with possible fullscreen movements, - // because -doGuiScreenResizeUpdates does itself an update on current monitor - if ([PlayerEntity sharedPlayer]) + [self setWindowBorderless: YES]; + } + break; + } + + case SDL_EVENT_WINDOW_MOVED: + { + 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. + // 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. + + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement(windowHandle, &wp); + + GetWindowRect(windowHandle, &rDC); + if (rDC.left != monitorInfo.rcMonitor.left || rDC.top != monitorInfo.rcMonitor.top) + { + BOOL fullScreenMaximized = NO; + if (wp.showCmd == SW_SHOWMAXIMIZED && !fullScreenMaximized) { - [[PlayerEntity sharedPlayer] doGuiScreenResizeUpdates]; + fullScreenMaximized = YES; + wp.showCmd = SW_SHOWNORMAL; + SetWindowPlacement(windowHandle, &wp); } - /* - deliberately no break statement here - moving or resizing the window changes its bounds - 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". - // However, for some reason I cannot get an actual string on lParam. This means that the - // 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 - // 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 - ` are set correctly to what they should be when we get focus. We have - ` to do it ourselves because SDL on Windows has problems with this - ` when focus change events occur, like e.g. Alt-Tab in/out of the - application - ` */ - [self resetSDLKeyModifiers]; - if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) + + if (wp.showCmd != SW_SHOWMINIMIZED && wp.showCmd != SW_MINIMIZE) { - dwLastError = GetLastError(); - OOLog(@"wm_setfocus.message", @"Setting thread priority to time critical failed! (error code: %ld)", dwLastError); + MoveWindow(windowHandle, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, + (int)viewSize.width, (int)viewSize.height, TRUE); } - [gameController setEcoQoS:[gameController isGamePaused]]; - break; - case WM_KILLFOCUS: - if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL)) + if (fullScreenMaximized) { - dwLastError = GetLastError(); - OOLog(@"wm_killfocus.message", @"Setting thread priority to normal failed! (error code: %ld)", dwLastError); + GetWindowPlacement(windowHandle, &wp); + wp.showCmd = SW_SHOWMAXIMIZED; + CopyRect(&wp.rcNormalPosition, &lastGoodRect); + SetWindowPlacement(windowHandle, &wp); } - [gameController setEcoQoS:YES]; - break; - - default: - ; + } + else if (wp.showCmd == SW_SHOWMAXIMIZED) + { + CopyRect(&wp.rcNormalPosition, &lastGoodRect); + SetWindowPlacement(windowHandle, &wp); + } } + // it is important that this gets done after we've dealt with possible fullscreen movements, + // because -doGuiScreenResizeUpdates does itself an update on current monitor + if ([PlayerEntity sharedPlayer]) + { + [[PlayerEntity sharedPlayer] doGuiScreenResizeUpdates]; + } + + if(grabMouseStatus) [self grabMouseInsideGameWindow:YES]; + break; + } + + case SDL_EVENT_WINDOW_FOCUS_GAINED: + { + // make sure that all modifier keys like Shift, Alt, Ctrl and Caps Lock + // are set correctly to what they should be when we get focus. We have + // to do it ourselves because SDL on Windows has problems with this + // when focus change events occur, like e.g. Alt-Tab in/out of the + // application + + [self resetSDLKeyModifiers]; + if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) + { + dwLastError = GetLastError(); + OOLog(@"wm_setfocus.message", @"Setting thread priority to time critical failed! (error code: %ld)", dwLastError); + } + [gameController setEcoQoS:[gameController isGamePaused]]; + break; + } + + case SDL_EVENT_WINDOW_FOCUS_LOST: + { + if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL)) + { + dwLastError = GetLastError(); + OOLog(@"wm_killfocus.message", @"Setting thread priority to normal failed! (error code: %ld)", dwLastError); + } + [gameController setEcoQoS:YES]; break; } #endif // caused by INTR or someone hitting close - case SDL_QUIT: + case SDL_EVENT_QUIT: { - SDL_FreeSurface(surface); + SDL_DestroyWindow(window); [gameController exitAppWithContext:@"SDL_QUIT event received"]; } } @@ -2751,7 +2640,7 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i // versions. - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event keyID:(Uint16)key_id; { - SDLKey key=kbd_event->keysym.sym; + SDL_Keycode key=kbd_event->key; // Del, Backspace if((key == SDLK_BACKSPACE || key == SDLK_DELETE) && [typedString length] > 0) @@ -2769,7 +2658,7 @@ - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event keyID:(Uint16)key_id if (allowingStringInput == gvStringInputAlpha) { // inputAlpha - limited input for planet find screen - if(key >= SDLK_a && key <= SDLK_z) + if(key >= SDLK_A && key <= SDLK_Z) { isAlphabetKeyDown=YES; [typedString appendFormat:@"%c", key]; @@ -2797,56 +2686,41 @@ - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event keyID:(Uint16)key_id - (void) populateFullScreenModelist { int i; - SDL_Rect **modes; + SDL_DisplayMode **modes; NSMutableDictionary *mode; + SDL_DisplayID displayId = [self getDisplayId]; screenSizes=[[NSMutableArray alloc] init]; // The default resolution (slot 0) is the resolution we are // already in since this is guaranteed to work. - mode=[MyOpenGLView getNativeSize]; + mode=[self getNativeSize]; [screenSizes addObject: mode]; - modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); - if(modes == (SDL_Rect **)NULL) + int displayModeCount; + modes = SDL_GetFullscreenDisplayModes(displayId, &displayModeCount); + if(!displayModeCount) { OOLog(@"display.mode.list.none", @"%@", @"SDL didn't return any screen modes"); return; } - if(modes == (SDL_Rect **)-1) + for(i=0; i < displayModeCount; i++) { - OOLog(@"display.mode.list.none", @"%@", @"SDL claims 'all resolutions available' which is unhelpful in the extreme"); - return; - } - - int lastw=[[mode objectForKey: kOODisplayWidth] intValue]; - int lasth=[[mode objectForKey: kOODisplayHeight] intValue]; - for(i=0; modes[i]; i++) - { - // SDL_ListModes often lists a mode several times, - // presumably because each mode has several refresh rates. - // But the modes pointer is an SDL_Rect which can't represent - // refresh rates. WHY!? - if(modes[i]->w != lastw || modes[i]->h != lasth) + mode = [NSMutableDictionary dictionary]; + [mode setValue: [NSNumber numberWithInt: (int)modes[i]->w] + forKey: kOODisplayWidth]; + [mode setValue: [NSNumber numberWithInt: (int)modes[i]->h] + forKey: kOODisplayHeight]; + [mode setValue: [NSNumber numberWithFloat: (int)modes[i]->refresh_rate] + forKey: kOODisplayRefreshRate]; + if (![screenSizes containsObject:mode]) { - // new resolution, save it - mode=[NSMutableDictionary dictionary]; - [mode setValue: [NSNumber numberWithInt: (int)modes[i]->w] - forKey: kOODisplayWidth]; - [mode setValue: [NSNumber numberWithInt: (int)modes[i]->h] - forKey: kOODisplayHeight]; - [mode setValue: [NSNumber numberWithInt: 0] - forKey: kOODisplayRefreshRate]; - if (![screenSizes containsObject:mode]) - { - [screenSizes addObject: mode]; - OOLog(@"display.mode.list", @"Added res %d x %d", modes[i]->w, modes[i]->h); - lastw=modes[i]->w; - lasth=modes[i]->h; - } + [screenSizes addObject: mode]; + OOLog(@"display.mode.list", @"Added res %d x %d", modes[i]->w, modes[i]->h); } } + SDL_free(modes); } @@ -2954,28 +2828,15 @@ - (NSSize) currentScreenSize return NSMakeSize(WINDOW_SIZE_DEFAULT_WIDTH, WINDOW_SIZE_DEFAULT_HEIGHT); } - -- (void) setMouseInDeltaMode: (BOOL) inDelta -{ - mouseInDeltaMode=inDelta; -} - - -- (void) setGammaValue: (float) value +- (NSDictionary *) currentScreenMode { - if (value < 0.2f) value = 0.2f; - if (value > 4.0f) value = 4.0f; - - _gamma = value; - SDL_SetGamma(_gamma, _gamma, _gamma); - - [[NSUserDefaults standardUserDefaults] setFloat:_gamma forKey:@"gamma-value"]; + NSDictionary *mode=[screenSizes objectAtIndex: currentSize]; + return [[mode retain] autorelease]; } - -- (float) gammaValue +- (void) setMouseInDeltaMode: (BOOL) inDelta { - return _gamma; + mouseInDeltaMode=inDelta; } @@ -3012,7 +2873,7 @@ - (OOOpenGLMatrixManager *) getOpenGLMatrixManager + (BOOL)pollShiftKey { #if !OOLITE_WINDOWS - return 0 != (SDL_GetModState() & (KMOD_LSHIFT | KMOD_RSHIFT)); + return 0 != (SDL_GetModState() & (SDL_KMOD_LSHIFT | SDL_KMOD_RSHIFT)); #else // SDL_GetModState() does not seem to do exactly what is intended under Windows. For this reason, // the GetKeyState Windows API call is used to detect the Shift keypress. -- Nikos. @@ -3032,12 +2893,11 @@ - (void) dumpRGBAToFileNamed:(NSString *)name // use the snapshots directory NSString *dumpFile = [[NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR]; - dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.bmp", name]]; + dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.png", name]]; - // convert transparency to black before saving to bmp - SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 32, rowBytes, 0xFF, 0xFF00, 0xFF0000, 0xFF000000); - SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]); - SDL_FreeSurface(tmpSurface); + SDL_Surface* tmpSurface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_RGBA32, bytes, rowBytes); + SDL_SavePNG(tmpSurface, [dumpFile UTF8String]); + SDL_DestroySurface(tmpSurface); } @@ -3051,11 +2911,11 @@ - (void) dumpRGBToFileNamed:(NSString *)name // use the snapshots directory NSString *dumpFile = [[NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR]; - dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.bmp", name]]; + dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.png", name]]; - SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 24, rowBytes, 0xFF, 0xFF00, 0xFF0000, 0x0); - SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]); - SDL_FreeSurface(tmpSurface); + SDL_Surface* tmpSurface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_RGB24, bytes, rowBytes); + SDL_SavePNG(tmpSurface, [dumpFile UTF8String]); + SDL_DestroySurface(tmpSurface); } @@ -3069,11 +2929,23 @@ - (void) dumpGrayToFileNamed:(NSString *)name // use the snapshots directory NSString *dumpFile = [[NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR]; - dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.bmp", name]]; + dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.png", name]]; - SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 8, rowBytes, 0xFF, 0xFF, 0xFF, 0x0); - SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]); - SDL_FreeSurface(tmpSurface); + SDL_Surface* tmpSurface = SDL_CreateSurface(width, height, SDL_PIXELFORMAT_RGBA32); + for(int y = 0; y < height; y++) + { + uint8_t* srcRow = bytes + rowBytes*y; + uint8_t* dstRow = (uint8_t*)tmpSurface->pixels + y*tmpSurface->pitch; + for(int x = 0; x < width; x++) + { + dstRow[4*x + 0] = srcRow[x]; + dstRow[4*x + 1] = srcRow[x]; + dstRow[4*x + 2] = srcRow[x]; + dstRow[4*x + 3] = '\xff'; + } + } + SDL_SavePNG(tmpSurface, [dumpFile UTF8String]); + SDL_DestroySurface(tmpSurface); } @@ -3087,11 +2959,23 @@ - (void) dumpGrayAlphaToFileNamed:(NSString *)name // use the snapshots directory NSString *dumpFile = [[NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR]; - dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.bmp", name]]; + dumpFile = [dumpFile stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.png", name]]; - SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 16, rowBytes, 0xFF, 0xFF, 0xFF, 0xFF); - SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]); - SDL_FreeSurface(tmpSurface); + SDL_Surface* tmpSurface = SDL_CreateSurfaceFrom(width, height, SDL_PIXELFORMAT_RGBA32, bytes, rowBytes); + for(int y = 0; y < height; y++) + { + uint8_t* srcRow = bytes + rowBytes*y; + uint8_t* dstRow = (uint8_t*)tmpSurface->pixels + y*tmpSurface->pitch; + for(int x = 0; x < width; x++) + { + dstRow[4*x + 0] = srcRow[2*x]; + dstRow[4*x + 1] = srcRow[2*x]; + dstRow[4*x + 2] = srcRow[2*x]; + dstRow[4*x + 3] = srcRow[2*x+1]; + } + } + SDL_SavePNG(tmpSurface, [dumpFile UTF8String]); + SDL_DestroySurface(tmpSurface); } diff --git a/src/SDL/OOSDLJoystickManager.h b/src/SDL/OOSDLJoystickManager.h index 1acb1f3bd..b1a4510a6 100644 --- a/src/SDL/OOSDLJoystickManager.h +++ b/src/SDL/OOSDLJoystickManager.h @@ -36,7 +36,7 @@ MA 02110-1301, USA. #import -#import +#import #import "OOJoystickManager.h" @@ -45,13 +45,19 @@ MA 02110-1301, USA. @interface OOSDLJoystickManager: OOJoystickManager { @private + NSDictionary *joystickIdMap; SDL_Joystick *stick[MAX_STICKS]; - NSUInteger stickCount; + int stickCount; } - (id) init; +- (void) dealloc; - (BOOL) handleSDLEvent: (SDL_Event *)evt; - (NSString *) nameOfJoystick:(NSUInteger)stickNumber; - (int16_t) getAxisWithStick:(NSUInteger) stickNum axis:(NSUInteger) axisNum ; +- (JoyAxisEvent) makeJoyAxisEvent: (SDL_JoyAxisEvent*) sdlevt; +- (JoyButtonEvent) makeJoyButtonEvent: (SDL_JoyButtonEvent*) sdlevt; +- (JoyHatEvent) makeJoyHatEvent: (SDL_JoyHatEvent*) sdlevt; +- (NSInteger) getJoystickIndexFromId: (SDL_JoystickID) joystickId; @end diff --git a/src/SDL/OOSDLJoystickManager.m b/src/SDL/OOSDLJoystickManager.m index 0f56d108b..ad680e481 100644 --- a/src/SDL/OOSDLJoystickManager.m +++ b/src/SDL/OOSDLJoystickManager.m @@ -35,9 +35,11 @@ - (id) init { int i; + NSMutableDictionary *idMap = [[[NSMutableDictionary alloc] init] autorelease]; + // Find and open the sticks. Make sure that we don't fail if more joysticks than MAX_STICKS are detected. - stickCount = SDL_NumJoysticks(); - OOLog(@"joystick.init", @"Number of joysticks detected: %ld", (long)stickCount); + SDL_JoystickID *joystickIds = SDL_GetJoysticks(&stickCount); + OOLog(@"joystick.init", @"Number of joysticks detected: %d", stickCount); if (stickCount > MAX_STICKS) { stickCount = MAX_STICKS; @@ -52,36 +54,116 @@ - (id) init if(i > MAX_STICKS) break; - stick[i]=SDL_JoystickOpen(i); - if(!stick[i]) + stick[i]=SDL_OpenJoystick(joystickIds[i]); + if(stick[i]) + { + [idMap setObject: [NSNumber numberWithInt: i] forKey: [NSString stringWithFormat: @"%d", joystickIds[i]]]; + } + else { OOLog(@"joystick.init", @"Failed to open joystick #%d", i); } } - SDL_JoystickEventState(SDL_ENABLE); + SDL_SetJoystickEventsEnabled(true); } + SDL_free(joystickIds); + joystickIdMap = [idMap copy]; return [super init]; } +- (void) dealloc +{ + [joystickIdMap release]; + [super dealloc]; +} + + +- (NSInteger) getJoystickIndexFromId: (SDL_JoystickID) joystickId +{ + NSNumber *index = [joystickIdMap valueForKey: [NSString stringWithFormat: @"%d", joystickId]]; + if (index) + { + return [index integerValue]; + } + return -1; +} + + +- (JoyAxisEvent) makeJoyAxisEvent: (SDL_JoyAxisEvent*) sdlevt +{ + JoyAxisEvent evt; + evt.type = sdlevt->type; + evt.which = [self getJoystickIndexFromId: sdlevt->which]; + evt.axis = sdlevt->axis; + evt.value = sdlevt->value; + return evt; +} + +- (JoyButtonEvent) makeJoyButtonEvent: (SDL_JoyButtonEvent*) sdlevt +{ + JoyButtonEvent evt; + evt.type = sdlevt->type; + evt.which = [self getJoystickIndexFromId: sdlevt->which]; + evt.button = sdlevt->button; + evt.down = sdlevt->down; + return evt; +} + + +- (JoyHatEvent) makeJoyHatEvent: (SDL_JoyHatEvent*) sdlevt +{ + JoyHatEvent evt; + evt.type = sdlevt->type; + evt.which = [self getJoystickIndexFromId: sdlevt->which]; + evt.hat = sdlevt->hat; + evt.value = sdlevt->value; + return evt; +} + + - (BOOL) handleSDLEvent: (SDL_Event *)evt { BOOL rc=NO; switch(evt->type) { - case SDL_JOYAXISMOTION: - [self decodeAxisEvent: (JoyAxisEvent *)evt]; - rc=YES; + case SDL_EVENT_GAMEPAD_AXIS_MOTION: + case SDL_EVENT_JOYSTICK_AXIS_MOTION: + { + JoyAxisEvent joyEvt = [self makeJoyAxisEvent: (SDL_JoyAxisEvent*)evt]; + if (joyEvt.which >= 0) + { + [self decodeAxisEvent: &joyEvt]; + rc=YES; + } break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - [self decodeButtonEvent: (JoyButtonEvent *)evt]; - rc=YES; + } + + case SDL_EVENT_GAMEPAD_BUTTON_DOWN: + case SDL_EVENT_GAMEPAD_BUTTON_UP: + case SDL_EVENT_JOYSTICK_BUTTON_DOWN: + case SDL_EVENT_JOYSTICK_BUTTON_UP: + { + JoyButtonEvent joyEvt = [self makeJoyButtonEvent: (SDL_JoyButtonEvent*)evt]; + if (joyEvt.which >= 0) + { + [self decodeButtonEvent: &joyEvt]; + rc=YES; + } break; - case SDL_JOYHATMOTION: - [self decodeHatEvent: (JoyHatEvent *)evt]; - rc=YES; + } + + case SDL_EVENT_JOYSTICK_HAT_MOTION: + { + JoyHatEvent joyEvt = [self makeJoyHatEvent: (SDL_JoyHatEvent*)evt]; + if (joyEvt.which >= 0) + { + [self decodeHatEvent: &joyEvt]; + rc=YES; + } break; + } + default: OOLog(@"handleSDLEvent.unknownEvent", @"%@", @"JoystickHandler was sent an event it doesn't know"); } @@ -99,13 +181,14 @@ - (NSUInteger) joystickCount - (NSString *) nameOfJoystick:(NSUInteger)stickNumber { - return [NSString stringWithUTF8String:SDL_JoystickName((int)stickNumber)]; + if (stickNumber >= stickCount) return @"(unknown joystick)"; + return [NSString stringWithUTF8String:SDL_GetJoystickName(stick[stickNumber])]; } - (int16_t) getAxisWithStick:(NSUInteger) stickNum axis:(NSUInteger) axisNum { - return SDL_JoystickGetAxis(stick[stickNum], axisNum); + return SDL_GetJoystickAxis(stick[stickNum], axisNum); } diff --git a/src/SDL/main.m b/src/SDL/main.m index cd4fbe733..8a55b64f5 100644 --- a/src/SDL/main.m +++ b/src/SDL/main.m @@ -34,7 +34,8 @@ #if OOLITE_WINDOWS #include -#include +#include +#include // Make sure that a high performance GPU is // selected, if more than one are available __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; @@ -93,40 +94,31 @@ int main(int argc, char *argv[]) // Prepend system PATH env variable with our own executable's path char pathEnvVar[] = "PATH"; - char *systemPath = SDL_getenv(pathEnvVar); + const char *systemPath = SDL_getenv(pathEnvVar); size_t currentWorkingDirLen = strlen(currentWorkingDir); size_t systemPathLen = strlen(systemPath); // the max possible length of the string below is systemPath plus the path // we have determined for us, plus one char for the ";" and one char for the null terminator char *finalPath = malloc(systemPathLen + currentWorkingDirLen + 2 * sizeof(char)); - // the max possible length of the string below is systemPath plus the path we have - // determined for us, plus one char for the ";", plus the string "PATH", plus one char for the - // "=" of the final string that will be passed on to SDL_putenv and one char for the null terminator - char *envVarString = malloc(systemPathLen + currentWorkingDirLen + strlen(pathEnvVar) + 3 * sizeof(char)); strcpy(finalPath, currentWorkingDir); strcat(finalPath, ";"); strcat(finalPath, systemPath); - #define SETENVVAR(var, value) do {\ - sprintf(envVarString, "%s=%s", (var), (value));\ - SDL_putenv (envVarString);\ - } while (0); - - SETENVVAR("GNUSTEP_PATH_HANDLING", "windows"); - SETENVVAR(pathEnvVar, finalPath); - SETENVVAR("GNUSTEP_SYSTEM_ROOT", currentWorkingDir); - SETENVVAR("GNUSTEP_LOCAL_ROOT", currentWorkingDir); - SETENVVAR("GNUSTEP_NETWORK_ROOT", currentWorkingDir); - SETENVVAR("GNUSTEP_USERS_ROOT", currentWorkingDir); + SDL_Environment *environment = SDL_GetEnvironment(); + SDL_SetEnvironmentVariable(environment, "GNUSTEP_PATH_HANDLING", "windows", YES); + SDL_SetEnvironmentVariable(environment, pathEnvVar, finalPath, YES); + SDL_SetEnvironmentVariable(environment, "GNUSTEP_SYSTEM_ROOT", currentWorkingDir, YES); + SDL_SetEnvironmentVariable(environment, "GNUSTEP_LOCAL_ROOT", currentWorkingDir, YES); + SDL_SetEnvironmentVariable(environment, "GNUSTEP_NETWORK_ROOT", currentWorkingDir, YES); + SDL_SetEnvironmentVariable(environment, "GNUSTEP_USERS_ROOT", currentWorkingDir, YES); #if OO_GAME_DATA_TO_USER_FOLDER - SETENVVAR("HOMEPATH", strcat(SDL_getenv("LOCALAPPDATA"), "\\Oolite\\oolite.app")); + SDL_SetEnvironmentVariable(environment, "HOMEPATH", strcat(SDL_getenv("LOCALAPPDATA"), "\\Oolite\\oolite.app"), YES); #else - SETENVVAR("HOMEPATH", currentWorkingDir); + SDL_SetEnvironmentVariable(environment, "HOMEPATH", currentWorkingDir, YES); #endif SetCurrentDirectory(currentWorkingDir); - free(envVarString); free(finalPath); /* Windows amibtiously starts apps with the C library locale set to the