From 0ab252d39d5d4ea0f1c56a7f06d0f3d3ea294d61 Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Thu, 19 Jun 2025 08:47:42 -0700 Subject: [PATCH 01/18] [jak1] Fix speedrun mode bug where loading a save is counted as new run (#3960) Fixes a small bug introduced in #3902. Without this change, whenever you load a save it is treated as if you started a new game and resets the autosplitter back to 0s. --- goal_src/jak1/engine/game/game-save.gc | 4 ++++ goal_src/jak1/pc/features/speedruns.gc | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/goal_src/jak1/engine/game/game-save.gc b/goal_src/jak1/engine/game/game-save.gc index eb1d4e9bb9..30fa51e2dd 100644 --- a/goal_src/jak1/engine/game/game-save.gc +++ b/goal_src/jak1/engine/game/game-save.gc @@ -16,6 +16,7 @@ ;; Having two state machines, one in C++ and one in GOAL is kind of a questionable and confusing design. +(define-extern mark-speedrun-started (function none)) ;; DECOMP BEGINS ;; version identifier @@ -607,6 +608,9 @@ (set! save-data (the-as game-save-tag (&+ (the-as pointer save-data) (logand -16 (+ (* (the-as int (-> save-data elt-size)) (-> save-data elt-count)) 31))))))) + ;; og:preserve-this make sure loading a save doesn't reset speedrun state + (when (and (-> *pc-settings* speedrunner-mode?) (zero? (-> save new-game))) + (mark-speedrun-started)) ;; if we're a new game, set our checkpoint. (when (nonzero? (-> save new-game)) (set-continue! this "game-start") diff --git a/goal_src/jak1/pc/features/speedruns.gc b/goal_src/jak1/pc/features/speedruns.gc index 1218293c08..c958eb51bb 100644 --- a/goal_src/jak1/pc/features/speedruns.gc +++ b/goal_src/jak1/pc/features/speedruns.gc @@ -385,6 +385,10 @@ (set! (-> *speedrun-info* should-display?) #f) (none)) +(defun mark-speedrun-started () + (true! (-> *speedrun-info* has-started?)) + (none)) + (defun speedrun-mode-update () "A per frame update for speedrunning related stuff" (when (-> *pc-settings* speedrunner-mode?) @@ -397,7 +401,7 @@ ;; target has landed on ground/water, or we're about to enter target-hit-ground state (or (logtest? (-> *target* control status) (cshape-moving-flags onground onsurf on-water)) (= (-> *target* next-state name) 'target-hit-ground))) - (true! (-> *speedrun-info* has-started?)) + (mark-speedrun-started) ;; spawn a process that resets autosplitter after suspending for 1 frame (process-spawn-function process (lambda () From 5ad176507b70abd943d6f3910e23d9e96836bf78 Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Thu, 19 Jun 2025 08:47:52 -0700 Subject: [PATCH 02/18] [jak3] Subtitle typo (#3961) --- game/assets/jak3/subtitle/subtitle_lines_en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/assets/jak3/subtitle/subtitle_lines_en-US.json b/game/assets/jak3/subtitle/subtitle_lines_en-US.json index 6afd0b1db8..03520b63ae 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_lines_en-US.json @@ -6923,7 +6923,7 @@ "seem002": [ "Good work, hero. I mean... Jak.", "And you too, Orange Lightning.", - "We are... greatful for your help.", + "We are... grateful for your help.", "It... is possible I may have misjudged you two.", "That artifact is called the Precursor Prism.", "It will be of use to you.", From d352856927a9547f95439e9697a1944b51da262a Mon Sep 17 00:00:00 2001 From: massimilianodelliubaldini <8584296+massimilianodelliubaldini@users.noreply.github.com> Date: Thu, 19 Jun 2025 23:33:15 -0400 Subject: [PATCH 03/18] [jak2] Fix Fortress Crash by Patching Mips2C Function (#3963) Fixes #3151 by applying the same fix as #2686 to another Mips2C function. Tested by mashing Jak's body into the bad collision walls for 30 minutes without a single crash. --- game/mips2c/jak2_functions/collide_hash.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/game/mips2c/jak2_functions/collide_hash.cpp b/game/mips2c/jak2_functions/collide_hash.cpp index 1f262d7707..e644104d01 100644 --- a/game/mips2c/jak2_functions/collide_hash.cpp +++ b/game/mips2c/jak2_functions/collide_hash.cpp @@ -1066,9 +1066,11 @@ u64 execute(void* ctxt) { c->ppach(a3, r0, a3); // ppach a3, r0, a3 c->lqc2(vf11, 272, a2); // lqc2 vf11, 272(a2) c->dsll(a3, a3, 16); // dsll a3, a3, 16 - c->vftoi0(DEST::xyzw, vf3, vf3); // vftoi0.xyzw vf3, vf3 + + // patch vftoi0 calls because there's more bogus collide fragments + c->vftoi0_sat(DEST::xyzw, vf3, vf3); // vftoi0.xyzw vf3, vf3 bc = c->sgpr64(a3) != 0; // bne a3, r0, L63 - c->vftoi0(DEST::xyzw, vf4, vf4); // vftoi0.xyzw vf4, vf4 + c->vftoi0_sat(DEST::xyzw, vf4, vf4); // vftoi0.xyzw vf4, vf4 if (bc) {goto block_22;} // branch non-likely // nop // sll r0, r0, 0 From 8fbd85b0fc893ce60c16cf16ad5c90177d88de3b Mon Sep 17 00:00:00 2001 From: ZedB0T <89345505+Zedb0T@users.noreply.github.com> Date: Sun, 22 Jun 2025 20:07:43 -0400 Subject: [PATCH 04/18] Fail building custom level if long_name is too long (#3966) If long_name is too long, it will result in the level being invisible but the collide loading, lets detect this and point the user in correct direction to solve it with a clear error message. --------- Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com> --- custom_assets/jak1/levels/test-zone/test-zone.jsonc | 1 + custom_assets/jak2/levels/test-zone/test-zone.jsonc | 1 + custom_assets/jak3/levels/test-zone/test-zone.jsonc | 1 + goalc/build_level/jak1/build_level.cpp | 3 +++ goalc/build_level/jak2/build_level.cpp | 3 +++ goalc/build_level/jak3/build_level.cpp | 3 +++ 6 files changed, 12 insertions(+) diff --git a/custom_assets/jak1/levels/test-zone/test-zone.jsonc b/custom_assets/jak1/levels/test-zone/test-zone.jsonc index a08d1b62ee..3e7bd77a05 100644 --- a/custom_assets/jak1/levels/test-zone/test-zone.jsonc +++ b/custom_assets/jak1/levels/test-zone/test-zone.jsonc @@ -1,6 +1,7 @@ { // The "in-game" name of the level. Should be lower case, with dashes (GOAL symbol name) // the name of this file, and the folder this file is in must have the same name. + // The long_name must also be 10 characters or fewer. "long_name": "test-zone", // The file name, should be upper case and 8 characters or less. "iso_name": "TESTZONE", diff --git a/custom_assets/jak2/levels/test-zone/test-zone.jsonc b/custom_assets/jak2/levels/test-zone/test-zone.jsonc index 78dce59c8f..5953484bd8 100644 --- a/custom_assets/jak2/levels/test-zone/test-zone.jsonc +++ b/custom_assets/jak2/levels/test-zone/test-zone.jsonc @@ -1,6 +1,7 @@ { // The "in-game" name of the level. Should be lower case, with dashes (GOAL symbol name) // the name of this file, and the folder this file is in must have the same name. + // The long_name must also be 10 characters or fewer. "long_name": "test-zone", // The file name, should be upper case and 8 characters or less. "iso_name": "TESTZONE", diff --git a/custom_assets/jak3/levels/test-zone/test-zone.jsonc b/custom_assets/jak3/levels/test-zone/test-zone.jsonc index cd852780df..af145a51b1 100644 --- a/custom_assets/jak3/levels/test-zone/test-zone.jsonc +++ b/custom_assets/jak3/levels/test-zone/test-zone.jsonc @@ -1,6 +1,7 @@ { // The "in-game" name of the level. Should be lower case, with dashes (GOAL symbol name) // the name of this file, and the folder this file is in must have the same name. + // The long_name must also be 10 characters or fewer. "long_name": "test-zone", // The file name, should be upper case and 8 characters or less. "iso_name": "TESTZONE", diff --git a/goalc/build_level/jak1/build_level.cpp b/goalc/build_level/jak1/build_level.cpp index 9513bf5596..52d6fa2ee1 100644 --- a/goalc/build_level/jak1/build_level.cpp +++ b/goalc/build_level/jak1/build_level.cpp @@ -48,6 +48,9 @@ bool run_build_level(const std::string& input_file, // unk zero // name file.name = level_json.at("long_name").get(); + ASSERT_MSG(file.name.size() <= 10, + fmt::format("long_name over 10 characters ({} characters): '{}'", file.name.size(), + file.name)); // nick file.nickname = level_json.at("nickname").get(); // vis infos diff --git a/goalc/build_level/jak2/build_level.cpp b/goalc/build_level/jak2/build_level.cpp index 7a65489e8c..b350ffac9a 100644 --- a/goalc/build_level/jak2/build_level.cpp +++ b/goalc/build_level/jak2/build_level.cpp @@ -42,6 +42,9 @@ bool run_build_level(const std::string& input_file, // unk zero // name file.name = level_json.at("long_name").get(); + ASSERT_MSG(file.name.size() <= 10, + fmt::format("long_name over 10 characters ({} characters): '{}'", file.name.size(), + file.name)); // nick file.nickname = level_json.at("nickname").get(); // vis infos diff --git a/goalc/build_level/jak3/build_level.cpp b/goalc/build_level/jak3/build_level.cpp index e83e220760..932ae679ff 100644 --- a/goalc/build_level/jak3/build_level.cpp +++ b/goalc/build_level/jak3/build_level.cpp @@ -40,6 +40,9 @@ bool run_build_level(const std::string& input_file, // unk zero // name file.name = level_json.at("long_name").get(); + ASSERT_MSG(file.name.size() <= 10, + fmt::format("long_name over 10 characters ({} characters): '{}'", file.name.size(), + file.name)); // nick file.nickname = level_json.at("nickname").get(); // vis infos From 2002cd018870ddc9c0b86f012c298c8f9a3df2f8 Mon Sep 17 00:00:00 2001 From: Aloqas <102683375+Aloqas@users.noreply.github.com> Date: Sun, 29 Jun 2025 04:23:32 +0300 Subject: [PATCH 05/18] Some jak 3 transcription fixes (#3893) --- .../jak3/subtitle/subtitle_lines_en-US.json | 728 ++++------- .../jak3/subtitle/subtitle_meta_en-US.json | 1118 +---------------- 2 files changed, 251 insertions(+), 1595 deletions(-) diff --git a/game/assets/jak3/subtitle/subtitle_lines_en-US.json b/game/assets/jak3/subtitle/subtitle_lines_en-US.json index 03520b63ae..7d7dd17bcf 100644 --- a/game/assets/jak3/subtitle/subtitle_lines_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_lines_en-US.json @@ -197,18 +197,6 @@ "asha013": [ "Oh, that hurt." ], - "asha014": [ - "Ugh!" - ], - "asha015": [ - "Ough!" - ], - "asha016": [ - "Ah!" - ], - "asha017": [ - "Agh!" - ], "asha018": [ "Hit me again and you'll lose something really valuable!" ], @@ -358,23 +346,23 @@ "barout01": [ "Game?! Games are for wimps!", "Get out in the real world. It's called the sun!", - "That round bright thing in the sky! Geez... Hahah!", + "That round bright thing in the sky! Geez...", "Seriously though, this is going to be one hell of a game.", "World is enormous, the scenery, state of the art,", - "the action is sizzling. I only wish I was getting some", - "back-end points, you know? Haha." + "the action is sizzling.", + "I only wish I was getting some back-end points, you know?" ], "barout02": [ - "Oh, well, I did it for the money.", + "Oh, well I did it for the money.", "I do everything for the money.", "Hey, you know I got a serious mortgage in Beverly Hills.", - "The story? Well, I mean you know, to be honest,", - "the writers were...", - "Well, let's just say there were a few plot errors and", - "some of the characters were painfully two-dimensional.", + "The story?", + "Well, to be honest, the writers were...", + "Well, let's just say there were a few plot errors", + "and some of the characters were painfully two-dimensional.", "And what was that stilted on-the-nose", "expository dialogue crap I was fed... Heh, ah geez...", - "Otherwise, no, I loved the script..." + "Otherwise no I loved the script..." ], "barout03": [ "Well I wish I had a stunt double for my death scene.", @@ -395,8 +383,8 @@ "What do you expect from the Baron?" ], "barout05": [ - "It was a pleasure working on this one. Seriously,", - "I hope Baron Praxis comes back from the dead", + "It was a pleasure working on this one.", + "Seriously, I hope Baron Praxis comes back from the dead", "so I can kick some more butt in the sequel. Hahaha!", "And Daxter, baby, hook me up with Ashelin, will you?", "She won't return my calls, man." @@ -739,7 +727,7 @@ "Stop!" ], "cit158": [ - "Alright, watch out!" + "All right, watch out!" ], "cit158a": [ "Watch out!" @@ -834,48 +822,6 @@ "cit173a": [ "Hahahaha...!" ], - "cit174": [ - "Hurgh!" - ], - "cit174a": [ - "Haa!" - ], - "cit175": [ - "Ge-aghh!" - ], - "cit175a": [ - "Ah!" - ], - "cit176": [ - "Oof!" - ], - "cit176a": [ - "Ugh!" - ], - "cit177": [ - "Gahh!" - ], - "cit177a": [ - "Aghh!" - ], - "cit178": [ - "Dahh!" - ], - "cit178a": [ - "Ough!" - ], - "cit179": [ - "Hrgh!" - ], - "cit179a": [ - "Aghhh!" - ], - "cit180": [ - "Urgh!" - ], - "cit180a": [ - "Ouh!" - ], "cit181": [ "Well, that hurt!" ], @@ -1104,30 +1050,6 @@ "cit219a": [ "Dance, sucker!" ], - "cit220": [ - "Gahh!" - ], - "cit220a": [ - "Arghh!" - ], - "cit221": [ - "Oughh!" - ], - "cit221a": [ - "Ourgh!" - ], - "cit222": [ - "Oof!" - ], - "cit222a": [ - "Ugh!" - ], - "cit223": [ - "Gahh!" - ], - "cit223a": [ - "Arhh!" - ], "cit224": [ "No!" ], @@ -1167,12 +1089,6 @@ "citi095": [ "Do I know you?" ], - "citi097": [ - "Ahhh!" - ], - "citi098": [ - "Ugh!" - ], "citi099": [ "No!" ], @@ -1212,9 +1128,6 @@ "citi137": [ "Wait!" ], - "citi138": [ - "Ahh!" - ], "citi139": [ "What are you doing?" ], @@ -1583,7 +1496,7 @@ "We did it!" ], "dax124": [ - "Alright, I won! I mean... we won." + "All right, I won! I mean... we won." ], "dax125": [ "These babies can glide too.", @@ -1593,7 +1506,7 @@ "We need to get all the lizards!" ], "dax127": [ - "We got company... marauders!" + "We got company! Marauders!" ], "dax128": [ "Head for the city, Jak." @@ -1653,7 +1566,7 @@ "Wait here, I'll be back." ], "dax147": [ - "O-okay, this is high up..." + "Okay, this is high up..." ], "dax148": [ "Fingers, don't fail me now." @@ -1671,7 +1584,7 @@ "Jak, you're getting too low!" ], "dax153": [ - "They got a missile lock, pull up!" + "They got a missile lock! Pull up!" ], "dax154": [ "Climb, baby, climb!" @@ -1743,10 +1656,10 @@ "Blurgh... These rolling hills are making me carsick." ], "dax177": [ - "Fly, they're onto us!" + "Fly! They're onto us!" ], "dax178": [ - "We got an artifact, cool!" + "We got an artifact. Cool!" ], "dax179": [ "Go to the next artifact, Jak." @@ -1755,7 +1668,7 @@ "We got another item." ], "dax181": [ - "Another trinket for Damas, whoopee!" + "Another trinket for Damas. Whoopee!" ], "dax182": [ "Great, more junk." @@ -1770,7 +1683,7 @@ "We got the last one!" ], "dax186": [ - "Alright, more Precursor crap." + "All right, more Precursor crap." ], "dax187": [ "The storm's getting worse!" @@ -1782,7 +1695,7 @@ "Head for the city!" ], "dax190": [ - "Almost there...!" + "Almost there!" ], "dax191": [ "You gotta get back to the city, man!" @@ -1806,7 +1719,7 @@ "You need to get closer, Jak!" ], "dax198": [ - "Almost there...!" + "Almost there!" ], "dax199": [ "Get him closer!" @@ -1914,17 +1827,11 @@ "Ahaaa!" ], "dax234": [ - "Yahoo, yes!" + "Yahoo! Yes!" ], "dax235": [ "I'm getting a little raw..." ], - "dax236": [ - "Whoaaow!" - ], - "dax237": [ - "Whoa-oa-oaa-oh!" - ], "dax238": [ "Wahoo!" ], @@ -1965,16 +1872,16 @@ "Let's not play chicken with them, okay?" ], "dax251": [ - "Watch out, that end has teeth!" + "Watch out! That end has teeth!" ], "dax252": [ "He's shooting at us!" ], "dax253": [ - "Shoot him, shoot him!" + "Shoot him! Shoot him!" ], "dax254": [ - "He's down, go get him!" + "He's down! Go get him!" ], "dax255": [ "Fire, fire!" @@ -1989,10 +1896,10 @@ "The bigger they are, the harder they fall." ], "dax259": [ - "Yes, you took one out!" + "Yes! You took one out!" ], "dax260": [ - "Keep at him, he's going down!" + "Keep at him! He's going down!" ], "dax261": [ "Down for the count!" @@ -2004,7 +1911,7 @@ "I think you pissed him off!" ], "dax264": [ - "Yes, nice work!" + "Yes! Nice work!" ], "dax265": [ "He's in the crosshairs!" @@ -2064,7 +1971,7 @@ "Nice shooting, Jak!" ], "dax284": [ - "Man, this thing look nasty." + "Man, this thing looks nasty." ], "dax285": [ "You gotta defeat the keylock, Jak!" @@ -2074,11 +1981,11 @@ "before they hit the center." ], "dax287": [ - "You can only take them out when they", - "pass through the circles." + "You can only take them out", + "when they pass through the circles." ], "dax288": [ - "Good job, you're killin' 'em!" + "Good job! You're killin' 'em!" ], "dax289": [ "Faster, Jak, faster!" @@ -2090,7 +1997,7 @@ "Yes!" ], "dax292": [ - "Hgghh...! Here come some more!" + "Here come some more!" ], "dax293": [ "Nooo!" @@ -2102,10 +2009,10 @@ "You missed another one!" ], "dax296": [ - "Aaaa, that's not gonna win the game!" + "Aghhh...! That's not gonna win the game!" ], "dax297": [ - "Not again." + "Not again..." ], "dax298": [ "This doesn't look good." @@ -2117,7 +2024,7 @@ "Don't miss another one, Jak!" ], "dax301": [ - "Aaaa, you lost!" + "Aghh! You lost!" ], "dax302": [ "That's the end of that." @@ -2138,7 +2045,7 @@ "You want me to play?" ], "dax308": [ - "You took them all out, you won!" + "You took them all out! You won!" ], "dax309": [ "You won! Yes, you did it!" @@ -2153,7 +2060,7 @@ "Get him, get him!" ], "dax313": [ - "You got it! Eww, nasty." + "You got it! Ewh... nasty." ], "dax314": [ "Did someone miss their breakfast?" @@ -2162,7 +2069,7 @@ "Hungry, huh?" ], "dax316": [ - "Get another one, yes!" + "Get another one! Yes!" ], "dax317": [ "One more, bon appétit!" @@ -2240,7 +2147,7 @@ "We got 'em all! Anybody else hungry?" ], "dax342": [ - "On your monk, get set, ride!" + "On your monk... Get set... Ride!" ], "dax343": [ "Go, Jak!" @@ -2282,7 +2189,7 @@ "Greased lizard coming through!" ], "dax356": [ - "Huah, you missed a ring!" + "Ahh, you missed a ring!" ], "dax357": [ "Noo!" @@ -2318,16 +2225,16 @@ "We won!" ], "dax368": [ - "Aaaa, we lost!" + "Aahh, we lost!" ], "dax369": [ - "Noo, we lost to a bunch of weirdos!" + "Noo! We lost to a bunch of weirdos!" ], "dax370": [ - "Ahhaa, we lost again." + "Aghhh, we lost again." ], "dax371": [ - "Nghh, we lost again." + "Nahh, we lost again." ], "dax372": [ "Gotta move, Jak!" @@ -2336,7 +2243,7 @@ "We got an unfriendly tailgater!" ], "dax374": [ - "Fly, Jak, the missiles are following us!" + "Fly, Jak! The missiles are following us!" ], "dax375": [ "Head for the Port!" @@ -2357,13 +2264,13 @@ "You have to get the missile to go after the decoy!" ], "dax381": [ - "Yes, the missile is going after the decoy!" + "Yes! The missile is going after the decoy!" ], "dax382": [ - "One missile down, go fire up another decoy!" + "One missile down. Go fire up another decoy." ], "dax383": [ - "Great, one more missile bites the dust!" + "Great! One more missile bites the dust!" ], "dax384": [ "Find another decoy!" @@ -2372,7 +2279,7 @@ "One more down. You are the man, Jak!" ], "dax386": [ - "Yes, one more down!" + "Yes! One more down!" ], "dax387": [ "I could drive like that." @@ -2457,10 +2364,10 @@ "Four laps!" ], "dax414": [ - "Five, and we're still alive!" + "Five and we're still alive!" ], "dax415": [ - "Last lap, you can do it!" + "Last lap! You can do it!" ], "dax416": [ "We won! We are the speed demons!" @@ -2469,7 +2376,7 @@ "We did it! We are the dust masters." ], "dax418": [ - "Yes! Win, place, AND show." + "Yes! Win, place, and show." ], "dax419": [ "We won!" @@ -2478,10 +2385,10 @@ "Oh no, we lost. I'm the main course..." ], "dax421": [ - "Noo, I'm as good as skinned!" + "No! I'm as good as skinned!" ], "dax422": [ - "Gaaah, he beat us! It was nice knowing ya, Jak." + "Gahhh, he beat us! It was nice knowing ya, Jak." ], "dax423": [ "Ah, we lost." @@ -2546,24 +2453,6 @@ "dax443": [ "Find 'em!" ], - "dax444": [ - "Whoow!" - ], - "dax445": [ - "Yeip!" - ], - "dax446": [ - "Uaa-eaugh!" - ], - "dax447": [ - "Oof!" - ], - "dax448": [ - "Ouuhh!" - ], - "dax449": [ - "Yaahohooo!" - ], "dax450": [ "Yaaahhh!" ], @@ -2574,13 +2463,13 @@ "Yes! Crunchy!" ], "dax453": [ - "Alright! Sucks to be him." + "All right! Sucks to be him." ], "dax454": [ "Almost!" ], "dax455": [ - "Aaaa, we missed it." + "Aghhh, we missed it." ], "dax456": [ "Missed!" @@ -2589,7 +2478,7 @@ "Lunge, Jak, lunge!" ], "dax458": [ - "Alright, sucks to be him. Hehe!" + "All right, sucks to be him. He he!" ], "dax459": [ "Aaahh!" @@ -2719,9 +2608,6 @@ "dax500": [ "It's crumbling, Jak!" ], - "dax501": [ - "Ngyeh-hey!" - ], "dax502": [ "There's one of those big boys!" ], @@ -2831,12 +2717,6 @@ "dax537": [ "Lizard, don't fail me now!" ], - "dax538": [ - "Ngggh! Ow! Oww! Owww!" - ], - "dax539": [ - "Woah-wow!" - ], "dax540": [ "Easy boy, easy boy!" ], @@ -2951,9 +2831,6 @@ "dax577": [ "Yes!" ], - "dax578": [ - "Oof!" - ], "dax579": [ "Good night!" ], @@ -2999,9 +2876,6 @@ "dax593": [ "Flames in the butt equals bad." ], - "dax594": [ - "Wooooo-ooow!" - ], "dax595": [ "Slippery tail!" ], @@ -3033,7 +2907,7 @@ "Bye bye!" ], "dax605": [ - "B.Y.O.D. Bring your own Daxter." + "BYOD. Bring your own Daxter." ], "dax606": [ "Okay, I'll get this one." @@ -3051,7 +2925,7 @@ "Aren't you lucky you got me?" ], "dax611": [ - "Not again, I have to do it all!" + "Not again... I have to do it all!" ], "dax612": [ "Aww, do I have to do this again?!" @@ -3066,10 +2940,10 @@ "Okay Jak, we're clear." ], "dax616": [ - "Once again, Daxter saves the day." + "Once again Daxter saves the day." ], "dax617": [ - "Once again, Orange Lightning saves the day." + "Once again Orange Lightning saves the day." ], "dax618": [ "It's nice to see you just stand there...", @@ -3352,7 +3226,7 @@ "Find another decoy!" ], "dax711": [ - "Don't crash, or we're toast!" + "Don't crash or we're toast!" ], "dax712": [ "Yes! One less missile on our tail." @@ -3414,24 +3288,6 @@ "dax731": [ "Take him out!" ], - "dax732": [ - "Oof!" - ], - "dax733": [ - "Ow!" - ], - "dax734": [ - "Eek!" - ], - "dax735": [ - "Ow!" - ], - "dax736": [ - "Gulp!" - ], - "dax737": [ - "Ow!" - ], "dax757": [ "Marauder warriors, Jak!" ], @@ -3493,44 +3349,44 @@ "Ooh, there's a baddie on my track!" ], "dax777": [ - "Push the buttons!" + "Push the buttons." ], "dax778": [ - "Jump dive on the button!" + "Jump dive on the button." ], "dax779": [ - "The claw's up!" + "The claw's up." ], "dax780": [ - "Attack the claw!" + "Attack the claw." ], "dax781": [ - "Attack 'em from behind!" + "Attack 'em from behind." ], "dax782": [ - "Get 'em from behind!" + "Get 'em from behind." ], "dax783": [ - "Shoot him where he's weak!" + "Shoot him where he's weak." ], "dax784": [ "That's not hurting him!" ], "dax785": [ - "Find another way to hurt him!" + "Find another way to hurt him." ], "dax786": [ "You gotta find a green eco vent." ], "dax787": [ - "You gotta charge up with green eco!" + "You gotta charge up with green eco." ], "dax788": [ "Hover over the plants", "while you're charged up with green eco." ], "dax789": [ - "Huh, robot transports are landing!" + "Whoo! Robot transports are landing!" ], "dax790": [ "Destroy all the transports, Jak!" @@ -3618,31 +3474,31 @@ "Do you remember how to use the JetBoard?" ], "dax818": [ - "You can jump with the JetBoard, Jak!" + "You can jump with the JetBoard, Jak." ], "dax819": [ - "Try jumping!" + "Try jumping." ], "dax820": [ "You can get a bigger jump by ducking first." ], "dax821": [ - "You can spin when you jump!" + "You can spin when you jump." ], "dax822": [ "You can grind with the JetBoard." ], "dax823": [ - "Try grinding!" + "Try grinding." ], "dax824": [ - "Landing a 360 gives you a boost!" + "Landing a 360 gives you a boost." ], "dax825": [ "You can do a flip when you jump." ], "dax826": [ - "You can do lots of cool tricks on the JetBoard!" + "You can do lots of cool tricks on the JetBoard." ], "dax827": [ "There's a Dark Crystal!" @@ -3651,7 +3507,7 @@ "There's a Light Crystal!" ], "dax829": [ - "You got all the crystals and they formed the Eco Sphere!" + "You got all the crystals and they form the Eco Sphere!" ], "dax830": [ "You got another gun upgrade." @@ -3770,9 +3626,8 @@ "daxout01": [ "I hope this game's fun. I mean I do my part,", "I'm practically carrying the whole thing, you know.", - "The next game should be called", - "Orange Lightning Strikes Again...", - "Orange Lightning Strikes Twice?...", + "The next game should be called Orange Lightning Strikes Again.", + "Orange Lightning Strikes Twice?", "You know, I think we should branch out.", "Shouldn't just feel completely anchored", "to the whole adventure genre, you know.", @@ -3780,7 +3635,7 @@ "I got the moves, I got the moves." ], "daxout02": [ - "Yeah it's uh, it's tough in the suit.", + "Yeah it's tough in the suit.", "I mean, it's a hundred and ten degrees in here.", "Takes seven hours in the chair to glue this stuff on.", "I'm like those monkeys in that movie,", @@ -3791,9 +3646,9 @@ "Now I've got you wondering, huh? I'm an enigma." ], "daxout03": [ - "Well I want to direct the next game,", - "you know, I've been working on my command voice.", - "Listen: Action! What do you think, not bad huh?", + "Well I want to direct the next game.", + "You know, I've been working on my command voice.", + "Listen: Action! What do you think? Not bad, huh?", "Action! See? I can do it.", "I'll grow a beard and look shabby chic", "and talk all intellectual about shot blocking,", @@ -3805,7 +3660,7 @@ "caught in the Hip Hog. Whew...", "It was a hot set when we were, you know,", "getting into our characters...", - "Ah, fun times, fun times." + "Ah... fun times, fun times." ], "daxout05": [ "Jak and I go way back.", @@ -3832,8 +3687,8 @@ "And for the rest, my agent straightened them out." ], "daxout08": [ - "Yeah, two words: Daxter 3.", - "I'm the star, man! Everyone knows it. Jak knows it!", + "Yeah, two words: Daxter Three.", + "I'm the star, man. Everyone knows it. Jak knows it!", "Come on, who gets the laughs?", "Who's out there taking the hard falls? With no stunt double!", "Me! I'm the glue in this horse factory. I want my props!", @@ -3904,9 +3759,6 @@ "ero017": [ "Now you see why I never lose." ], - "ero019": [ - "Ahh!" - ], "ero020": [ "Here's some pain!" ], @@ -3938,7 +3790,7 @@ "Now we end this!" ], "ero035": [ - "DIE!" + "Die!" ], "ero036": [ "Die!" @@ -3950,13 +3802,13 @@ "YEAH!" ], "ero039": [ - "HA!" + "Ha!" ], "ero040": [ - "NO!" + "No!" ], "ero041": [ - "NOOOOO!" + "Nooooo!" ], "ero042": [ "AHHHHHH!" @@ -4019,22 +3871,13 @@ "No!" ], "ero074": [ - "STOP!" + "Stop!" ], "ero075": [ "Hahahaha!" ], "ero076": [ - "HAHA!" - ], - "ero077": [ - "Ahhh!" - ], - "ero078": [ - "Ough!" - ], - "ero079": [ - "Oof!" + "Ha ha!" ], "ero083": [ "It was easier than I thought to beat you." @@ -4055,38 +3898,11 @@ "Too bad, I win!" ], "ero094": [ - "Hahahaha, pathetic insect, I win!" + "Hahaha! Pathetic insect, I win!" ], "ero095": [ "You can never defeat me!" ], - "ero096": [ - "Ahhh... hrgh!" - ], - "ero097": [ - "Ugh!" - ], - "ero098": [ - "Ughhh!" - ], - "ero099": [ - "Dahh!" - ], - "ero100": [ - "Yaughh!" - ], - "ero101": [ - "AUGHH!" - ], - "ero102": [ - "OW!" - ], - "ero103": [ - "DAHHH!" - ], - "ero104": [ - "DAUGHH!" - ], "erol001": [ "You fool! You can't stop evolution, Jak.", "The future belongs to the machines.", @@ -4240,9 +4056,6 @@ "erot017": [ "Now you see why I never lose." ], - "erot019": [ - "Ahh!" - ], "erot020": [ "Here's some pain!" ], @@ -4274,7 +4087,7 @@ "Now we end this!" ], "erot035": [ - "DIE!" + "Die!" ], "erot036": [ "Die!" @@ -4286,13 +4099,13 @@ "YEAH!" ], "erot039": [ - "HA!" + "Ha!" ], "erot040": [ - "NO!" + "No!" ], "erot041": [ - "NOOOOO!" + "Nooooo!" ], "erot042": [ "AHHHHHH!" @@ -4355,22 +4168,13 @@ "No!" ], "erot074": [ - "STOP!" + "Stop!" ], "erot075": [ "Hahahaha!" ], "erot076": [ - "HAHA!" - ], - "erot077": [ - "Ahhh!" - ], - "erot078": [ - "Ough!" - ], - "erot079": [ - "Oof!" + "Ha ha!" ], "erot083": [ "It was easier than I thought to beat you." @@ -4391,55 +4195,28 @@ "Too bad, I win!" ], "erot094": [ - "Hahahaha, pathetic insect, I win!" + "Hahaha! Pathetic insect, I win!" ], "erot095": [ "You can never defeat me!" ], - "erot096": [ - "Ahhh... hrgh!" - ], - "erot097": [ - "Ugh!" - ], - "erot098": [ - "Ughhh!" - ], - "erot099": [ - "Dahh!" - ], - "erot100": [ - "Yaughh!" - ], - "erot101": [ - "AUGHH!" - ], - "erot102": [ - "OW!" - ], - "erot103": [ - "DAHHH!" - ], - "erot104": [ - "DAUGHH!" - ], "grds101": [ - "Look out, Blast Bots!" + "Look out! Blast Bots!" ], "grds101a": [ - "Look out, Blast Bots!" + "Look out! Blast Bots!" ], "grds101b": [ - "Look out, Blast Bots!" + "Look out! Blast Bots!" ], "grds102": [ - "Death Bots are attacking the Port, return fire!" + "Death Bots are attacking the Port! Return fire!" ], "grds102a": [ - "Death Bots are attacking the Port, return fire!" + "Death Bots are attacking the Port! Return fire!" ], "grds102b": [ - "Death Bots are attacking the Port, return fire!" + "Death Bots are attacking the Port! Return fire!" ], "grds103": [ "Take out the Blast Bot!" @@ -4451,13 +4228,13 @@ "Take out the Blast Bot!" ], "grds104": [ - "Alert, alert, we are under attack!" + "Alert! Alert! We are under attack!" ], "grds104a": [ - "Alert, alert, we are under attack!" + "Alert! Alert! We are under attack!" ], "grds104b": [ - "Alert, alert, we're under attack!" + "Alert! Alert! We're under attack!" ], "grds105": [ "Move, move, we've got Metal Heads inbound!" @@ -4487,13 +4264,13 @@ "That's a big robot!" ], "grds108": [ - "Metal Heads, shoot 'em, shoot 'em!" + "Metal Heads! Shoot 'em, shoot 'em!" ], "grds108a": [ - "Metal Heads, shoot 'em, shoot 'em!" + "Metal Heads! Shoot 'em, shoot 'em!" ], "grds108b": [ - "Metal Heads, shoot 'em, shoot 'em!" + "Metal Heads! Shoot 'em, shoot 'em!" ], "grds109": [ "Shoot it, man!" @@ -4735,24 +4512,6 @@ "grds135b": [ "Help me!" ], - "grds136": [ - "Aghhh!" - ], - "grds136a": [ - "AGHH!" - ], - "grds136b": [ - "AHHH!" - ], - "grds137": [ - "Ough!" - ], - "grds137a": [ - "Oof!" - ], - "grds137b": [ - "Oughh!" - ], "grds138": [ "No!" ], @@ -5294,14 +5053,15 @@ "I just gotta reach down inside and RAAAHH!" ], "jakout02": [ - "Well, you know, sometimes I just get a little angry.", - "I like to have my own personal space and", - "when people invade it, I just get mad and,", - "you know, I can't deal with that sometimes", - "because, you know, I'm an artist and I need my time,", - "and I'm creating new things and outlets for this process and", - "sometimes the hindrance of people coming up to me and", - "telling me what I'm supposed to do just really pisses me off!" + "Well, sometimes I just get a little angry.", + "I like to have my own personal space", + "and when people invade it, I just get mad", + "and I can't deal with that sometimes", + "because I'm an artist and I need my time", + "and I'm creating new things and outlets for this process", + "and sometimes the hindrance of people coming up to me", + "and telling me what I'm supposed to do", + "just really pisses me off!" ], "jakout03": [ "Well Daxter's his own little furball.", @@ -5311,7 +5071,7 @@ "jakout04": [ "Well I'm really looking in to do some dramatic work", "to really show my sensitive side.", - "Um, and I'm working right now on my own sitcom.", + "And I'm working right now on my own sitcom.", "I'd just like to do a shoutout real quick, to Lashandra." ], "jinx001": [ @@ -5324,7 +5084,7 @@ "You're close enough. Pull the pin, Jakey!" ], "jinx102": [ - "Hey there, pretty boy! You ready to rock and rumble?" + "Hey there, pretty boy. You ready to rock and rumble?" ], "jinx103": [ "Let's drive, sweetheart." @@ -5364,7 +5124,7 @@ "Fly, man, we ain't getting any younger." ], "jinx115": [ - "Get to the next target!" + "Get to the next target." ], "jinx116": [ "Drive to the next junction box, man." @@ -5382,7 +5142,7 @@ "Cover me, Jak!" ], "jinx121": [ - "Come on, keep them off me, buddy!" + "Come on, keep them off me, buddy." ], "jinx122": [ "That was a sweet fireball." @@ -5405,15 +5165,6 @@ "jinx128": [ "One more of those and you'll taking me home in pieces." ], - "jinx129": [ - "AHHH!" - ], - "jinx130": [ - "AHH!" - ], - "jinx131": [ - "Agh!" - ], "jinx132": [ "Oh boy!" ], @@ -5453,7 +5204,7 @@ "and I'll give you a special reward." ], "k-bb03w": [ - "I can't believe ya did it. Nice rollin', nipper.", + "I can't believe you did it. Nice rollin', nipper.", "Here's a prize for your effort." ], "k-bb04f": [ @@ -5484,7 +5235,7 @@ "Get more air, beat the record, and I'll give up the loot." ], "k-bb05w": [ - "Alright, you did it, kid. I'm happy for ya.", + "All right, you did it, kid. I'm happy for ya.", "But not for long." ], "k-bb05x": [ @@ -5530,13 +5281,14 @@ "Not too shabby. You did the deed, so here's the feed." ], "k-bb09f": [ - "I knew you didn't have it in ya. Let's pretend we never met." + "I knew you didn't have it in ya. ", + "Let's pretend we never met." ], "k-bb09i": [ "Here's a fun challenge for ya.", "Get on the turret and take out as many targets as you can.", - "Beat me high score and I'll pound ya.", - "But, I'll also give you a nice little prize." + "Beat me high score and I'll pound ya,", + "but I'll also give you a nice little prize." ], "k-bb09w": [ "Okay, okay. So you got some moves, kid.", @@ -5567,8 +5319,8 @@ "Not bad shootin', Jak. You win another one." ], "k-bb12f": [ - "Can't ya do this for good old Kleiver?", - "I don't ask for much. Come on, Jak, try harder." + "Can't ya do this one for good old Kleiver?", + "I don't ask for much. Come on, Jak. Try harder." ], "k-bb12i": [ "Did I mention I hate Metal Heads?", @@ -5576,11 +5328,11 @@ "Take 'em all out before time runs out and a prize is yours." ], "k-bb12w": [ - "The bigger they are, the harder they fall, ey?", + "The bigger they are, the harder they fall, eh?", "Nice work, wheelboy." ], "k-bb13f": [ - "You lost. Don't let these animals get the best of ya!", + "You lost! Don't let these animals get the best of ya!", "Never show 'em fear! Go back out there and have at 'em." ], "k-bb13i": [ @@ -5660,7 +5412,7 @@ "Well, we'll see how long that is, mates." ], "klev101": [ - "Alright, let's race!" + "All right, let's race!" ], "klev102": [ "You up for this, Jak?" @@ -5681,7 +5433,7 @@ "See ya!" ], "klev108": [ - "I'll for you at the finish line." + "I'll wait for you at the finish line." ], "klev109": [ "Bye bye, newbie." @@ -5714,7 +5466,7 @@ "Move over!" ], "klev119": [ - "Pump and grind, nipper." + "Bump and grind, nipper." ], "klev120": [ "Ha ha, last lap!" @@ -5768,10 +5520,10 @@ "Yes!" ], "klev137": [ - "Hahah!" + "Ha ha!" ], "klev138": [ - "Hahah, I win!" + "Ha ha, I win!" ], "klev139": [ "You lose!" @@ -5783,7 +5535,7 @@ "How'd you beat me?!" ], "klev142": [ - "Arrhh, you won." + "Arrgh, you won." ], "klev143": [ "Shoot the targets." @@ -5792,7 +5544,7 @@ "Looking good." ], "klev145": [ - "Nice shot, keep it up." + "Nice shot. Keep it up." ], "klev146": [ "Lead those puppies." @@ -5846,7 +5598,7 @@ "Lightning shot!" ], "klev163": [ - "You won, amazing." + "You won. Amazing." ], "klev164": [ "Blast, you did it." @@ -6023,7 +5775,7 @@ ], "o-bb05w": [ "Once again you prove the stories were true.", - "You were - we mean... you are - a great hero." + "You were - we mean you are - a great hero." ], "o-bb06f": [ "It is not easy to fail. Would you like to try again?" @@ -6310,7 +6062,7 @@ "No." ], "peck001": [ - "Hahaa! The bad boy and his rat win in style." + "Ha haa! The bad boy and his rat win in style." ], "peck002": [ "You guys keep the surprises coming!", @@ -6371,13 +6123,13 @@ "You have to make jumps to survive in this world." ], "peck115": [ - "Come on Jak, jump like you've got a pair!" + "Come on Jak, jump like you've got a pair." ], "peck116": [ - "Come on Jak, jump like you've got 'em!" + "Come on Jak, jump like you've got 'em." ], "peck117": [ - "And the newcomer makes the first jump!" + "And the newcomer makes the first jump." ], "peck118": [ "Keep going!" @@ -6398,7 +6150,7 @@ "Whoa, this boy's got promise." ], "peck124": [ - "You can punch as well! Try your fist out." + "You can punch as well. Try your fist out." ], "peck125": [ "Ooh! Sweet move!" @@ -6413,7 +6165,7 @@ "Beautiful." ], "peck129": [ - "You must roll sometimes. Jak, give the crowd a roll!" + "You must roll sometimes. Jak, give the crowd a roll." ], "peck130": [ "And the crowd goes wild!" @@ -6474,7 +6226,7 @@ "Very nice. Very nice indeed." ], "peck149": [ - "Oh yeah, nice heat." + "Oh yeah, nice hit." ], "peck150": [ "Okay boys, get busy." @@ -6564,7 +6316,7 @@ "Ready... begin!" ], "peck179": [ - "I haven't seen such bravery since... well... this morning." + "I haven't seen such bravery since... well, this morning." ], "peck180": [ "Very smooth move!" @@ -6891,7 +6643,7 @@ "Jak, you can kill those plants with your JetBoard.", "Just collect the green eco energy,", "then lay it down over the plants.", - "You have to kill the main plant stocks too.", + "You have to kill the main plant stalks too.", "And one more thing, don't let the spores resprout.", "And Daxter... don't get in Jak's way!" ], @@ -7083,7 +6835,7 @@ "Sweet shot!" ], "sig136": [ - "One Metal Head, totally dead!" + "One Metal Head totally dead!" ], "sig137": [ "Another trophy on the wall!" @@ -7092,7 +6844,7 @@ "He's history!" ], "sig139": [ - "Keep trackin'! More coming in." + "Keep tracking! More coming in." ], "sig140": [ "Keep your tail dry, chili pepper." @@ -7128,7 +6880,7 @@ "Look out!" ], "sig151": [ - "One more like that and we'll be walkin' home!" + "One more like that and we'll be walking home!" ], "sig152": [ "Fire on the roll!" @@ -7154,24 +6906,6 @@ "sig166": [ "Hang on!" ], - "sig167": [ - "Gah!" - ], - "sig168": [ - "Woah!" - ], - "sig169": [ - "Gah!" - ], - "sig170": [ - "Gah!" - ], - "sig171": [ - "Aah!" - ], - "sig172": [ - "Aah!" - ], "sig173": [ "Into the cave!" ], @@ -7304,27 +7038,6 @@ "sig216": [ "Whew, that was close." ], - "sig217": [ - "Argh!" - ], - "sig218": [ - "Ugh!" - ], - "sig219": [ - "Ugh!" - ], - "sig220": [ - "Aargh!" - ], - "sig221": [ - "Oof!" - ], - "sig222": [ - "Urgh!" - ], - "sig223": [ - "Roaaaargh!" - ], "sig224": [ "We got company!" ], @@ -7476,7 +7189,7 @@ "We did it!" ], "sig277": [ - "That was a gas! Heh heh... sorry, I couldn't resist." + "That was a gas! Heh heh... Sorry, I couldn't resist." ], "sig278": [ "Shoot it to knock it down!" @@ -7593,7 +7306,7 @@ "Find this spot before time runs out for a prize." ], "t-bb03w": [ - "Good work, you haven't lost it." + "Good work. You haven't lost it." ], "t-bb04f": [ "Not fast enough, Jak. Get a map, man." @@ -7602,7 +7315,7 @@ "Here's another get-to challenge. Time's counting." ], "t-bb04w": [ - "Good work, you're looking like the hero I remember." + "Good work. You're looking like the hero I remember." ], "t-bb05f": [ "Tough one, huh? Wanna shuffle your feet again?" @@ -7611,7 +7324,7 @@ "Find this spot fast. Good luck." ], "t-bb05w": [ - "Excellent, you did it." + "Excellent. You did it." ], "t-bb06f": [ "I didn't think you could do this one." @@ -7630,7 +7343,7 @@ "Find this place fast. You'll need a vehicle." ], "t-bb07w": [ - "Alright, nice driving, speed demon." + "All right. Nice driving, speed demon." ], "t-bb08f": [ "Not fast enough, buddy. Next time get the lead out." @@ -7703,7 +7416,7 @@ "Here's another place to find." ], "t-bb15x": [ - "One more place to reach, go get it." + "One more place to reach. Go get it." ], "t-bb16x": [ "Can you find this spot?" @@ -7721,13 +7434,13 @@ "Not your best effort." ], "t-bb21x": [ - "You lose, try again." + "You lose. Try again." ], "t-bb22x": [ "Sweet work." ], "t-bb23x": [ - "Alright, good stuff, Jak." + "All right. Good stuff, Jak." ], "t-bb24x": [ "Nice!" @@ -7748,10 +7461,10 @@ "tesout02": [ "Where did you read that?", "Like, you totally have to talk to my therapist about that.", - "But, you know Daxter he's like, he's totally neat.", + "But, you know Daxter he's like totally neat.", "He's a hottie! Like, burning volcano hot.", "I mean, the whole like, animal thing, it's a total act.", - "He's really sophisticated in real life, for sure!", + "He's really sophisticated in real life for sure!", "He orders wine with lunch and everything." ], "tesout03": [ @@ -7947,7 +7660,7 @@ "Dax, honey, you need a new partner." ], "tess158": [ - "Care to the second course?" + "Care to try the second course?" ], "tess159": [ "You wasted 'em." @@ -8133,7 +7846,7 @@ "You can be my bodyguard anytime." ], "tess218": [ - "Alright, you beat the course. Is it getting hot in here?" + "All right, you beat the course. Is it getting hot in here?" ], "tess219": [ "Nice weapon work, yakow boy." @@ -8157,7 +7870,7 @@ "Fire in the hole!" ], "tor009": [ - "Flames 'r us, he he he." + "Flames 'r us, hee hee hee." ], "tor010": [ "Glad you're here, Jak. This is the big one.", @@ -8166,7 +7879,7 @@ "If the wall's breached, we're through." ], "tor014": [ - "This is it, get ready. Here they come!" + "This is it. Get ready. Here they come!" ], "tor019": [ "Got one!" @@ -8178,10 +7891,10 @@ "Multiple targets inbound!" ], "tor023": [ - "Too many, too many!" + "Too many! Too many!" ], "tor026": [ - "Here comes a whole swarm of them." + "Here comes a whole swarm of 'em." ], "tor029": [ "You got it!" @@ -8202,10 +7915,10 @@ "Good shooting!" ], "tor035": [ - "Nice work, that was close." + "Nice work! That was close." ], "tor036": [ - "More on the right, shoot to the right!" + "More on the right. Shoot to the right!" ], "tor037": [ "They're coming in faster!" @@ -8223,7 +7936,7 @@ "Keep shooting!" ], "tor056": [ - "Yeah, now they're feeling it!" + "Yeah! Now they're feeling it!" ], "tor059": [ "Get 'em!" @@ -8284,9 +7997,9 @@ "torn008": [ "Jak, we've located four critical power junctions,", "that if destroyed, could drop some of their shields.", - "Our bang expert Jinx can blow the juctions", - "if you can get him to each one and protect him", - "while he's laying the charges.", + "Our bang expert Jinx can blow the junctions", + "if you can get him to each one", + "and protect him while he's laying the charges.", "You remember Jinx? He's waiting in a vehicle outside.", "Happy blastin'." ], @@ -8332,7 +8045,7 @@ "You can move the bot and shoot with the remote box." ], "torn110": [ - "Alright, let's do this.", + "All right, let's do this.", "Try to get in as far as you can before making a move.", "They'll know something's up soon enough." ], @@ -8340,7 +8053,7 @@ "Keep moving!" ], "torn112": [ - "They know something's wrong, move it!" + "They know something's wrong. Move it!" ], "torn113": [ "That bot's taking a lot of fire, Jak. Shoot back!" @@ -8403,13 +8116,13 @@ "Those Metal Heads won't know what hit 'em." ], "torn133": [ - "They're onto you, move!" + "They're onto you. Move!" ], "torn134": [ "Get a little closer." ], "torn135": [ - "Alright buddy, you did it." + "All right, buddy. You did it." ], "torn136": [ "Watch out!", @@ -8426,7 +8139,7 @@ "Use the Gyro Blast setting on your gun for maximum damage!" ], "torn140": [ - "You took one out, now get the rest!" + "You took one out. Now get the rest!" ], "torn141": [ "Shoot it now, the shield's down!" @@ -8435,7 +8148,7 @@ "You gotta hit them at the right time." ], "torn143": [ - "That didn't touch it, the shields wore out!" + "That didn't touch it. The shields wore out!" ], "torn144": [ "Didn't lay a glove on it, try again." @@ -8447,7 +8160,7 @@ "Fire now!" ], "torn147": [ - "It's got a bead on you, move!" + "It's got a bead on you. Move!" ], "torn148": [ "Use the high firepower modes on your weapon for these babies." @@ -8474,10 +8187,10 @@ "Activate another decoy!" ], "torn156": [ - "Come on, Jak, you can do it." + "Come on, Jak. You can do it." ], "torn157": [ - "You got it, one missile down." + "You got it! One missile down." ], "torn158": [ "Another missile's off track. Keep going!" @@ -8573,7 +8286,7 @@ "You can't miss them." ], "torn187": [ - "There they are, shoot them!" + "There they are. Shoot 'em!" ], "torn188": [ "Take out the shield generators." @@ -8589,7 +8302,7 @@ "Watch out for fighters!" ], "torn192": [ - "More blips on the scope, you got company." + "More blips on the scope. You got company." ], "torn193": [ "You're taking lots of fire!", @@ -8649,7 +8362,7 @@ ], "torn209": [ "Okay, you're hot and heavy.", - "Don't run into anything, or you and that missile are toast." + "Don't run into anything or you and that missile are toast." ], "torn210": [ "Find an eco charge to arm the missile!" @@ -8669,7 +8382,7 @@ "The missile's almost fully armed. Keep going!" ], "torn215": [ - "Alright, the missile's armed.", + "All right, the missile's armed.", "Now drive it right into the barrier.", "And Daxter, you may wanna get off first." ], @@ -8689,7 +8402,7 @@ "You've got to avoid everything!" ], "torn221": [ - "Touch anything, and you're an Ottsel fireball." + "Touch anything and you're an Ottsel fireball." ], "torn222": [ "Keep driving!" @@ -8701,26 +8414,26 @@ "Find the barrier and crash it!" ], "torn225": [ - "That was close, stay frosty!" + "That was close. Stay frosty!" ], "torn226": [ "You're braver than I thought, Daxter." ], "torout01": [ - "Uh, I guess it was his rugged manliness, but yet,", - "someone who was also not afraid to touch the inner me,", + "Uh, I guess it was his rugged manliness,", + "but yet someone who's also not afraid to touch the inner me,", "you know what I mean?", - "Uh, Torn's that guy we all want to be.", - "The cool quiet guy, that just sits there and", - "when your back's up against the wall,", - "you know, he ain't gonna go dancing with you, but,", - "he'll cover your back." + "Torn's that guy we all want to be.", + "The cool quiet guy that just sits there", + "and when your back's up against the wall,", + "he ain't gonna go dancing with you", + "but he'll cover your back." ], "torout02": [ "Well, the thing about Ashelin is she, you know,", "she got a great set of guns.", - "She... and you know, the ones you shoot with.", - "And uh, yeah she's good, she's strong, she's intelligent.", + "She... And you know, the ones you shoot with.", + "And yeah, she's good, she's strong, she's intelligent.", "Uh, yeah. Fire in the hole!" ], "vin101": [ @@ -8728,7 +8441,7 @@ ], "vin102": [ "Okay, you're in.", - "Now, I'm gonna hide in the memory core", + "Now I'm gonna hide in the memory core", "and pretend I don't know you." ], "vin103": [ @@ -8747,7 +8460,7 @@ "Way to go!" ], "vin108": [ - "Alright!" + "All right!" ], "vin109": [ "Uh oh, not good." @@ -8759,7 +8472,7 @@ "You're erased, bit-boy." ], "vin112": [ - "Game over, man, game over." + "Game over, man. Game over." ], "vin113": [ "Game over, man." @@ -8771,7 +8484,7 @@ "Do over, dude." ], "vin116": [ - "You're the gamer, alright." + "You're the gamer, all right." ], "vin117": [ "Game on!" @@ -8801,7 +8514,7 @@ "You won!" ], "vin126": [ - "Yes, you beat the system!" + "Yes! You beat the system!" ], "vin127": [ "Does this mean we're not gonna hang out?" @@ -8851,19 +8564,18 @@ "vinout01": [ "Oh, you know, it's a funny thing", "because there's a lot of pressure on the mic.", - "Yeah, there's like five or six people watching you at once.", - "And they feed you the lines,", - "and I tell you, it's never good enough.", + "Yeah, there's like five or six people watching you at once", + "and they feed you the lines.", + "And I tell you, it's never good enough.", "Ah, they just want more.", - "But I got to tell you at the same time, it's just,", - "it's a lot of fun, you know.", + "But I got to tell you at the same time it's a lot of fun.", "I do have fun working and I love the people.", - "You know, people are interesting to me,", + "People are interesting to me", "but just as long as they don't get too close.", - "Yeah, they have me in a booth here,", - "and I have this thing about people getting too close.", - "So they have to stay sort of outside the booth,", - "and then I do my thing in here, and then I go outside,", + "Yeah, they have me in a booth here", + "and I have this thing about people getting too close,", + "so they have to stay sort of outside the booth.", + "And then I do my thing in here and then I go outside,", "but I don't shake hands 'cause I got a thing about germs.", "Yeah, that's why I keep this thing right here on my belt, see,", "and I just squeeze it and it's a dry wash for the hands,", diff --git a/game/assets/jak3/subtitle/subtitle_meta_en-US.json b/game/assets/jak3/subtitle/subtitle_meta_en-US.json index 16c74cf978..2f2697e990 100644 --- a/game/assets/jak3/subtitle/subtitle_meta_en-US.json +++ b/game/assets/jak3/subtitle/subtitle_meta_en-US.json @@ -10225,50 +10225,6 @@ } ] }, - "asha014": { - "lines": [ - { - "frame_end": 11, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "ashelin" - } - ] - }, - "asha015": { - "lines": [ - { - "frame_end": 9, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "ashelin" - } - ] - }, - "asha016": { - "lines": [ - { - "frame_end": 10, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "ashelin" - } - ] - }, - "asha017": { - "lines": [ - { - "frame_end": 10, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "ashelin" - } - ] - }, "asha018": { "lines": [ { @@ -10889,7 +10845,7 @@ "speaker": "baron" }, { - "frame_end": 525, + "frame_end": 486, "frame_start": 445, "merge": false, "offscreen": true, @@ -10897,7 +10853,7 @@ }, { "frame_end": 580, - "frame_start": 526, + "frame_start": 487, "merge": false, "offscreen": true, "speaker": "baron" @@ -10928,7 +10884,7 @@ "speaker": "baron" }, { - "frame_end": 297, + "frame_end": 240, "frame_start": 203, "merge": false, "offscreen": true, @@ -10936,7 +10892,7 @@ }, { "frame_end": 332, - "frame_start": 298, + "frame_start": 241, "merge": false, "offscreen": true, "speaker": "baron" @@ -11087,7 +11043,7 @@ "barout05": { "lines": [ { - "frame_end": 96, + "frame_end": 78, "frame_start": 0, "merge": false, "offscreen": true, @@ -11095,7 +11051,7 @@ }, { "frame_end": 172, - "frame_start": 97, + "frame_start": 79, "merge": false, "offscreen": true, "speaker": "baron" @@ -12724,160 +12680,6 @@ } ] }, - "cit174": { - "lines": [ - { - "frame_end": 8, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit174a": { - "lines": [ - { - "frame_end": 13, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit175": { - "lines": [ - { - "frame_end": 19, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit175a": { - "lines": [ - { - "frame_end": 22, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit176": { - "lines": [ - { - "frame_end": 7, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit176a": { - "lines": [ - { - "frame_end": 7, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit177": { - "lines": [ - { - "frame_end": 9, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit177a": { - "lines": [ - { - "frame_end": 17, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit178": { - "lines": [ - { - "frame_end": 14, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit178a": { - "lines": [ - { - "frame_end": 10, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit179": { - "lines": [ - { - "frame_end": 10, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit179a": { - "lines": [ - { - "frame_end": 26, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit180": { - "lines": [ - { - "frame_end": 15, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit180a": { - "lines": [ - { - "frame_end": 8, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, "cit181": { "lines": [ { @@ -13714,94 +13516,6 @@ } ] }, - "cit220": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit220a": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit221": { - "lines": [ - { - "frame_end": 15, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit221a": { - "lines": [ - { - "frame_end": 14, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit222": { - "lines": [ - { - "frame_end": 12, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit222a": { - "lines": [ - { - "frame_end": 11, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit223": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, - "cit223a": { - "lines": [ - { - "frame_end": 12, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-male" - } - ] - }, "cit224": { "lines": [ { @@ -13945,28 +13659,6 @@ } ] }, - "citi097": { - "lines": [ - { - "frame_end": 31, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-female" - } - ] - }, - "citi098": { - "lines": [ - { - "frame_end": 16, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-female" - } - ] - }, "citi099": { "lines": [ { @@ -14110,17 +13802,6 @@ } ] }, - "citi138": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "wastelander-female" - } - ] - }, "citi139": { "lines": [ { @@ -16789,28 +16470,6 @@ } ] }, - "dax236": { - "lines": [ - { - "frame_end": 25, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax237": { - "lines": [ - { - "frame_end": 31, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax238": { "lines": [ { @@ -17360,7 +17019,7 @@ "dax287": { "lines": [ { - "frame_end": 37, + "frame_end": 30, "frame_start": 0, "merge": false, "offscreen": true, @@ -17368,7 +17027,7 @@ }, { "frame_end": 75, - "frame_start": 38, + "frame_start": 31, "merge": false, "offscreen": true, "speaker": "daxter" @@ -19098,72 +18757,6 @@ } ] }, - "dax444": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax445": { - "lines": [ - { - "frame_end": 15, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax446": { - "lines": [ - { - "frame_end": 39, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax447": { - "lines": [ - { - "frame_end": 12, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax448": { - "lines": [ - { - "frame_end": 27, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax449": { - "lines": [ - { - "frame_end": 36, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax450": { "lines": [ { @@ -19739,17 +19332,6 @@ } ] }, - "dax501": { - "lines": [ - { - "frame_end": 29, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax502": { "lines": [ { @@ -20153,28 +19735,6 @@ } ] }, - "dax538": { - "lines": [ - { - "frame_end": 106, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax539": { - "lines": [ - { - "frame_end": 29, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax540": { "lines": [ { @@ -20593,17 +20153,6 @@ } ] }, - "dax578": { - "lines": [ - { - "frame_end": 14, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax579": { "lines": [ { @@ -20769,17 +20318,6 @@ } ] }, - "dax594": { - "lines": [ - { - "frame_end": 40, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax595": { "lines": [ { @@ -22294,72 +21832,6 @@ } ] }, - "dax732": { - "lines": [ - { - "frame_end": 11, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax733": { - "lines": [ - { - "frame_end": 11, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax734": { - "lines": [ - { - "frame_end": 7, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax735": { - "lines": [ - { - "frame_end": 10, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax736": { - "lines": [ - { - "frame_end": 6, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, - "dax737": { - "lines": [ - { - "frame_end": 11, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "daxter" - } - ] - }, "dax757": { "lines": [ { @@ -23611,16 +23083,9 @@ "offscreen": true, "speaker": "daxter" }, - { - "frame_end": 198, - "frame_start": 146, - "merge": false, - "offscreen": true, - "speaker": "daxter" - }, { "frame_end": 263, - "frame_start": 199, + "frame_start": 146, "merge": false, "offscreen": true, "speaker": "daxter" @@ -24284,17 +23749,6 @@ } ] }, - "ero019": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, "ero020": { "lines": [ { @@ -24735,39 +24189,6 @@ } ] }, - "ero077": { - "lines": [ - { - "frame_end": 33, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero078": { - "lines": [ - { - "frame_end": 26, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero079": { - "lines": [ - { - "frame_end": 25, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, "ero083": { "lines": [ { @@ -24856,105 +24277,6 @@ } ] }, - "ero096": { - "lines": [ - { - "frame_end": 62, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero097": { - "lines": [ - { - "frame_end": 20, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero098": { - "lines": [ - { - "frame_end": 23, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero099": { - "lines": [ - { - "frame_end": 26, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero100": { - "lines": [ - { - "frame_end": 28, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero101": { - "lines": [ - { - "frame_end": 31, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero102": { - "lines": [ - { - "frame_end": 36, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero103": { - "lines": [ - { - "frame_end": 33, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "ero104": { - "lines": [ - { - "frame_end": 47, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, "erol001": { "lines": [ { @@ -25536,17 +24858,6 @@ } ] }, - "erot019": { - "lines": [ - { - "frame_end": 13, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, "erot020": { "lines": [ { @@ -25987,39 +25298,6 @@ } ] }, - "erot077": { - "lines": [ - { - "frame_end": 25, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot078": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot079": { - "lines": [ - { - "frame_end": 17, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, "erot083": { "lines": [ { @@ -26108,105 +25386,6 @@ } ] }, - "erot096": { - "lines": [ - { - "frame_end": 54, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot097": { - "lines": [ - { - "frame_end": 12, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot098": { - "lines": [ - { - "frame_end": 15, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot099": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot100": { - "lines": [ - { - "frame_end": 20, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot101": { - "lines": [ - { - "frame_end": 24, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot102": { - "lines": [ - { - "frame_end": 28, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot103": { - "lines": [ - { - "frame_end": 26, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, - "erot104": { - "lines": [ - { - "frame_end": 37, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "errol" - } - ] - }, "grds101": { "lines": [ { @@ -27351,72 +26530,6 @@ } ] }, - "grds136": { - "lines": [ - { - "frame_end": 32, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "guard" - } - ] - }, - "grds136a": { - "lines": [ - { - "frame_end": 39, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "guard" - } - ] - }, - "grds136b": { - "lines": [ - { - "frame_end": 39, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "guard" - } - ] - }, - "grds137": { - "lines": [ - { - "frame_end": 16, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "guard" - } - ] - }, - "grds137a": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "guard" - } - ] - }, - "grds137b": { - "lines": [ - { - "frame_end": 23, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "guard" - } - ] - }, "grds138": { "lines": [ { @@ -29469,11 +28582,18 @@ "speaker": "jak" }, { - "frame_end": 691, + "frame_end": 629, "frame_start": 596, "merge": false, "offscreen": true, "speaker": "jak" + }, + { + "frame_end": 691, + "frame_start": 630, + "merge": false, + "offscreen": true, + "speaker": "jak" } ] }, @@ -29881,39 +29001,6 @@ } ] }, - "jinx129": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "jinx" - } - ] - }, - "jinx130": { - "lines": [ - { - "frame_end": 17, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "jinx" - } - ] - }, - "jinx131": { - "lines": [ - { - "frame_end": 8, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "jinx" - } - ] - }, "jinx132": { "lines": [ { @@ -30452,11 +29539,18 @@ "k-bb09f": { "lines": [ { - "frame_end": 121, + "frame_end": 60, "frame_start": 0, "merge": false, "offscreen": true, "speaker": "kleiver" + }, + { + "frame_end": 121, + "frame_start": 61, + "merge": false, + "offscreen": true, + "speaker": "kleiver" } ] }, @@ -31338,7 +30432,7 @@ "klev127": { "lines": [ { - "frame_end": 56, + "frame_end": 65, "frame_start": 0, "merge": false, "offscreen": true, @@ -37214,72 +36308,6 @@ } ] }, - "sig167": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig168": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig169": { - "lines": [ - { - "frame_end": 11, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig170": { - "lines": [ - { - "frame_end": 12, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig171": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig172": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, "sig173": { "lines": [ { @@ -37764,83 +36792,6 @@ } ] }, - "sig217": { - "lines": [ - { - "frame_end": 25, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig218": { - "lines": [ - { - "frame_end": 25, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig219": { - "lines": [ - { - "frame_end": 23, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig220": { - "lines": [ - { - "frame_end": 36, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig221": { - "lines": [ - { - "frame_end": 18, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig222": { - "lines": [ - { - "frame_end": 21, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, - "sig223": { - "lines": [ - { - "frame_end": 35, - "frame_start": 0, - "merge": false, - "offscreen": true, - "speaker": "sig" - } - ] - }, "sig224": { "lines": [ { @@ -41627,7 +40578,7 @@ "speaker": "torn" }, { - "frame_end": 345, + "frame_end": 317, "frame_start": 271, "merge": false, "offscreen": true, @@ -41635,7 +40586,7 @@ }, { "frame_end": 394, - "frame_start": 346, + "frame_start": 318, "merge": false, "offscreen": true, "speaker": "torn" @@ -43301,7 +42252,7 @@ "torout01": { "lines": [ { - "frame_end": 108, + "frame_end": 87, "frame_start": 0, "merge": false, "offscreen": true, @@ -43309,7 +42260,7 @@ }, { "frame_end": 195, - "frame_start": 109, + "frame_start": 88, "merge": false, "offscreen": true, "speaker": "torn" @@ -43906,16 +42857,9 @@ "offscreen": true, "speaker": "vin" }, - { - "frame_end": 422, - "frame_start": 361, - "merge": false, - "offscreen": true, - "speaker": "vin" - }, { "frame_end": 470, - "frame_start": 423, + "frame_start": 361, "merge": false, "offscreen": true, "speaker": "vin" From 1748086136362927ebd940594b834249526c86cc Mon Sep 17 00:00:00 2001 From: MuchWhittering <149691053+MuchWhittering@users.noreply.github.com> Date: Sun, 29 Jun 2025 02:24:36 +0100 Subject: [PATCH 06/18] Updating UK English spelling - Cutscene (#3962) Fixing some of the warrior's spelling for British English. --- game/assets/jak1/subtitle/subtitle_lines_en-GB.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game/assets/jak1/subtitle/subtitle_lines_en-GB.json b/game/assets/jak1/subtitle/subtitle_lines_en-GB.json index d0a53153e3..e91a755d08 100644 --- a/game/assets/jak1/subtitle/subtitle_lines_en-GB.json +++ b/game/assets/jak1/subtitle/subtitle_lines_en-GB.json @@ -126,9 +126,9 @@ "MAYBE EVEN THE TOUGHEST OF THEM ALL.", "I SINGLE-HANDEDLY DEFENDED THIS VILLAGE FROM THOSE HORRID CREATURES FOR ALMOST A YEAR!", "THEN THAT HORRIBLE MONSTER ARRIVED AND COMMENCED THE BOULDER BOMBARDMENT.", - "SO, FULL OF VALOUR, ARMOR SHINING IN THE SUN...", + "SO, FULL OF VALOUR, ARMOUR SHINING IN THE SUN...", "I CLIMBED THE HILL TO TAKE HIM ON...!", - "BUT HE POUNDED ME LIKE ONE TENDERIZES A YAKOW STEAK.", + "BUT HE POUNDED ME LIKE ONE TENDERISES A YAKOW STEAK.", "HAVE YOU TRIED ATTACKING HIM WITH YOUR MELODRAMA?", "'CAUSE IT'S KILLIN' ME!", "AFTER MY LAST STUNNING FAILURE,", From 72c3bd3d309bd337117c13dc2d9507df5a588823 Mon Sep 17 00:00:00 2001 From: OpenGOAL Bot <99294829+OpenGOALBot@users.noreply.github.com> Date: Sat, 28 Jun 2025 21:24:42 -0400 Subject: [PATCH 07/18] CI: Periodic Controller Database Update (#3953) Updating Controller Database Co-authored-by: OpenGOALBot --- game/assets/sdl_controller_db.txt | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/game/assets/sdl_controller_db.txt b/game/assets/sdl_controller_db.txt index 20784195b5..66c198d1ff 100644 --- a/game/assets/sdl_controller_db.txt +++ b/game/assets/sdl_controller_db.txt @@ -329,6 +329,7 @@ 030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000c100000000000000,Horipad Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000f600000000000000,Horipad Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, +030000000d0f00000202000000000000,Horipad O Nintendo Switch 2 Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,misc2:b14,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f00009601000000000000,Horipad Steam,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc2:b2,paddle1:b5,paddle2:b15,paddle3:b18,paddle4:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, @@ -469,8 +470,10 @@ 030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows, 03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows, 03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, +030000007e0500006920000000000000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Windows, 030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows, +030000007e0500007320000000000000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Windows, 030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows, 030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows, 03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows, @@ -1000,13 +1003,16 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X, 03000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c62400002b89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000853200008906000000010000,Nacon Revolution X Unlimited,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000632500007505000000020000,NeoGeo mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X, 03000000921200004b46000003020000,NES 2-port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Mac OS X, 030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Mac OS X, +030000007e0500006920000001010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Mac OS X, 030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 030000007e0500000920000010020000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:Mac OS X, 050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:Mac OS X, +030000007e0500007320000001010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Mac OS X, 030000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Mac OS X, 030000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Mac OS X, 03000000550900001472000025050000,NVIDIA Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X, @@ -1481,6 +1487,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, 03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux, +030000007e0500006920000011010000,Nintendo Switch 2 Pro Controller,a:b0,b:b1,back:b14,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,leftstick:b15,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,paddle1:b18,paddle2:b19,rightshoulder:b4,rightstick:b7,righttrigger:b5,rightx:a2,righty:a3~,start:b6,x:b2,y:b3,platform:Linux, 060000004e696e74656e646f20537700,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, @@ -1495,6 +1502,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 050000005a1d00000218000003000000,Nokia GC 5000,a:b9,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, +030000007e0500007320000011010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Linux, 030000007e0500001920000011810000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux, 050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux, 050000007e0500001920000001800000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux, @@ -1607,6 +1615,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800006100000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux, +030000009b2800006400000001010000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Linux, 030000009b2800008000000020020000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux, 030000009b2800008000000001010000,Raphnet Wii Classic Adapter V3,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Linux, 03000000f8270000bf0b000011010000,Razer Kishi,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, @@ -2122,6 +2131,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, 05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, 05000000ac05000004000000a8986d04,8BitDo Micro gamepad,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,lefttrigger:b12,rightshoulder:b13,righttrigger:b14,start:b3,x:b6,y:b5,platform:iOS, +05000000ac05000004000000fd216d04,8BitDo Pro 2,a:b3,b:b2,back:b6,dpdown:b9,dpleft:b10,dpright:b11,dpup:b12,guide:b4,leftshoulder:b13,leftstick:b14,lefttrigger:+a2,leftx:a0,lefty:a1~,paddle1:b1,paddle2:b0,rightshoulder:b16,rightstick:b17,righttrigger:+a5,rightx:a3,righty:a4~,start:b5,x:b8,y:b7,platform:iOS, +05000000ac05000004000000209f6d04,8Bitdo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,platform:iOS, 05000000ac050000040000003b8a6d04,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,platform:iOS, 050000008a35000003010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 050000008a35000004010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, @@ -2129,11 +2140,12 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS, 050000007e050000062000000f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,platform:iOS, 050000007e050000062000004f060000,Nintendo Switch Joy-Con (L),+leftx:h0.1,+lefty:h0.2,-leftx:h0.4,-lefty:h0.8,dpdown:b2,dpleft:b0,dpright:b3,dpup:b1,leftshoulder:b4,misc1:b6,rightshoulder:b5,platform:iOS, -050000007e05000008200000df070000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000007e05000008200000df070000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:iOS, 050000007e0500000e200000df070000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:iOS, -050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+rightx:h0.4,+righty:h0.8,-rightx:h0.1,-righty:h0.2,a:b1,b:b0,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b3,y:b2,platform:iOS, +050000007e050000072000000f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,platform:iOS, +050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,platform:iOS, 050000007e05000009200000df870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:iOS, -050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,platform:iOS, 050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, 050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, @@ -2145,9 +2157,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS, -050000005e040000050b0000df070001,Xbox Elite Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, -050000005e040000050b0000ff070001,Xbox Elite Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, -050000005e040000e0020000df070000,Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, -050000005e040000e0020000ff070000,Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, -050000005e040000130b0000df870001,Xbox Series Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, -050000005e040000130b0000ff870001,Xbox Series Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000005e040000050b0000df070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000005e040000130b0000df870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000005e040000130b0000ff870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, +050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS, +050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, From 560f769c03bdd32f9a2a10a2f2fee5e68709b5da Mon Sep 17 00:00:00 2001 From: "cla.grisenti" <91843204+clagrisenti@users.noreply.github.com> Date: Sun, 29 Jun 2025 22:39:05 +0200 Subject: [PATCH 08/18] Assert - added missing macros (#3968) Compilation with the NO_ASSERT flag set results in errors. This happens because some the macros are not defined in the else branch of #ifndef NO_ASSERT. --- common/util/Assert.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/util/Assert.h b/common/util/Assert.h index 1ed1866ef3..7369a8f30d 100644 --- a/common/util/Assert.h +++ b/common/util/Assert.h @@ -43,5 +43,8 @@ #define ASSERT(EX) ((void)0) #define ASSERT_MSG(EXPR, STR) ((void)0) +#define ASSERT_NOT_REACHED() ((void)0) +#define ASSERT_NOT_REACHED_MSG(STR) ((void)0) +#define ASSERT_EQ_IMM(EXPR, EXPECTED) ((void)0) #endif From ce23af2cb20437c8633bbb3b453851f29715e00d Mon Sep 17 00:00:00 2001 From: OpenGOAL Bot <99294829+OpenGOALBot@users.noreply.github.com> Date: Wed, 2 Jul 2025 22:20:55 -0400 Subject: [PATCH 09/18] CI: Periodic Controller Database Update (#3973) Updating Controller Database Co-authored-by: OpenGOALBot --- game/assets/sdl_controller_db.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/game/assets/sdl_controller_db.txt b/game/assets/sdl_controller_db.txt index 66c198d1ff..8758aac8e8 100644 --- a/game/assets/sdl_controller_db.txt +++ b/game/assets/sdl_controller_db.txt @@ -137,13 +137,13 @@ 030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000000055000000000000,Betop BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000790000000700000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, +03000000808300000300000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000006321000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, -03000000790000000700000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, -03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 030000006f0e00006401000000000000,BF One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows, 03000000300f00000202000000000000,Bigben,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a5,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 030000006b1400000209000000000000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, @@ -231,7 +231,7 @@ 03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, -03000000ac0500001a06000000000000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000ac0500001a06000000000000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 0300000047530000616d000000000000,GameStop,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -891,8 +891,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00001630000001000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001730000001000000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001130000000020000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000c82d00001330000000020000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001330000001000000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, -03000000c82d00001330000000020000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000a00500003232000009010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X, @@ -930,7 +930,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000b40400001124000001040000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000b40400001224000003030000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000790000004618000000010000,GameCube Controller Adapter,a:b4,b:b0,dpdown:b56,dpleft:b60,dpright:b52,dpup:b48,lefttrigger:a12,leftx:a0,lefty:a4,rightshoulder:b28,righttrigger:a16,rightx:a20,righty:a8,start:b36,x:b8,y:b12,platform:Mac OS X, -03000000ac0500001a06000002020000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000ac0500001a06000002020000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +03000000373500000411000023000000,GameSir X4A Xbox Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 03000000ad1b000001f9000000000000,Gamestop BB070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X, 03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Mac OS X, @@ -1210,10 +1211,10 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000c82d00001730000011010000,8BitDo Ultimate C,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001130000011010000,8BitDo Ultimate Wired,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000631000010010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +03000000c82d00000631000014010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c82d00000760000011010000,8BitDo Ultimate Wireless,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00001230000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001330000011010000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, -03000000c82d00000631000014010000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c82d00000121000011010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000c82d00000121000000010000,8BitDo Xbox One SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, @@ -1302,8 +1303,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000ac0500007a05000011010000,GameSir G5,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000373500009710000001020000,GameSir Kaleid Flux,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000ac0500001a06000011010000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, -03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -2130,7 +2131,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS, 05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, 05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS, -05000000ac05000004000000a8986d04,8BitDo Micro gamepad,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,lefttrigger:b12,rightshoulder:b13,righttrigger:b14,start:b3,x:b6,y:b5,platform:iOS, +05000000ac05000004000000a8986d04,8BitDo Micro,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,lefttrigger:b12,rightshoulder:b13,righttrigger:b14,start:b3,x:b6,y:b5,platform:iOS, 05000000ac05000004000000fd216d04,8BitDo Pro 2,a:b3,b:b2,back:b6,dpdown:b9,dpleft:b10,dpright:b11,dpup:b12,guide:b4,leftshoulder:b13,leftstick:b14,lefttrigger:+a2,leftx:a0,lefty:a1~,paddle1:b1,paddle2:b0,rightshoulder:b16,rightstick:b17,righttrigger:+a5,rightx:a3,righty:a4~,start:b5,x:b8,y:b7,platform:iOS, 05000000ac05000004000000209f6d04,8Bitdo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,platform:iOS, 05000000ac050000040000003b8a6d04,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,platform:iOS, From ac7ccd960d2fb6b1ef344d8232a1d04689212ba8 Mon Sep 17 00:00:00 2001 From: tripp <86533397+trippjoe@users.noreply.github.com> Date: Wed, 2 Jul 2025 22:21:17 -0400 Subject: [PATCH 10/18] optional linting: only fetch master branch (#3972) --- .github/workflows/linting.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml index cf4c7136d6..21d8673130 100644 --- a/.github/workflows/linting.yaml +++ b/.github/workflows/linting.yaml @@ -67,6 +67,6 @@ jobs: - name: Check for Removed goal_src/ Code # FYI - if you run this `git diff` on windows, it creates a utf-16 LE file run: | - git fetch origin + git fetch origin master git diff origin/master > lint-changes.diff python ./scripts/ci/lint-gsrc-removals.py From a0a4ec7df51bad696196ca8403b75847c6ee66d5 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Wed, 2 Jul 2025 22:44:02 -0400 Subject: [PATCH 11/18] game: fix level select for untranslated languages and fix infinite recursion edge-case in `lookup-text!` (#3969) The main bug this fixes is not being able to use level select when your language isn't translated. Why? Because they use the result from `lookup-text!` to determine if a menu item should be drawn or not. No text found, no menu item. However this uncovered a long-standing bug in my fallback extension to this code. If you call this function with a text-id that doesnt even have an english string, it will recursively keep calling itself until it crashes. Of course the first few tasks in the game are dummies and have no valid text-id so this had to be fixed. Should be fixed for all 3 games. --- goal_src/jak1/engine/ui/text.gc | 36 ++++++++++++++++++++++++--------- goal_src/jak2/engine/ui/text.gc | 31 +++++++++++++++++++++------- goal_src/jak3/engine/ui/text.gc | 33 ++++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 25 deletions(-) diff --git a/goal_src/jak1/engine/ui/text.gc b/goal_src/jak1/engine/ui/text.gc index b0e71517d2..0ffe5c17b2 100644 --- a/goal_src/jak1/engine/ui/text.gc +++ b/goal_src/jak1/engine/ui/text.gc @@ -67,10 +67,10 @@ (+! (-> arg0 data 80 total) (logand -16 (+ v1-18 15))))) this) -(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol)) - "Look up text by ID. Will return the string. - If the ID can't be found, and arg1 is #t, it will return #f, - otherwise the temp string UNKNOWN ID " +;; og:preserve-this extracted implementation out so that callers of `lookup-text!` were uneffected +;; this implementation is different from the original (has fallback text lookup) +(define-extern lookup-text-impl! (function game-text-info text-id symbol symbol string)) +(defun lookup-text-impl! ((this game-text-info) (arg0 text-id) (arg1 symbol) (fallback-call? symbol)) ;; binary search for it (let* ((a1-1 0) ;; min (a3-0 (+ (-> this length) 1)) ;; max @@ -88,19 +88,35 @@ (cond ((!= (-> this data v1-2 id) arg0) ;; didn't find it :( (cond - (arg1 (the-as string #f)) - (else - ;; First, look up the id in the fallback + (arg1 + ;; og:preserve-this Added fallback to english is string is not found. (#if PC_PORT - (if *fallback-text-lookup?* - (let ((fallback-result (lookup-text! *fallback-text* arg0 #t))) - (if (!= fallback-result #f) fallback-result (string-format "UNKNOWN ID ~D" arg0))) + (if (and *fallback-text-lookup?* (not fallback-call?)) + (aif (lookup-text-impl! *fallback-text* arg0 #t #t) + it + (the-as string #f)) + (the-as string #f)) + (the-as string #f))) + (else + ;; og:preserve-this Added fallback to english is string is not found. + (#if PC_PORT + (if (and *fallback-text-lookup?* (not fallback-call?)) + (aif (lookup-text-impl! *fallback-text* arg0 #t #t) + it + (string-format "UNKNOWN ID ~D" arg0)) (string-format "UNKNOWN ID ~D" arg0)) (string-format "UNKNOWN ID ~D" arg0))))) (else (-> this data v1-2 text) ;; found it! )))) +(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol)) + "Look up text by ID. Will return the string. + If the ID can't be found, and arg1 is #t, it will return #f, + otherwise the temp string UNKNOWN ID " + ;; og:preserve-this call custom function + (lookup-text-impl! this arg0 arg1 #f)) + ;; Game text loading. ;; The implementation of loading is blocking. ;; If you change languages, the game will freeze for a second while it loads diff --git a/goal_src/jak2/engine/ui/text.gc b/goal_src/jak2/engine/ui/text.gc index da6ae40df3..6b00ab1ec7 100644 --- a/goal_src/jak2/engine/ui/text.gc +++ b/goal_src/jak2/engine/ui/text.gc @@ -160,7 +160,10 @@ ) ) -(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol)) +;; og:preserve-this extracted implementation out so that callers of `lookup-text!` were uneffected +;; this implementation is different from the original (has fallback text lookup) +(define-extern lookup-text-impl! (function game-text-info text-id symbol symbol string)) +(defun lookup-text-impl! ((this game-text-info) (arg0 text-id) (arg1 symbol) (fallback-call? symbol)) (cond ((= this #f) (cond @@ -192,15 +195,23 @@ ((!= (-> this data v1-2 id) arg0) (cond (arg1 - (the-as string #f) + ;; og:preserve-this Added fallback to english is string is not found. + (#if PC_PORT + (if (and *fallback-text-lookup?* (not fallback-call?)) + (aif (lookup-text-impl! *fallback-text* arg0 #t #t) + it + (the-as string #f)) + (the-as string #f)) + (the-as string #f)) ) (else ;; og:preserve-this Added fallback to english is string is not found. (#if PC_PORT - (if *fallback-text-lookup?* - (aif (lookup-text! *fallback-text* arg0 #t) + (if (and *fallback-text-lookup?* (not fallback-call?)) + (aif (lookup-text-impl! *fallback-text* arg0 #t #t) it - (string-format "UNKNOWN ID ~D" arg0))) + (string-format "UNKNOWN ID ~D" arg0)) + (string-format "UNKNOWN ID ~D" arg0)) (string-format "UNKNOWN ID ~D" arg0)) ) ) @@ -214,8 +225,14 @@ ) ) ) - ) - ) + )) + +(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol)) + "Look up text by ID. Will return the string. + If the ID can't be found, and arg1 is #t, it will return #f, + otherwise the temp string UNKNOWN ID " + ;; og:preserve-this call custom function + (lookup-text-impl! this arg0 arg1 #f)) (defmethod lookup-text ((this level) (arg0 text-id) (arg1 symbol)) (let ((v1-0 *common-text*)) diff --git a/goal_src/jak3/engine/ui/text.gc b/goal_src/jak3/engine/ui/text.gc index b711477fec..dd57e00de8 100644 --- a/goal_src/jak3/engine/ui/text.gc +++ b/goal_src/jak3/engine/ui/text.gc @@ -159,7 +159,10 @@ ) ) -(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol)) +;; og:preserve-this extracted implementation out so that callers of `lookup-text!` were uneffected +;; this implementation is different from the original (has fallback text lookup) +(define-extern lookup-text-impl! (function game-text-info text-id symbol symbol string)) +(defun lookup-text-impl! ((this game-text-info) (arg0 text-id) (arg1 symbol) (fallback-call? symbol)) (cond ((= this #f) (cond @@ -191,15 +194,23 @@ ((!= (-> this data v1-2 id) arg0) (cond (arg1 - (the-as string #f) + ;; og:preserve-this Added fallback to english is string is not found. + (#if PC_PORT + (if (and *fallback-text-lookup?* (not fallback-call?)) + (aif (lookup-text-impl! *fallback-text* arg0 #t #t) + it + (the-as string #f)) + (the-as string #f)) + (the-as string #f)) ) (else - ;; og:preserve-this Added fallback to English if string is not found. + ;; og:preserve-this Added fallback to english is string is not found. (#if PC_PORT - (if *fallback-text-lookup?* - (aif (lookup-text! *fallback-text* arg0 #t) + (if (and *fallback-text-lookup?* (not fallback-call?)) + (aif (lookup-text-impl! *fallback-text* arg0 #t #t) it - (string-format "UNKNOWN ID ~D" arg0))) + (string-format "UNKNOWN ID ~D" arg0)) + (string-format "UNKNOWN ID ~D" arg0)) (string-format "UNKNOWN ID ~D" arg0)) ) ) @@ -213,8 +224,14 @@ ) ) ) - ) - ) + )) + +(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol)) + "Look up text by ID. Will return the string. + If the ID can't be found, and arg1 is #t, it will return #f, + otherwise the temp string UNKNOWN ID " + ;; og:preserve-this call custom function + (lookup-text-impl! this arg0 arg1 #f)) (defmethod lookup-text ((this level) (arg0 text-id) (arg1 symbol)) (let ((v1-0 *common-text*)) From 2d64108af5fa0b64c8d8a7630af5cbdc97ff58fd Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Wed, 2 Jul 2025 22:57:57 -0400 Subject: [PATCH 12/18] display: be more generous when filtering resolutions by refresh rate (#3974) Some monitors are very specific about their reported refresh rates: ``` [54:37] [debug] [DISPLAY]: Skipping 640x480 as it requires 360.11hz but the monitor is currently set to 360hz ``` The current code truncated the display mode, but would compare against the reported refresh rate. As per the log, they are obviously not equal. - Retain the float component and only round it off when sending the value to GOAL - Make the comparison more generous, +/- 1.0hz --- game/system/hid/display_manager.cpp | 9 ++++++--- game/system/hid/display_manager.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/game/system/hid/display_manager.cpp b/game/system/hid/display_manager.cpp index 23d57d9863..c2072dcbe1 100644 --- a/game/system/hid/display_manager.cpp +++ b/game/system/hid/display_manager.cpp @@ -1,5 +1,8 @@ #include "display_manager.h" +#include +#include + #include "sdl_util.h" #include "common/global_profiler/GlobalProfiler.h" @@ -160,7 +163,7 @@ std::string DisplayManager::get_connected_display_name(int id) { int DisplayManager::get_active_display_refresh_rate() { const auto display_index = get_active_display_index(); if (m_current_display_modes.size() > display_index) { - return m_current_display_modes.at(display_index).refresh_rate; + return round(m_current_display_modes.at(display_index).refresh_rate); } return 0; } @@ -450,7 +453,7 @@ void DisplayManager::update_video_modes() { } DisplayMode new_mode = {display_id, display_name_str, curr_mode->format, - curr_mode->w, curr_mode->h, (int)curr_mode->refresh_rate, + curr_mode->w, curr_mode->h, curr_mode->refresh_rate, orient}; m_current_display_modes.push_back(new_mode); lg::info( @@ -492,7 +495,7 @@ void DisplayManager::update_resolutions() { // Skip resolutions that aren't using the current refresh rate, they won't work. // For example if your monitor is currently set to `60hz` and the monitor _could_ support // resolution X but only at `30hz`...then there's no reason for us to consider it as an option. - if (display_mode->refresh_rate != active_refresh_rate) { + if (std::abs(display_mode->refresh_rate - active_refresh_rate) < 1.0) { lg::debug( "[DISPLAY]: Skipping {}x{} as it requires {}hz but the monitor is currently set to {}hz", display_mode->w, display_mode->h, display_mode->refresh_rate, active_refresh_rate); diff --git a/game/system/hid/display_manager.h b/game/system/hid/display_manager.h index a7d2803f12..c5077fd62f 100644 --- a/game/system/hid/display_manager.h +++ b/game/system/hid/display_manager.h @@ -30,7 +30,7 @@ struct DisplayMode { int screen_width; int screen_height; /// refresh rate (in Hz), or 0 for unspecified - int refresh_rate; + float refresh_rate; Orientation orientation; }; From 012ff7bb161c19db4c8bf1f8df0bc81b41afda89 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Wed, 2 Jul 2025 23:07:05 -0400 Subject: [PATCH 13/18] deps: update to SDL 3.2.16 (#3975) --- third-party/SDL/CMakeLists.txt | 2 +- .../SDL/Xcode/SDL/Info-Framework.plist | 4 +- .../Xcode/SDL/SDL.xcodeproj/project.pbxproj | 8 +- .../SDL/Xcode/SDL/pkg-support/SDL.info | 2 +- .../android-project/app/proguard-rules.pro | 2 + .../main/java/org/libsdl/app/SDLActivity.java | 41 +- third-party/SDL/docs/README-platforms.md | 2 +- third-party/SDL/include/SDL3/SDL.h | 2 +- third-party/SDL/include/SDL3/SDL_hints.h | 4 +- third-party/SDL/include/SDL3/SDL_init.h | 2 +- third-party/SDL/include/SDL3/SDL_pixels.h | 2 +- third-party/SDL/include/SDL3/SDL_stdinc.h | 4 +- third-party/SDL/include/SDL3/SDL_surface.h | 5 +- third-party/SDL/include/SDL3/SDL_version.h | 2 +- third-party/SDL/src/SDL_internal.h | 6 + third-party/SDL/src/audio/SDL_audio.c | 17 +- .../audio/emscripten/SDL_emscriptenaudio.c | 2 +- .../SDL/src/audio/pulseaudio/SDL_pulseaudio.c | 3 +- .../camera/emscripten/SDL_camera_emscripten.c | 2 +- .../SDL/src/core/android/SDL_android.c | 74 +--- third-party/SDL/src/core/windows/version.rc | 8 +- .../src/dialog/windows/SDL_windowsdialog.c | 8 +- third-party/SDL/src/events/SDL_events.c | 32 +- third-party/SDL/src/events/SDL_mouse.c | 12 +- third-party/SDL/src/gpu/SDL_gpu.c | 397 ++++++++++++++++-- third-party/SDL/src/gpu/SDL_sysgpu.h | 55 ++- third-party/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c | 330 ++++++++------- third-party/SDL/src/gpu/metal/SDL_gpu_metal.m | 135 +++--- .../SDL/src/gpu/vulkan/SDL_gpu_vulkan.c | 184 ++++---- third-party/SDL/src/joystick/SDL_gamepad.c | 3 + third-party/SDL/src/joystick/SDL_joystick.c | 30 +- .../src/joystick/hidapi/SDL_hidapijoystick.c | 10 +- .../joystick/windows/SDL_rawinputjoystick.c | 2 +- .../SDL/src/render/ps2/SDL_render_ps2.c | 2 +- third-party/SDL/src/storage/SDL_storage.c | 3 + third-party/SDL/src/storage/SDL_sysstorage.h | 1 + third-party/SDL/src/tray/unix/SDL_tray.c | 2 +- third-party/SDL/src/video/SDL_sysvideo.h | 3 +- third-party/SDL/src/video/SDL_video.c | 13 +- .../SDL/src/video/cocoa/SDL_cocoaclipboard.m | 11 + .../SDL/src/video/cocoa/SDL_cocoamouse.m | 10 +- .../SDL/src/video/cocoa/SDL_cocoavideo.m | 4 - .../SDL/src/video/cocoa/SDL_cocoawindow.m | 17 + .../video/emscripten/SDL_emscriptenvideo.c | 2 +- .../SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c | 13 +- third-party/SDL/src/video/psp/SDL_pspvideo.c | 2 + .../SDL/src/video/vita/SDL_vitavideo.c | 2 + .../SDL/src/video/vita/SDL_vitavideo.h | 2 - .../SDL/src/video/wayland/SDL_waylandevents.c | 30 +- .../src/video/wayland/SDL_waylandevents_c.h | 13 +- .../src/video/wayland/SDL_waylandkeyboard.c | 44 +- .../src/video/wayland/SDL_waylandkeyboard.h | 3 +- .../SDL/src/video/wayland/SDL_waylandvideo.c | 4 - .../SDL/src/video/windows/SDL_windowsvideo.c | 4 - third-party/SDL/src/video/x11/SDL_x11dyn.h | 3 + .../SDL/src/video/x11/SDL_x11keyboard.c | 4 +- third-party/SDL/src/video/x11/SDL_x11pen.c | 22 +- third-party/SDL/src/video/x11/SDL_x11video.c | 32 +- third-party/SDL/src/video/x11/SDL_x11window.c | 6 + vendor.yaml | 2 +- 60 files changed, 1071 insertions(+), 575 deletions(-) diff --git a/third-party/SDL/CMakeLists.txt b/third-party/SDL/CMakeLists.txt index 2b9c768847..1c120a5900 100644 --- a/third-party/SDL/CMakeLists.txt +++ b/third-party/SDL/CMakeLists.txt @@ -5,7 +5,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) endif() # See docs/release_checklist.md -project(SDL3 LANGUAGES C VERSION "3.2.14") +project(SDL3 LANGUAGES C VERSION "3.2.16") if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) set(SDL3_MAINPROJECT ON) diff --git a/third-party/SDL/Xcode/SDL/Info-Framework.plist b/third-party/SDL/Xcode/SDL/Info-Framework.plist index 5c988e48b1..2f0338d685 100644 --- a/third-party/SDL/Xcode/SDL/Info-Framework.plist +++ b/third-party/SDL/Xcode/SDL/Info-Framework.plist @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.2.14 + 3.2.16 CFBundleSignature SDLX CFBundleVersion - 3.2.14 + 3.2.16 diff --git a/third-party/SDL/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/third-party/SDL/Xcode/SDL/SDL.xcodeproj/project.pbxproj index b5e5608c04..5a5d205290 100644 --- a/third-party/SDL/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/third-party/SDL/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -3086,7 +3086,7 @@ CLANG_ENABLE_OBJC_ARC = YES; DEPLOYMENT_POSTPROCESSING = YES; DYLIB_COMPATIBILITY_VERSION = 201.0.0; - DYLIB_CURRENT_VERSION = 201.14.0; + DYLIB_CURRENT_VERSION = 201.16.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_ALTIVEC_EXTENSIONS = YES; @@ -3121,7 +3121,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 3.2.14; + MARKETING_VERSION = 3.2.16; OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3; PRODUCT_NAME = SDL3; @@ -3150,7 +3150,7 @@ CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; DYLIB_COMPATIBILITY_VERSION = 201.0.0; - DYLIB_CURRENT_VERSION = 201.14.0; + DYLIB_CURRENT_VERSION = 201.16.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -3182,7 +3182,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 3.2.14; + MARKETING_VERSION = 3.2.16; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3; diff --git a/third-party/SDL/Xcode/SDL/pkg-support/SDL.info b/third-party/SDL/Xcode/SDL/pkg-support/SDL.info index 5edcd164df..6f42a55475 100644 --- a/third-party/SDL/Xcode/SDL/pkg-support/SDL.info +++ b/third-party/SDL/Xcode/SDL/pkg-support/SDL.info @@ -1,4 +1,4 @@ -Title SDL 3.2.14 +Title SDL 3.2.16 Version 1 Description SDL Library for macOS (http://www.libsdl.org) DefaultLocation /Library/Frameworks diff --git a/third-party/SDL/android-project/app/proguard-rules.pro b/third-party/SDL/android-project/app/proguard-rules.pro index 1eeb90e2c3..5f8ee6a25e 100644 --- a/third-party/SDL/android-project/app/proguard-rules.pro +++ b/third-party/SDL/android-project/app/proguard-rules.pro @@ -51,6 +51,8 @@ boolean supportsRelativeMouse(); int openFileDescriptor(java.lang.String, java.lang.String); boolean showFileDialog(java.lang.String[], boolean, boolean, int); + java.lang.String getPreferredLocales(); + java.lang.String formatLocale(java.util.Locale); } -keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager { diff --git a/third-party/SDL/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/third-party/SDL/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 33203d3d8a..361688d68e 100644 --- a/third-party/SDL/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/third-party/SDL/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -23,6 +23,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.os.LocaleList; import android.os.Message; import android.os.ParcelFileDescriptor; import android.util.DisplayMetrics; @@ -60,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh private static final String TAG = "SDL"; private static final int SDL_MAJOR_VERSION = 3; private static final int SDL_MINOR_VERSION = 2; - private static final int SDL_MICRO_VERSION = 14; + private static final int SDL_MICRO_VERSION = 16; /* // Display InputType.SOURCE/CLASS of events and devices // @@ -2116,6 +2117,44 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh int requestCode; boolean multipleChoice; } + + /** + * This method is called by SDL using JNI. + */ + public static String getPreferredLocales() { + String result = ""; + if (Build.VERSION.SDK_INT >= 24 /* Android 7 (N) */) { + LocaleList locales = LocaleList.getAdjustedDefault(); + for (int i = 0; i < locales.size(); i++) { + if (i != 0) result += ","; + result += formatLocale(locales.get(i)); + } + } else if (mCurrentLocale != null) { + result = formatLocale(mCurrentLocale); + } + return result; + } + + public static String formatLocale(Locale locale) { + String result = ""; + String lang = ""; + if (locale.getLanguage() == "in") { + // Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility + lang = "id"; + } else if (locale.getLanguage() == "") { + // Make sure language is never empty + lang = "und"; + } else { + lang = locale.getLanguage(); + } + + if (locale.getCountry() == "") { + result = lang; + } else { + result = lang + "_" + locale.getCountry(); + } + return result; + } } /** diff --git a/third-party/SDL/docs/README-platforms.md b/third-party/SDL/docs/README-platforms.md index 77ae411d27..46a054a8ae 100644 --- a/third-party/SDL/docs/README-platforms.md +++ b/third-party/SDL/docs/README-platforms.md @@ -11,7 +11,7 @@ - [macOS](README-macos.md) - [NetBSD](README-bsd.md) - [Nintendo Switch](README-switch.md) -- [Nintendo 3DS](README-3ds.md) +- [Nintendo 3DS](README-n3ds.md) - [OpenBSD](README-bsd.md) - [PlayStation 2](README-ps2.md) - [PlayStation 4](README-ps4.md) diff --git a/third-party/SDL/include/SDL3/SDL.h b/third-party/SDL/include/SDL3/SDL.h index a8eb7aeedf..ed1b32483a 100644 --- a/third-party/SDL/include/SDL3/SDL.h +++ b/third-party/SDL/include/SDL3/SDL.h @@ -20,7 +20,7 @@ */ /** - * Main include header for the SDL library, version 3.2.14 + * Main include header for the SDL library, version 3.2.16 * * It is almost always best to include just this one header instead of * picking out individual headers included here. There are exceptions to diff --git a/third-party/SDL/include/SDL3/SDL_hints.h b/third-party/SDL/include/SDL3/SDL_hints.h index 89fc545d43..a081535716 100644 --- a/third-party/SDL/include/SDL3/SDL_hints.h +++ b/third-party/SDL/include/SDL3/SDL_hints.h @@ -2026,8 +2026,8 @@ extern "C" { * * The variable can be set to the following values: * - * - "0": RAWINPUT drivers are not used. - * - "1": RAWINPUT drivers are used. (default) + * - "0": RAWINPUT drivers are not used. (default) + * - "1": RAWINPUT drivers are used. * * This hint should be set before SDL is initialized. * diff --git a/third-party/SDL/include/SDL3/SDL_init.h b/third-party/SDL/include/SDL3/SDL_init.h index adf0de8a21..27ebe4b0ed 100644 --- a/third-party/SDL/include/SDL3/SDL_init.h +++ b/third-party/SDL/include/SDL3/SDL_init.h @@ -79,7 +79,7 @@ typedef Uint32 SDL_InitFlags; #define SDL_INIT_AUDIO 0x00000010u /**< `SDL_INIT_AUDIO` implies `SDL_INIT_EVENTS` */ #define SDL_INIT_VIDEO 0x00000020u /**< `SDL_INIT_VIDEO` implies `SDL_INIT_EVENTS`, should be initialized on the main thread */ -#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS`, should be initialized on the same thread as SDL_INIT_VIDEO on Windows if you don't set SDL_HINT_JOYSTICK_THREAD */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< `SDL_INIT_JOYSTICK` implies `SDL_INIT_EVENTS` */ #define SDL_INIT_HAPTIC 0x00001000u #define SDL_INIT_GAMEPAD 0x00002000u /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */ #define SDL_INIT_EVENTS 0x00004000u diff --git a/third-party/SDL/include/SDL3/SDL_pixels.h b/third-party/SDL/include/SDL3/SDL_pixels.h index 4127ac06c7..39596c1c98 100644 --- a/third-party/SDL/include/SDL3/SDL_pixels.h +++ b/third-party/SDL/include/SDL3/SDL_pixels.h @@ -517,7 +517,7 @@ typedef enum SDL_PackedLayout * ABGR32, define a platform-independent encoding into bytes in the order * specified. For example, in RGB24 data, each pixel is encoded in 3 bytes * (red, green, blue) in that order, and in ABGR32 data, each pixel is - * encoded in 4 bytes alpha, blue, green, red) in that order. Use these + * encoded in 4 bytes (alpha, blue, green, red) in that order. Use these * names if the property of a format that is important to you is the order * of the bytes in memory or on disk. * - Names with a bit count per component, such as ARGB8888 and XRGB1555, are diff --git a/third-party/SDL/include/SDL3/SDL_stdinc.h b/third-party/SDL/include/SDL3/SDL_stdinc.h index 8c547477ed..7df253fece 100644 --- a/third-party/SDL/include/SDL3/SDL_stdinc.h +++ b/third-party/SDL/include/SDL3/SDL_stdinc.h @@ -4656,7 +4656,7 @@ extern SDL_DECLSPEC float SDLCALL SDL_atanf(float x); * * Domain: `-INF <= x <= INF`, `-INF <= y <= INF` * - * Range: `-Pi/2 <= y <= Pi/2` + * Range: `-Pi <= y <= Pi` * * This function operates on double-precision floating point values, use * SDL_atan2f for single-precision floats. @@ -4692,7 +4692,7 @@ extern SDL_DECLSPEC double SDLCALL SDL_atan2(double y, double x); * * Domain: `-INF <= x <= INF`, `-INF <= y <= INF` * - * Range: `-Pi/2 <= y <= Pi/2` + * Range: `-Pi <= y <= Pi` * * This function operates on single-precision floating point values, use * SDL_atan2 for double-precision floats. diff --git a/third-party/SDL/include/SDL3/SDL_surface.h b/third-party/SDL/include/SDL3/SDL_surface.h index be842fe38d..15fce042f7 100644 --- a/third-party/SDL/include/SDL3/SDL_surface.h +++ b/third-party/SDL/include/SDL3/SDL_surface.h @@ -1279,10 +1279,11 @@ extern SDL_DECLSPEC bool SDLCALL SDL_BlitSurfaceUncheckedScaled(SDL_Surface *src * * \param src the SDL_Surface structure to be copied from. * \param srcrect the SDL_Rect structure representing the rectangle to be - * copied, may not be NULL. + * copied, or NULL to copy the entire surface. * \param dst the SDL_Surface structure that is the blit target. * \param dstrect the SDL_Rect structure representing the target rectangle in - * the destination surface, may not be NULL. + * the destination surface, or NULL to fill the entire + * destination surface. * \param scaleMode the SDL_ScaleMode to be used. * \returns true on success or false on failure; call SDL_GetError() for more * information. diff --git a/third-party/SDL/include/SDL3/SDL_version.h b/third-party/SDL/include/SDL3/SDL_version.h index 2387fcff9c..435b3f95fe 100644 --- a/third-party/SDL/include/SDL3/SDL_version.h +++ b/third-party/SDL/include/SDL3/SDL_version.h @@ -62,7 +62,7 @@ extern "C" { * * \since This macro is available since SDL 3.2.0. */ -#define SDL_MICRO_VERSION 14 +#define SDL_MICRO_VERSION 16 /** * This macro turns the version numbers into a numeric value. diff --git a/third-party/SDL/src/SDL_internal.h b/third-party/SDL/src/SDL_internal.h index a345252f3a..8fcd96a7fa 100644 --- a/third-party/SDL/src/SDL_internal.h +++ b/third-party/SDL/src/SDL_internal.h @@ -265,6 +265,12 @@ extern "C" { #include "SDL_utils_c.h" #include "SDL_hashtable.h" +#define PUSH_SDL_ERROR() \ + { char *_error = SDL_strdup(SDL_GetError()); + +#define POP_SDL_ERROR() \ + SDL_SetError("%s", _error); SDL_free(_error); } + // Do any initialization that needs to happen before threads are started extern void SDL_InitMainThread(void); diff --git a/third-party/SDL/src/audio/SDL_audio.c b/third-party/SDL/src/audio/SDL_audio.c index 5ddf97876c..fbe6e22a39 100644 --- a/third-party/SDL/src/audio/SDL_audio.c +++ b/third-party/SDL/src/audio/SDL_audio.c @@ -1743,13 +1743,18 @@ static bool OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec SDL_copyp(&spec, inspec ? inspec : &device->default_spec); PrepareAudioFormat(device->recording, &spec); - /* We allow the device format to change if it's better than the current settings (by various definitions of "better"). This prevents - something low quality, like an old game using S8/8000Hz audio, from ruining a music thing playing at CD quality that tries to open later. - (or some VoIP library that opens for mono output ruining your surround-sound game because it got there first). + /* We impose a simple minimum on device formats. This prevents something low quality, like an old game using S8/8000Hz audio, + from ruining a music thing playing at CD quality that tries to open later, or some VoIP library that opens for mono output + ruining your surround-sound game because it got there first. These are just requests! The backend may change any of these values during OpenDevice method! */ - device->spec.format = (SDL_AUDIO_BITSIZE(device->default_spec.format) >= SDL_AUDIO_BITSIZE(spec.format)) ? device->default_spec.format : spec.format; - device->spec.freq = SDL_max(device->default_spec.freq, spec.freq); - device->spec.channels = SDL_max(device->default_spec.channels, spec.channels); + + const SDL_AudioFormat minimum_format = device->recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT; + const int minimum_channels = device->recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS; + const int minimum_freq = device->recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY; + + device->spec.format = (SDL_AUDIO_BITSIZE(minimum_format) >= SDL_AUDIO_BITSIZE(spec.format)) ? minimum_format : spec.format; + device->spec.channels = SDL_max(minimum_channels, spec.channels); + device->spec.freq = SDL_max(minimum_freq, spec.freq); device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq); SDL_UpdatedAudioDeviceFormat(device); // start this off sane. diff --git a/third-party/SDL/src/audio/emscripten/SDL_emscriptenaudio.c b/third-party/SDL/src/audio/emscripten/SDL_emscriptenaudio.c index 55fb5b49fc..46b8b7645b 100644 --- a/third-party/SDL/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/third-party/SDL/src/audio/emscripten/SDL_emscriptenaudio.c @@ -189,7 +189,7 @@ static bool EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *device) } // limit to native freq - device->spec.freq = EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; }); + device->spec.freq = MAIN_THREAD_EM_ASM_INT({ return Module['SDL3'].audioContext.sampleRate; }); device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq) * 2; // double the buffer size, some browsers need more, and we'll just have to live with the latency. SDL_UpdatedAudioDeviceFormat(device); diff --git a/third-party/SDL/src/audio/pulseaudio/SDL_pulseaudio.c b/third-party/SDL/src/audio/pulseaudio/SDL_pulseaudio.c index 69e8c1a84c..4d618a6e2b 100644 --- a/third-party/SDL/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/third-party/SDL/src/audio/pulseaudio/SDL_pulseaudio.c @@ -672,7 +672,8 @@ static bool PULSEAUDIO_OpenDevice(SDL_AudioDevice *device) paspec.rate = device->spec.freq; // Reduced prebuffering compared to the defaults. - paattr.fragsize = device->buffer_size; // despite the name, this is only used for recording devices, according to PulseAudio docs! + + paattr.fragsize = device->buffer_size * 2; // despite the name, this is only used for recording devices, according to PulseAudio docs! (times 2 because we want _more_ than our buffer size sent from the server at a time, which helps some drivers). paattr.tlength = device->buffer_size; paattr.prebuf = -1; paattr.maxlength = -1; diff --git a/third-party/SDL/src/camera/emscripten/SDL_camera_emscripten.c b/third-party/SDL/src/camera/emscripten/SDL_camera_emscripten.c index fa2a51144e..36418c57ab 100644 --- a/third-party/SDL/src/camera/emscripten/SDL_camera_emscripten.c +++ b/third-party/SDL/src/camera/emscripten/SDL_camera_emscripten.c @@ -61,7 +61,7 @@ static SDL_CameraFrameResult EMSCRIPTENCAMERA_AcquireFrame(SDL_Camera *device, S SDL3.camera.ctx2d.drawImage(SDL3.camera.video, 0, 0, w, h); const imgrgba = SDL3.camera.ctx2d.getImageData(0, 0, w, h).data; - Module.HEAPU8.set(imgrgba, rgba); + HEAPU8.set(imgrgba, rgba); return 1; }, device->actual_spec.width, device->actual_spec.height, rgba); diff --git a/third-party/SDL/src/core/android/SDL_android.c b/third-party/SDL/src/core/android/SDL_android.c index eb450979a2..1cc9ccdb4e 100644 --- a/third-party/SDL/src/core/android/SDL_android.c +++ b/third-party/SDL/src/core/android/SDL_android.c @@ -371,6 +371,7 @@ static jmethodID midShowTextInput; static jmethodID midSupportsRelativeMouse; static jmethodID midOpenFileDescriptor; static jmethodID midShowFileDialog; +static jmethodID midGetPreferredLocales; // audio manager static jclass mAudioManagerClass; @@ -660,6 +661,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z"); midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I"); midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z"); + midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;"); if (!midClipboardGetText || !midClipboardHasText || @@ -691,7 +693,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl !midShowTextInput || !midSupportsRelativeMouse || !midOpenFileDescriptor || - !midShowFileDialog) { + !midShowFileDialog || + !midGetPreferredLocales) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); } @@ -2585,65 +2588,22 @@ bool Android_JNI_ShowToast(const char *message, int duration, int gravity, int x bool Android_JNI_GetLocale(char *buf, size_t buflen) { - AConfiguration *cfg; - - SDL_assert(buflen > 6); - - // Need to re-create the asset manager if locale has changed (SDL_EVENT_LOCALE_CHANGED) - Internal_Android_Destroy_AssetManager(); - - if (!asset_manager) { - Internal_Android_Create_AssetManager(); - } - - if (!asset_manager) { - return false; - } - - cfg = AConfiguration_new(); - if (!cfg) { - return false; - } - - { - char language[2] = {}; - char country[2] = {}; - size_t id = 0; - - AConfiguration_fromAssetManager(cfg, asset_manager); - AConfiguration_getLanguage(cfg, language); - AConfiguration_getCountry(cfg, country); - - // Indonesian is "id" according to ISO 639.2, but on Android is "in" because of Java backwards compatibility - if (language[0] == 'i' && language[1] == 'n') { - language[1] = 'd'; - } - - // copy language (not null terminated) - if (language[0]) { - buf[id++] = language[0]; - if (language[1]) { - buf[id++] = language[1]; + bool result = false; + if (buf && buflen > 0) { + *buf = '\0'; + JNIEnv *env = Android_JNI_GetEnv(); + jstring string = (jstring)(*env)->CallStaticObjectMethod(env, mActivityClass, midGetPreferredLocales); + if (string) { + const char *utf8string = (*env)->GetStringUTFChars(env, string, NULL); + if (utf8string) { + result = true; + SDL_strlcpy(buf, utf8string, buflen); + (*env)->ReleaseStringUTFChars(env, string, utf8string); } + (*env)->DeleteLocalRef(env, string); } - - buf[id++] = '_'; - - // copy country (not null terminated) - if (country[0]) { - buf[id++] = country[0]; - if (country[1]) { - buf[id++] = country[1]; - } - } - - buf[id++] = '\0'; - SDL_assert(id <= buflen); } - - AConfiguration_delete(cfg); - - return true; + return result; } bool Android_JNI_OpenURL(const char *url) diff --git a/third-party/SDL/src/core/windows/version.rc b/third-party/SDL/src/core/windows/version.rc index ad9e934453..3492918f5e 100644 --- a/third-party/SDL/src/core/windows/version.rc +++ b/third-party/SDL/src/core/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,2,14,0 - PRODUCTVERSION 3,2,14,0 + FILEVERSION 3,2,16,0 + PRODUCTVERSION 3,2,16,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "3, 2, 14, 0\0" + VALUE "FileVersion", "3, 2, 16, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL3.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "3, 2, 14, 0\0" + VALUE "ProductVersion", "3, 2, 16, 0\0" END END BLOCK "VarFileInfo" diff --git a/third-party/SDL/src/dialog/windows/SDL_windowsdialog.c b/third-party/SDL/src/dialog/windows/SDL_windowsdialog.c index 6822944fc0..364753cfdf 100644 --- a/third-party/SDL/src/dialog/windows/SDL_windowsdialog.c +++ b/third-party/SDL/src/dialog/windows/SDL_windowsdialog.c @@ -261,7 +261,7 @@ void windows_ShowFileDialog(void *ptr) chosen_files_list[nfiles] = NULL; - if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) >= MAX_PATH) { + if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) == 0) { SDL_SetError("Path too long or invalid character in path"); SDL_free(chosen_files_list); callback(userdata, NULL, -1); @@ -273,7 +273,7 @@ void windows_ShowFileDialog(void *ptr) SDL_strlcpy(chosen_file, chosen_folder, MAX_PATH); chosen_file[chosen_folder_size] = '\\'; - file_ptr += SDL_strlen(chosen_folder) + 1; + file_ptr += SDL_wcslen(file_ptr) + 1; while (*file_ptr) { nfiles++; @@ -295,7 +295,7 @@ void windows_ShowFileDialog(void *ptr) int diff = ((int) chosen_folder_size) + 1; - if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) >= MAX_PATH - diff) { + if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) == 0) { SDL_SetError("Path too long or invalid character in path"); for (size_t i = 0; i < nfiles - 1; i++) { @@ -308,7 +308,7 @@ void windows_ShowFileDialog(void *ptr) return; } - file_ptr += SDL_strlen(chosen_file) + 1 - diff; + file_ptr += SDL_wcslen(file_ptr) + 1; chosen_files_list[nfiles - 1] = SDL_strdup(chosen_file); diff --git a/third-party/SDL/src/events/SDL_events.c b/third-party/SDL/src/events/SDL_events.c index eff205f71b..a151740524 100644 --- a/third-party/SDL/src/events/SDL_events.c +++ b/third-party/SDL/src/events/SDL_events.c @@ -1077,16 +1077,11 @@ static void SDL_SendWakeupEvent(void) return; } - SDL_LockMutex(_this->wakeup_lock); - { - if (_this->wakeup_window) { - _this->SendWakeupEvent(_this, _this->wakeup_window); - - // No more wakeup events needed until we enter a new wait - _this->wakeup_window = NULL; - } + // We only want to do this once while waiting for an event, so set it to NULL atomically here + SDL_Window *wakeup_window = (SDL_Window *)SDL_SetAtomicPointer(&_this->wakeup_window, NULL); + if (wakeup_window) { + _this->SendWakeupEvent(_this, wakeup_window); } - SDL_UnlockMutex(_this->wakeup_lock); #endif } @@ -1524,18 +1519,7 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu */ SDL_PumpEventsInternal(true); - SDL_LockMutex(_this->wakeup_lock); - { - status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); - // If status == 0 we are going to block so wakeup will be needed. - if (status == 0) { - _this->wakeup_window = wakeup_window; - } else { - _this->wakeup_window = NULL; - } - } - SDL_UnlockMutex(_this->wakeup_lock); - + status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); if (status < 0) { // Got an error: return break; @@ -1548,8 +1532,6 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu if (timeoutNS > 0) { Sint64 elapsed = SDL_GetTicksNS() - start; if (elapsed >= timeoutNS) { - // Set wakeup_window to NULL without holding the lock. - _this->wakeup_window = NULL; return 0; } loop_timeoutNS = (timeoutNS - elapsed); @@ -1562,9 +1544,9 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu loop_timeoutNS = poll_intervalNS; } } + SDL_SetAtomicPointer(&_this->wakeup_window, wakeup_window); status = _this->WaitEventTimeout(_this, loop_timeoutNS); - // Set wakeup_window to NULL without holding the lock. - _this->wakeup_window = NULL; + SDL_SetAtomicPointer(&_this->wakeup_window, NULL); if (status == 0 && poll_intervalNS != SDL_MAX_SINT64 && loop_timeoutNS == poll_intervalNS) { // We may have woken up to poll. Try again continue; diff --git a/third-party/SDL/src/events/SDL_mouse.c b/third-party/SDL/src/events/SDL_mouse.c index d84f5592ac..92f9913442 100644 --- a/third-party/SDL/src/events/SDL_mouse.c +++ b/third-party/SDL/src/events/SDL_mouse.c @@ -138,21 +138,25 @@ static void SDLCALL SDL_TouchMouseEventsChanged(void *userdata, const char *name #ifdef SDL_PLATFORM_VITA static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { + Uint8 vita_touch_mouse_device = 1; + SDL_Mouse *mouse = (SDL_Mouse *)userdata; if (hint) { switch (*hint) { - default: case '0': - mouse->vita_touch_mouse_device = 1; + vita_touch_mouse_device = 1; break; case '1': - mouse->vita_touch_mouse_device = 2; + vita_touch_mouse_device = 2; break; case '2': - mouse->vita_touch_mouse_device = 3; + vita_touch_mouse_device = 3; + break; + default: break; } } + mouse->vita_touch_mouse_device = vita_touch_mouse_device; } #endif diff --git a/third-party/SDL/src/gpu/SDL_gpu.c b/third-party/SDL/src/gpu/SDL_gpu.c index 34c99f5f96..e1ad66c00b 100644 --- a/third-party/SDL/src/gpu/SDL_gpu.c +++ b/third-party/SDL/src/gpu/SDL_gpu.c @@ -93,10 +93,10 @@ } \ } -#define CHECK_GRAPHICS_PIPELINE_BOUND \ - if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \ - SDL_assert_release(!"Graphics pipeline not bound!"); \ - return; \ +#define CHECK_GRAPHICS_PIPELINE_BOUND \ + if (!((RenderPass *)render_pass)->graphics_pipeline) { \ + SDL_assert_release(!"Graphics pipeline not bound!"); \ + return; \ } #define CHECK_COMPUTEPASS \ @@ -106,7 +106,7 @@ } #define CHECK_COMPUTE_PIPELINE_BOUND \ - if (!((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->compute_pipeline_bound) { \ + if (!((ComputePass *)compute_pass)->compute_pipeline) { \ SDL_assert_release(!"Compute pipeline not bound!"); \ return; \ } @@ -174,18 +174,132 @@ #define RENDERPASS_DEVICE \ ((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device +#define RENDERPASS_BOUND_PIPELINE \ + ((RenderPass *)render_pass)->graphics_pipeline + #define COMPUTEPASS_COMMAND_BUFFER \ ((Pass *)compute_pass)->command_buffer #define COMPUTEPASS_DEVICE \ ((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->device +#define COMPUTEPASS_BOUND_PIPELINE \ + ((ComputePass *)compute_pass)->compute_pipeline + #define COPYPASS_COMMAND_BUFFER \ ((Pass *)copy_pass)->command_buffer #define COPYPASS_DEVICE \ ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->device +static bool TextureFormatIsComputeWritable[] = { + false, // INVALID + false, // A8_UNORM + true, // R8_UNORM + true, // R8G8_UNORM + true, // R8G8B8A8_UNORM + true, // R16_UNORM + true, // R16G16_UNORM + true, // R16G16B16A16_UNORM + true, // R10G10B10A2_UNORM + false, // B5G6R5_UNORM + false, // B5G5R5A1_UNORM + false, // B4G4R4A4_UNORM + false, // B8G8R8A8_UNORM + false, // BC1_UNORM + false, // BC2_UNORM + false, // BC3_UNORM + false, // BC4_UNORM + false, // BC5_UNORM + false, // BC7_UNORM + false, // BC6H_FLOAT + false, // BC6H_UFLOAT + true, // R8_SNORM + true, // R8G8_SNORM + true, // R8G8B8A8_SNORM + true, // R16_SNORM + true, // R16G16_SNORM + true, // R16G16B16A16_SNORM + true, // R16_FLOAT + true, // R16G16_FLOAT + true, // R16G16B16A16_FLOAT + true, // R32_FLOAT + true, // R32G32_FLOAT + true, // R32G32B32A32_FLOAT + true, // R11G11B10_UFLOAT + true, // R8_UINT + true, // R8G8_UINT + true, // R8G8B8A8_UINT + true, // R16_UINT + true, // R16G16_UINT + true, // R16G16B16A16_UINT + true, // R32_UINT + true, // R32G32_UINT + true, // R32G32B32A32_UINT + true, // R8_INT + true, // R8G8_INT + true, // R8G8B8A8_INT + true, // R16_INT + true, // R16G16_INT + true, // R16G16B16A16_INT + true, // R32_INT + true, // R32G32_INT + true, // R32G32B32A32_INT + false, // R8G8B8A8_UNORM_SRGB + false, // B8G8R8A8_UNORM_SRGB + false, // BC1_UNORM_SRGB + false, // BC3_UNORM_SRGB + false, // BC3_UNORM_SRGB + false, // BC7_UNORM_SRGB + false, // D16_UNORM + false, // D24_UNORM + false, // D32_FLOAT + false, // D24_UNORM_S8_UINT + false, // D32_FLOAT_S8_UINT + false, // ASTC_4x4_UNORM + false, // ASTC_5x4_UNORM + false, // ASTC_5x5_UNORM + false, // ASTC_6x5_UNORM + false, // ASTC_6x6_UNORM + false, // ASTC_8x5_UNORM + false, // ASTC_8x6_UNORM + false, // ASTC_8x8_UNORM + false, // ASTC_10x5_UNORM + false, // ASTC_10x6_UNORM + false, // ASTC_10x8_UNORM + false, // ASTC_10x10_UNORM + false, // ASTC_12x10_UNORM + false, // ASTC_12x12_UNORM + false, // ASTC_4x4_UNORM_SRGB + false, // ASTC_5x4_UNORM_SRGB + false, // ASTC_5x5_UNORM_SRGB + false, // ASTC_6x5_UNORM_SRGB + false, // ASTC_6x6_UNORM_SRGB + false, // ASTC_8x5_UNORM_SRGB + false, // ASTC_8x6_UNORM_SRGB + false, // ASTC_8x8_UNORM_SRGB + false, // ASTC_10x5_UNORM_SRGB + false, // ASTC_10x6_UNORM_SRGB + false, // ASTC_10x8_UNORM_SRGB + false, // ASTC_10x10_UNORM_SRGB + false, // ASTC_12x10_UNORM_SRGB + false, // ASTC_12x12_UNORM_SRGB + false, // ASTC_4x4_FLOAT + false, // ASTC_5x4_FLOAT + false, // ASTC_5x5_FLOAT + false, // ASTC_6x5_FLOAT + false, // ASTC_6x6_FLOAT + false, // ASTC_8x5_FLOAT + false, // ASTC_8x6_FLOAT + false, // ASTC_8x8_FLOAT + false, // ASTC_10x5_FLOAT + false, // ASTC_10x6_FLOAT + false, // ASTC_10x8_FLOAT + false, // ASTC_10x10_FLOAT + false, // ASTC_12x10_FLOAT + false // ASTC_12x12_FLOAT +}; + // Drivers #ifndef SDL_GPU_DISABLED @@ -403,6 +517,73 @@ void SDL_GPU_BlitCommon( SDL_EndGPURenderPass(render_pass); } +static void SDL_GPU_CheckGraphicsBindings(SDL_GPURenderPass *render_pass) +{ + RenderPass *rp = (RenderPass *)render_pass; + GraphicsPipelineCommonHeader *pipeline = (GraphicsPipelineCommonHeader *)RENDERPASS_BOUND_PIPELINE; + for (Uint32 i = 0; i < pipeline->num_vertex_samplers; i += 1) { + if (!rp->vertex_sampler_bound[i]) { + SDL_assert_release(!"Missing vertex sampler binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_vertex_storage_textures; i += 1) { + if (!rp->vertex_storage_texture_bound[i]) { + SDL_assert_release(!"Missing vertex storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_vertex_storage_buffers; i += 1) { + if (!rp->vertex_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing vertex storage buffer binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_fragment_samplers; i += 1) { + if (!rp->fragment_sampler_bound[i]) { + SDL_assert_release(!"Missing fragment sampler binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_fragment_storage_textures; i += 1) { + if (!rp->fragment_storage_texture_bound[i]) { + SDL_assert_release(!"Missing fragment storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->num_fragment_storage_buffers; i += 1) { + if (!rp->fragment_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing fragment storage buffer binding!"); + } + } +} + +static void SDL_GPU_CheckComputeBindings(SDL_GPUComputePass *compute_pass) +{ + ComputePass *cp = (ComputePass *)compute_pass; + ComputePipelineCommonHeader *pipeline = (ComputePipelineCommonHeader *)COMPUTEPASS_BOUND_PIPELINE; + for (Uint32 i = 0; i < pipeline->numSamplers; i += 1) { + if (!cp->sampler_bound[i]) { + SDL_assert_release(!"Missing compute sampler binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadonlyStorageTextures; i += 1) { + if (!cp->read_only_storage_texture_bound[i]) { + SDL_assert_release(!"Missing compute readonly storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadonlyStorageBuffers; i += 1) { + if (!cp->read_only_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing compute readonly storage buffer binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) { + if (!cp->read_write_storage_texture_bound[i]) { + SDL_assert_release(!"Missing compute read-write storage texture binding!"); + } + } + for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) { + if (!cp->read_write_storage_buffer_bound[i]) { + SDL_assert_release(!"Missing compute read-write storage buffer bbinding!"); + } + } +} + // Driver Functions #ifndef SDL_GPU_DISABLED @@ -564,7 +745,6 @@ SDL_GPUDevice *SDL_CreateGPUDeviceWithProperties(SDL_PropertiesID props) result = selectedBackend->CreateDevice(debug_mode, preferLowPower, props); if (result != NULL) { result->backend = selectedBackend->name; - result->shader_formats = selectedBackend->shader_formats; result->debug_mode = debug_mode; } } @@ -753,6 +933,13 @@ bool SDL_GPUTextureSupportsFormat( CHECK_TEXTUREFORMAT_ENUM_INVALID(format, false) } + if ((usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE) || + (usage & SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE)) { + if (!TextureFormatIsComputeWritable[format]) { + return false; + } + } + return device->SupportsTextureFormat( device->driverData, format, @@ -1375,15 +1562,29 @@ SDL_GPUCommandBuffer *SDL_AcquireGPUCommandBuffer( commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; commandBufferHeader->device = device; commandBufferHeader->render_pass.command_buffer = command_buffer; - commandBufferHeader->render_pass.in_progress = false; - commandBufferHeader->graphics_pipeline_bound = false; commandBufferHeader->compute_pass.command_buffer = command_buffer; - commandBufferHeader->compute_pass.in_progress = false; - commandBufferHeader->compute_pipeline_bound = false; commandBufferHeader->copy_pass.command_buffer = command_buffer; - commandBufferHeader->copy_pass.in_progress = false; - commandBufferHeader->swapchain_texture_acquired = false; - commandBufferHeader->submitted = false; + + if (device->debug_mode) { + commandBufferHeader->render_pass.in_progress = false; + commandBufferHeader->render_pass.graphics_pipeline = NULL; + commandBufferHeader->compute_pass.in_progress = false; + commandBufferHeader->compute_pass.compute_pipeline = NULL; + commandBufferHeader->copy_pass.in_progress = false; + commandBufferHeader->swapchain_texture_acquired = false; + commandBufferHeader->submitted = false; + SDL_zeroa(commandBufferHeader->render_pass.vertex_sampler_bound); + SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_texture_bound); + SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_buffer_bound); + SDL_zeroa(commandBufferHeader->render_pass.fragment_sampler_bound); + SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_texture_bound); + SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_buffer_bound); + SDL_zeroa(commandBufferHeader->compute_pass.sampler_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_texture_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_buffer_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_texture_bound); + SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_buffer_bound); + } return command_buffer; } @@ -1501,30 +1702,47 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( if (color_target_infos[i].cycle && color_target_infos[i].load_op == SDL_GPU_LOADOP_LOAD) { SDL_assert_release(!"Cannot cycle color target when load op is LOAD!"); + return NULL; } if (color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE || color_target_infos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) { if (color_target_infos[i].resolve_texture == NULL) { SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but resolve_texture is NULL!"); + return NULL; } else { TextureCommonHeader *resolveTextureHeader = (TextureCommonHeader *)color_target_infos[i].resolve_texture; if (textureHeader->info.sample_count == SDL_GPU_SAMPLECOUNT_1) { SDL_assert_release(!"Store op is RESOLVE or RESOLVE_AND_STORE but texture is not multisample!"); + return NULL; } if (resolveTextureHeader->info.sample_count != SDL_GPU_SAMPLECOUNT_1) { SDL_assert_release(!"Resolve texture must have a sample count of 1!"); + return NULL; } if (resolveTextureHeader->info.format != textureHeader->info.format) { SDL_assert_release(!"Resolve texture must have the same format as its corresponding color target!"); + return NULL; } if (resolveTextureHeader->info.type == SDL_GPU_TEXTURETYPE_3D) { SDL_assert_release(!"Resolve texture must not be of TEXTURETYPE_3D!"); + return NULL; } if (!(resolveTextureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_COLOR_TARGET)) { SDL_assert_release(!"Resolve texture usage must include COLOR_TARGET!"); + return NULL; } } } + + if (color_target_infos[i].layer_or_depth_plane >= textureHeader->info.layer_count_or_depth) { + SDL_assert_release(!"Color target layer index must be less than the texture's layer count!"); + return NULL; + } + + if (color_target_infos[i].mip_level >= textureHeader->info.num_levels) { + SDL_assert_release(!"Color target mip level must be less than the texture's level count!"); + return NULL; + } } if (depth_stencil_target_info != NULL) { @@ -1532,10 +1750,12 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( TextureCommonHeader *textureHeader = (TextureCommonHeader *)depth_stencil_target_info->texture; if (!(textureHeader->info.usage & SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET)) { SDL_assert_release(!"Depth target must have been created with the DEPTH_STENCIL_TARGET usage flag!"); + return NULL; } if (depth_stencil_target_info->cycle && (depth_stencil_target_info->load_op == SDL_GPU_LOADOP_LOAD || depth_stencil_target_info->stencil_load_op == SDL_GPU_LOADOP_LOAD)) { SDL_assert_release(!"Cannot cycle depth target when load op or stencil load op is LOAD!"); + return NULL; } if (depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE || @@ -1543,6 +1763,7 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( depth_stencil_target_info->store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE || depth_stencil_target_info->stencil_store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) { SDL_assert_release(!"RESOLVE store ops are not supported for depth-stencil targets!"); + return NULL; } } } @@ -1554,14 +1775,18 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( depth_stencil_target_info); commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; - commandBufferHeader->render_pass.in_progress = true; - for (Uint32 i = 0; i < num_color_targets; i += 1) { - commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture; - } - commandBufferHeader->render_pass.num_color_targets = num_color_targets; - if (depth_stencil_target_info != NULL) { - commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture; + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + commandBufferHeader->render_pass.in_progress = true; + for (Uint32 i = 0; i < num_color_targets; i += 1) { + commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture; + } + commandBufferHeader->render_pass.num_color_targets = num_color_targets; + if (depth_stencil_target_info != NULL) { + commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture; + } } + return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass); } @@ -1569,8 +1794,6 @@ void SDL_BindGPUGraphicsPipeline( SDL_GPURenderPass *render_pass, SDL_GPUGraphicsPipeline *graphics_pipeline) { - CommandBufferCommonHeader *commandBufferHeader; - if (render_pass == NULL) { SDL_InvalidParamError("render_pass"); return; @@ -1584,8 +1807,10 @@ void SDL_BindGPUGraphicsPipeline( RENDERPASS_COMMAND_BUFFER, graphics_pipeline); - commandBufferHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER; - commandBufferHeader->graphics_pipeline_bound = true; + + if (RENDERPASS_DEVICE->debug_mode) { + RENDERPASS_BOUND_PIPELINE = graphics_pipeline; + } } void SDL_SetGPUViewport( @@ -1740,6 +1965,10 @@ void SDL_BindGPUVertexSamplers( { CHECK_SAMPLER_TEXTURES } + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->vertex_sampler_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindVertexSamplers( @@ -1767,6 +1996,10 @@ void SDL_BindGPUVertexStorageTextures( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_STORAGE_TEXTURES + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->vertex_storage_texture_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindVertexStorageTextures( @@ -1793,6 +2026,10 @@ void SDL_BindGPUVertexStorageBuffers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->vertex_storage_buffer_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindVertexStorageBuffers( @@ -1820,10 +2057,13 @@ void SDL_BindGPUFragmentSamplers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS - if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation) - { + if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation) { CHECK_SAMPLER_TEXTURES } + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->fragment_sampler_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindFragmentSamplers( @@ -1851,6 +2091,10 @@ void SDL_BindGPUFragmentStorageTextures( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_STORAGE_TEXTURES + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->fragment_storage_texture_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindFragmentStorageTextures( @@ -1877,6 +2121,10 @@ void SDL_BindGPUFragmentStorageBuffers( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((RenderPass *)render_pass)->fragment_storage_buffer_bound[first_slot + i] = true; + } } RENDERPASS_DEVICE->BindFragmentStorageBuffers( @@ -1902,6 +2150,7 @@ void SDL_DrawGPUIndexedPrimitives( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawIndexedPrimitives( @@ -1928,6 +2177,7 @@ void SDL_DrawGPUPrimitives( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawPrimitives( @@ -1956,6 +2206,7 @@ void SDL_DrawGPUPrimitivesIndirect( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawPrimitivesIndirect( @@ -1983,6 +2234,7 @@ void SDL_DrawGPUIndexedPrimitivesIndirect( if (RENDERPASS_DEVICE->debug_mode) { CHECK_RENDERPASS CHECK_GRAPHICS_PIPELINE_BOUND + SDL_GPU_CheckGraphicsBindings(render_pass); } RENDERPASS_DEVICE->DrawIndexedPrimitivesIndirect( @@ -1996,6 +2248,7 @@ void SDL_EndGPURenderPass( SDL_GPURenderPass *render_pass) { CommandBufferCommonHeader *commandBufferCommonHeader; + commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER; if (render_pass == NULL) { SDL_InvalidParamError("render_pass"); @@ -2009,15 +2262,22 @@ void SDL_EndGPURenderPass( RENDERPASS_DEVICE->EndRenderPass( RENDERPASS_COMMAND_BUFFER); - commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER; - commandBufferCommonHeader->render_pass.in_progress = false; - for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) - { - commandBufferCommonHeader->render_pass.color_targets[i] = NULL; + if (RENDERPASS_DEVICE->debug_mode) { + commandBufferCommonHeader->render_pass.in_progress = false; + for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1) + { + commandBufferCommonHeader->render_pass.color_targets[i] = NULL; + } + commandBufferCommonHeader->render_pass.num_color_targets = 0; + commandBufferCommonHeader->render_pass.depth_stencil_target = NULL; + commandBufferCommonHeader->render_pass.graphics_pipeline = NULL; + SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_sampler_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_buffer_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_sampler_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_buffer_bound); } - commandBufferCommonHeader->render_pass.num_color_targets = 0; - commandBufferCommonHeader->render_pass.depth_stencil_target = NULL; - commandBufferCommonHeader->graphics_pipeline_bound = false; } // Compute Pass @@ -2061,6 +2321,16 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass( SDL_assert_release(!"Texture must be created with COMPUTE_STORAGE_WRITE or COMPUTE_STORAGE_SIMULTANEOUS_READ_WRITE flag"); return NULL; } + + if (storage_texture_bindings[i].layer >= header->info.layer_count_or_depth) { + SDL_assert_release(!"Storage texture layer index must be less than the texture's layer count!"); + return NULL; + } + + if (storage_texture_bindings[i].mip_level >= header->info.num_levels) { + SDL_assert_release(!"Storage texture mip level must be less than the texture's level count!"); + return NULL; + } } // TODO: validate buffer usage? @@ -2074,7 +2344,19 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass( num_storage_buffer_bindings); commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; - commandBufferHeader->compute_pass.in_progress = true; + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + commandBufferHeader->compute_pass.in_progress = true; + + for (Uint32 i = 0; i < num_storage_texture_bindings; i += 1) { + commandBufferHeader->compute_pass.read_write_storage_texture_bound[i] = true; + } + + for (Uint32 i = 0; i < num_storage_buffer_bindings; i += 1) { + commandBufferHeader->compute_pass.read_write_storage_buffer_bound[i] = true; + } + } + return (SDL_GPUComputePass *)&(commandBufferHeader->compute_pass); } @@ -2082,8 +2364,6 @@ void SDL_BindGPUComputePipeline( SDL_GPUComputePass *compute_pass, SDL_GPUComputePipeline *compute_pipeline) { - CommandBufferCommonHeader *commandBufferHeader; - if (compute_pass == NULL) { SDL_InvalidParamError("compute_pass"); return; @@ -2101,8 +2381,10 @@ void SDL_BindGPUComputePipeline( COMPUTEPASS_COMMAND_BUFFER, compute_pipeline); - commandBufferHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER; - commandBufferHeader->compute_pipeline_bound = true; + + if (COMPUTEPASS_DEVICE->debug_mode) { + COMPUTEPASS_BOUND_PIPELINE = compute_pipeline; + } } void SDL_BindGPUComputeSamplers( @@ -2122,6 +2404,10 @@ void SDL_BindGPUComputeSamplers( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((ComputePass *)compute_pass)->sampler_bound[first_slot + i] = true; + } } COMPUTEPASS_DEVICE->BindComputeSamplers( @@ -2148,6 +2434,10 @@ void SDL_BindGPUComputeStorageTextures( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((ComputePass *)compute_pass)->read_only_storage_texture_bound[first_slot + i] = true; + } } COMPUTEPASS_DEVICE->BindComputeStorageTextures( @@ -2174,6 +2464,10 @@ void SDL_BindGPUComputeStorageBuffers( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS + + for (Uint32 i = 0; i < num_bindings; i += 1) { + ((ComputePass *)compute_pass)->read_only_storage_buffer_bound[first_slot + i] = true; + } } COMPUTEPASS_DEVICE->BindComputeStorageBuffers( @@ -2197,6 +2491,7 @@ void SDL_DispatchGPUCompute( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS CHECK_COMPUTE_PIPELINE_BOUND + SDL_GPU_CheckComputeBindings(compute_pass); } COMPUTEPASS_DEVICE->DispatchCompute( @@ -2219,6 +2514,7 @@ void SDL_DispatchGPUComputeIndirect( if (COMPUTEPASS_DEVICE->debug_mode) { CHECK_COMPUTEPASS CHECK_COMPUTE_PIPELINE_BOUND + SDL_GPU_CheckComputeBindings(compute_pass); } COMPUTEPASS_DEVICE->DispatchComputeIndirect( @@ -2244,9 +2540,16 @@ void SDL_EndGPUComputePass( COMPUTEPASS_DEVICE->EndComputePass( COMPUTEPASS_COMMAND_BUFFER); - commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER; - commandBufferCommonHeader->compute_pass.in_progress = false; - commandBufferCommonHeader->compute_pipeline_bound = false; + if (COMPUTEPASS_DEVICE->debug_mode) { + commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER; + commandBufferCommonHeader->compute_pass.in_progress = false; + commandBufferCommonHeader->compute_pass.compute_pipeline = false; + SDL_zeroa(commandBufferCommonHeader->compute_pass.sampler_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_buffer_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_texture_bound); + SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_buffer_bound); + } } // TransferBuffer Data @@ -2304,7 +2607,11 @@ SDL_GPUCopyPass *SDL_BeginGPUCopyPass( command_buffer); commandBufferHeader = (CommandBufferCommonHeader *)command_buffer; - commandBufferHeader->copy_pass.in_progress = true; + + if (COMMAND_BUFFER_DEVICE->debug_mode) { + commandBufferHeader->copy_pass.in_progress = true; + } + return (SDL_GPUCopyPass *)&(commandBufferHeader->copy_pass); } @@ -2555,7 +2862,9 @@ void SDL_EndGPUCopyPass( COPYPASS_DEVICE->EndCopyPass( COPYPASS_COMMAND_BUFFER); - ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false; + if (COPYPASS_DEVICE->debug_mode) { + ((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false; + } } void SDL_GenerateMipmapsForGPUTexture( diff --git a/third-party/SDL/src/gpu/SDL_sysgpu.h b/third-party/SDL/src/gpu/SDL_sysgpu.h index 3c2c786600..8469d9418b 100644 --- a/third-party/SDL/src/gpu/SDL_sysgpu.h +++ b/third-party/SDL/src/gpu/SDL_sysgpu.h @@ -47,6 +47,20 @@ typedef struct Pass bool in_progress; } Pass; +typedef struct ComputePass +{ + SDL_GPUCommandBuffer *command_buffer; + bool in_progress; + + SDL_GPUComputePipeline *compute_pipeline; + + bool sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + bool read_only_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE]; + bool read_only_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE]; + bool read_write_storage_texture_bound[MAX_COMPUTE_WRITE_TEXTURES]; + bool read_write_storage_buffer_bound[MAX_COMPUTE_WRITE_BUFFERS]; +} ComputePass; + typedef struct RenderPass { SDL_GPUCommandBuffer *command_buffer; @@ -54,15 +68,25 @@ typedef struct RenderPass SDL_GPUTexture *color_targets[MAX_COLOR_TARGET_BINDINGS]; Uint32 num_color_targets; SDL_GPUTexture *depth_stencil_target; + + SDL_GPUGraphicsPipeline *graphics_pipeline; + + bool vertex_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + bool vertex_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE]; + bool vertex_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE]; + + bool fragment_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + bool fragment_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE]; + bool fragment_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE]; } RenderPass; typedef struct CommandBufferCommonHeader { SDL_GPUDevice *device; + RenderPass render_pass; - bool graphics_pipeline_bound; - Pass compute_pass; - bool compute_pipeline_bound; + ComputePass compute_pass; + Pass copy_pass; bool swapchain_texture_acquired; bool submitted; @@ -75,6 +99,29 @@ typedef struct TextureCommonHeader SDL_GPUTextureCreateInfo info; } TextureCommonHeader; +typedef struct GraphicsPipelineCommonHeader +{ + Uint32 num_vertex_samplers; + Uint32 num_vertex_storage_textures; + Uint32 num_vertex_storage_buffers; + Uint32 num_vertex_uniform_buffers; + + Uint32 num_fragment_samplers; + Uint32 num_fragment_storage_textures; + Uint32 num_fragment_storage_buffers; + Uint32 num_fragment_uniform_buffers; +} GraphicsPipelineCommonHeader; + +typedef struct ComputePipelineCommonHeader +{ + Uint32 numSamplers; + Uint32 numReadonlyStorageTextures; + Uint32 numReadonlyStorageBuffers; + Uint32 numReadWriteStorageTextures; + Uint32 numReadWriteStorageBuffers; + Uint32 numUniformBuffers; +} ComputePipelineCommonHeader; + typedef struct BlitFragmentUniforms { // texcoord space @@ -162,6 +209,7 @@ static inline Sint32 Texture_GetBlockWidth( case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT: case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT: case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB: + case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_ASTC_4x4_UNORM: @@ -279,6 +327,7 @@ static inline Sint32 Texture_GetBlockHeight( case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_FLOAT: case SDL_GPU_TEXTUREFORMAT_BC6H_RGB_UFLOAT: case SDL_GPU_TEXTUREFORMAT_BC1_RGBA_UNORM_SRGB: + case SDL_GPU_TEXTUREFORMAT_BC2_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC3_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_BC7_RGBA_UNORM_SRGB: case SDL_GPU_TEXTUREFORMAT_ASTC_5x4_UNORM: diff --git a/third-party/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c b/third-party/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c index 737dbc300f..a92215910c 100644 --- a/third-party/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/third-party/SDL/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -1015,26 +1015,38 @@ struct D3D12CommandBuffer Uint32 vertexBufferOffsets[MAX_VERTEX_BUFFERS]; Uint32 vertexBufferCount; - D3D12Texture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Sampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Texture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - D3D12Buffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE vertexStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12UniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; - D3D12Texture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Sampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Texture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - D3D12Buffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE fragmentStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE]; + D3D12UniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; - D3D12Texture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - D3D12Sampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeSamplerTextureDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeSamplerDescriptorHandles[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeReadOnlyStorageTextureDescriptorHandles[MAX_STORAGE_TEXTURES_PER_STAGE]; + D3D12_CPU_DESCRIPTOR_HANDLE computeReadOnlyStorageBufferDescriptorHandles[MAX_STORAGE_BUFFERS_PER_STAGE]; + + // Track these separately because barriers can happen mid compute pass D3D12Texture *computeReadOnlyStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; D3D12Buffer *computeReadOnlyStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + + D3D12_CPU_DESCRIPTOR_HANDLE computeReadWriteStorageTextureDescriptorHandles[MAX_COMPUTE_WRITE_TEXTURES]; + D3D12_CPU_DESCRIPTOR_HANDLE computeReadWriteStorageBufferDescriptorHandles[MAX_COMPUTE_WRITE_BUFFERS]; + + // Track these separately because they are bound when the compute pass begins D3D12TextureSubresource *computeReadWriteStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES]; Uint32 computeReadWriteStorageTextureSubresourceCount; D3D12Buffer *computeReadWriteStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS]; Uint32 computeReadWriteStorageBufferCount; + D3D12UniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; // Resource tracking @@ -1098,22 +1110,14 @@ typedef struct D3D12GraphicsRootSignature struct D3D12GraphicsPipeline { + GraphicsPipelineCommonHeader header; + ID3D12PipelineState *pipelineState; D3D12GraphicsRootSignature *rootSignature; SDL_GPUPrimitiveType primitiveType; Uint32 vertexStrides[MAX_VERTEX_BUFFERS]; - Uint32 vertexSamplerCount; - Uint32 vertexUniformBufferCount; - Uint32 vertexStorageBufferCount; - Uint32 vertexStorageTextureCount; - - Uint32 fragmentSamplerCount; - Uint32 fragmentUniformBufferCount; - Uint32 fragmentStorageBufferCount; - Uint32 fragmentStorageTextureCount; - SDL_AtomicInt referenceCount; }; @@ -1132,16 +1136,11 @@ typedef struct D3D12ComputeRootSignature struct D3D12ComputePipeline { + ComputePipelineCommonHeader header; + ID3D12PipelineState *pipelineState; D3D12ComputeRootSignature *rootSignature; - Uint32 numSamplers; - Uint32 numReadOnlyStorageTextures; - Uint32 numReadOnlyStorageBuffers; - Uint32 numReadWriteStorageTextures; - Uint32 numReadWriteStorageBuffers; - Uint32 numUniformBuffers; - SDL_AtomicInt referenceCount; }; @@ -2886,12 +2885,12 @@ static SDL_GPUComputePipeline *D3D12_CreateComputePipeline( computePipeline->pipelineState = pipelineState; computePipeline->rootSignature = rootSignature; - computePipeline->numSamplers = createinfo->num_samplers; - computePipeline->numReadOnlyStorageTextures = createinfo->num_readonly_storage_textures; - computePipeline->numReadOnlyStorageBuffers = createinfo->num_readonly_storage_buffers; - computePipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; - computePipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; - computePipeline->numUniformBuffers = createinfo->num_uniform_buffers; + computePipeline->header.numSamplers = createinfo->num_samplers; + computePipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures; + computePipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers; + computePipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; + computePipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; + computePipeline->header.numUniformBuffers = createinfo->num_uniform_buffers; SDL_SetAtomicInt(&computePipeline->referenceCount, 0); if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) { @@ -3172,15 +3171,15 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline( pipeline->primitiveType = createinfo->primitive_type; - pipeline->vertexSamplerCount = vertShader->num_samplers; - pipeline->vertexStorageTextureCount = vertShader->numStorageTextures; - pipeline->vertexStorageBufferCount = vertShader->numStorageBuffers; - pipeline->vertexUniformBufferCount = vertShader->numUniformBuffers; + pipeline->header.num_vertex_samplers = vertShader->num_samplers; + pipeline->header.num_vertex_storage_textures = vertShader->numStorageTextures; + pipeline->header.num_vertex_storage_buffers = vertShader->numStorageBuffers; + pipeline->header.num_vertex_uniform_buffers = vertShader->numUniformBuffers; - pipeline->fragmentSamplerCount = fragShader->num_samplers; - pipeline->fragmentStorageTextureCount = fragShader->numStorageTextures; - pipeline->fragmentStorageBufferCount = fragShader->numStorageBuffers; - pipeline->fragmentUniformBufferCount = fragShader->numUniformBuffers; + pipeline->header.num_fragment_samplers = fragShader->num_samplers; + pipeline->header.num_fragment_storage_textures = fragShader->numStorageTextures; + pipeline->header.num_fragment_storage_buffers = fragShader->numStorageBuffers; + pipeline->header.num_fragment_uniform_buffers = fragShader->numUniformBuffers; SDL_SetAtomicInt(&pipeline->referenceCount, 0); @@ -3350,7 +3349,7 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture( if (createinfo->type != SDL_GPU_TEXTURETYPE_3D) { desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Alignment = isSwapchainTexture ? 0 : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + desc.Alignment = isSwapchainTexture ? 0 : isMultisample ? D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; desc.Width = createinfo->width; desc.Height = createinfo->height; desc.DepthOrArraySize = (UINT16)createinfo->layer_count_or_depth; @@ -4637,14 +4636,14 @@ static void D3D12_BindGraphicsPipeline( d3d12CommandBuffer->needFragmentUniformBufferBind[i] = true; } - for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) { if (d3d12CommandBuffer->vertexUniformBuffers[i] == NULL) { d3d12CommandBuffer->vertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool( d3d12CommandBuffer); } } - for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) { if (d3d12CommandBuffer->fragmentUniformBuffers[i] == NULL) { d3d12CommandBuffer->fragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool( d3d12CommandBuffer); @@ -4711,21 +4710,21 @@ static void D3D12_BindVertexSamplers( D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; - if (d3d12CommandBuffer->vertexSamplers[firstSlot + i] != sampler) { + if (d3d12CommandBuffer->vertexSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) { D3D12_INTERNAL_TrackSampler( d3d12CommandBuffer, sampler); - d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler; + d3d12CommandBuffer->vertexSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle; d3d12CommandBuffer->needVertexSamplerBind = true; } - if (d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] != container->activeTexture) { + if (d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, container->activeTexture); - d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needVertexSamplerBind = true; } } @@ -4743,10 +4742,10 @@ static void D3D12_BindVertexStorageTextures( D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; D3D12Texture *texture = container->activeTexture; - if (d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] != texture) { + if (d3d12CommandBuffer->vertexStorageTextureDescriptorHandles[firstSlot + i].ptr != texture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture); - d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture; + d3d12CommandBuffer->vertexStorageTextureDescriptorHandles[firstSlot + i] = texture->srvHandle.cpuHandle; d3d12CommandBuffer->needVertexStorageTextureBind = true; } } @@ -4762,12 +4761,12 @@ static void D3D12_BindVertexStorageBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; - if (d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] != container->activeBuffer) { + if (d3d12CommandBuffer->vertexStorageBufferDescriptorHandles[firstSlot + i].ptr != container->activeBuffer->srvDescriptor.cpuHandle.ptr) { D3D12_INTERNAL_TrackBuffer( d3d12CommandBuffer, container->activeBuffer); - d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer; + d3d12CommandBuffer->vertexStorageBufferDescriptorHandles[firstSlot + i] = container->activeBuffer->srvDescriptor.cpuHandle; d3d12CommandBuffer->needVertexStorageBufferBind = true; } } @@ -4785,21 +4784,21 @@ static void D3D12_BindFragmentSamplers( D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; - if (d3d12CommandBuffer->fragmentSamplers[firstSlot + i] != sampler) { + if (d3d12CommandBuffer->fragmentSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) { D3D12_INTERNAL_TrackSampler( d3d12CommandBuffer, sampler); - d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler; + d3d12CommandBuffer->fragmentSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle; d3d12CommandBuffer->needFragmentSamplerBind = true; } - if (d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] != container->activeTexture) { + if (d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, container->activeTexture); - d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needFragmentSamplerBind = true; } } @@ -4817,10 +4816,10 @@ static void D3D12_BindFragmentStorageTextures( D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; D3D12Texture *texture = container->activeTexture; - if (d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] != texture) { + if (d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles[firstSlot + i].ptr != texture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture); - d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture; + d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles[firstSlot + i] = texture->srvHandle.cpuHandle; d3d12CommandBuffer->needFragmentStorageTextureBind = true; } } @@ -4837,12 +4836,12 @@ static void D3D12_BindFragmentStorageBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; - if (d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] != container->activeBuffer) { + if (d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles[firstSlot + i].ptr != container->activeBuffer->srvDescriptor.cpuHandle.ptr) { D3D12_INTERNAL_TrackBuffer( d3d12CommandBuffer, container->activeBuffer); - d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer; + d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles[firstSlot + i] = container->activeBuffer->srvDescriptor.cpuHandle; d3d12CommandBuffer->needFragmentStorageBufferBind = true; } } @@ -4923,15 +4922,19 @@ static void D3D12_INTERNAL_WriteGPUDescriptors( gpuBaseDescriptor->ptr = heap->descriptorHeapGPUStart.ptr + (heap->currentDescriptorIndex * heap->descriptorSize); for (Uint32 i = 0; i < resourceHandleCount; i += 1) { - ID3D12Device_CopyDescriptorsSimple( - commandBuffer->renderer->device, - 1, - gpuHeapCpuHandle, - resourceDescriptorHandles[i], - heapType); + // This will crash the driver if it gets a null handle! Cool! + if (resourceDescriptorHandles[i].ptr != 0) + { + ID3D12Device_CopyDescriptorsSimple( + commandBuffer->renderer->device, + 1, + gpuHeapCpuHandle, + resourceDescriptorHandles[i], + heapType); - heap->currentDescriptorIndex += 1; - gpuHeapCpuHandle.ptr += heap->descriptorSize; + heap->currentDescriptorIndex += 1; + gpuHeapCpuHandle.ptr += heap->descriptorSize; + } } } @@ -4961,19 +4964,21 @@ static void D3D12_INTERNAL_BindGraphicsResources( 0, commandBuffer->vertexBufferCount, vertexBufferViews); + + commandBuffer->needVertexBufferBind = false; } if (commandBuffer->needVertexSamplerBind) { - if (graphicsPipeline->vertexSamplerCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexSamplers[i]->handle.cpuHandle; + if (graphicsPipeline->header.num_vertex_samplers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_samplers; i += 1) { + cpuHandles[i] = commandBuffer->vertexSamplerDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, cpuHandles, - graphicsPipeline->vertexSamplerCount, + graphicsPipeline->header.num_vertex_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -4981,15 +4986,15 @@ static void D3D12_INTERNAL_BindGraphicsResources( graphicsPipeline->rootSignature->vertexSamplerRootIndex, gpuDescriptorHandle); - for (Uint32 i = 0; i < graphicsPipeline->vertexSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexSamplerTextures[i]->srvHandle.cpuHandle; + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_samplers; i += 1) { + cpuHandles[i] = commandBuffer->vertexSamplerTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->vertexSamplerCount, + graphicsPipeline->header.num_vertex_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5001,16 +5006,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needVertexStorageTextureBind) { - if (graphicsPipeline->vertexStorageTextureCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->vertexStorageTextureCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexStorageTextures[i]->srvHandle.cpuHandle; + if (graphicsPipeline->header.num_vertex_storage_textures > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_storage_textures; i += 1) { + cpuHandles[i] = commandBuffer->vertexStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->vertexStorageTextureCount, + graphicsPipeline->header.num_vertex_storage_textures, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5022,16 +5027,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needVertexStorageBufferBind) { - if (graphicsPipeline->vertexStorageBufferCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->vertexStorageBufferCount; i += 1) { - cpuHandles[i] = commandBuffer->vertexStorageBuffers[i]->srvDescriptor.cpuHandle; + if (graphicsPipeline->header.num_vertex_storage_buffers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_storage_buffers; i += 1) { + cpuHandles[i] = commandBuffer->vertexStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->vertexStorageBufferCount, + graphicsPipeline->header.num_vertex_storage_buffers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5044,7 +5049,7 @@ static void D3D12_INTERNAL_BindGraphicsResources( for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needVertexUniformBufferBind[i]) { - if (graphicsPipeline->vertexUniformBufferCount > i) { + if (graphicsPipeline->header.num_vertex_uniform_buffers > i) { ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView( commandBuffer->graphicsCommandList, graphicsPipeline->rootSignature->vertexUniformBufferRootIndex[i], @@ -5055,16 +5060,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needFragmentSamplerBind) { - if (graphicsPipeline->fragmentSamplerCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentSamplers[i]->handle.cpuHandle; + if (graphicsPipeline->header.num_fragment_samplers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_samplers; i += 1) { + cpuHandles[i] = commandBuffer->fragmentSamplerDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, cpuHandles, - graphicsPipeline->fragmentSamplerCount, + graphicsPipeline->header.num_fragment_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5072,15 +5077,15 @@ static void D3D12_INTERNAL_BindGraphicsResources( graphicsPipeline->rootSignature->fragmentSamplerRootIndex, gpuDescriptorHandle); - for (Uint32 i = 0; i < graphicsPipeline->fragmentSamplerCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentSamplerTextures[i]->srvHandle.cpuHandle; + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_samplers; i += 1) { + cpuHandles[i] = commandBuffer->fragmentSamplerTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->fragmentSamplerCount, + graphicsPipeline->header.num_fragment_samplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5092,16 +5097,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needFragmentStorageTextureBind) { - if (graphicsPipeline->fragmentStorageTextureCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageTextureCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentStorageTextures[i]->srvHandle.cpuHandle; + if (graphicsPipeline->header.num_fragment_storage_textures > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_storage_textures; i += 1) { + cpuHandles[i] = commandBuffer->fragmentStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->fragmentStorageTextureCount, + graphicsPipeline->header.num_fragment_storage_textures, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5113,16 +5118,16 @@ static void D3D12_INTERNAL_BindGraphicsResources( } if (commandBuffer->needFragmentStorageBufferBind) { - if (graphicsPipeline->fragmentStorageBufferCount > 0) { - for (Uint32 i = 0; i < graphicsPipeline->fragmentStorageBufferCount; i += 1) { - cpuHandles[i] = commandBuffer->fragmentStorageBuffers[i]->srvDescriptor.cpuHandle; + if (graphicsPipeline->header.num_fragment_storage_buffers > 0) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_storage_buffers; i += 1) { + cpuHandles[i] = commandBuffer->fragmentStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - graphicsPipeline->fragmentStorageBufferCount, + graphicsPipeline->header.num_fragment_storage_buffers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( @@ -5135,7 +5140,7 @@ static void D3D12_INTERNAL_BindGraphicsResources( for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needFragmentUniformBufferBind[i]) { - if (graphicsPipeline->fragmentUniformBufferCount > i) { + if (graphicsPipeline->header.num_fragment_uniform_buffers > i) { ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView( commandBuffer->graphicsCommandList, graphicsPipeline->rootSignature->fragmentUniformBufferRootIndex[i], @@ -5300,15 +5305,15 @@ static void D3D12_EndRenderPass( SDL_zeroa(d3d12CommandBuffer->vertexBufferOffsets); d3d12CommandBuffer->vertexBufferCount = 0; - SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextures); - SDL_zeroa(d3d12CommandBuffer->vertexSamplers); - SDL_zeroa(d3d12CommandBuffer->vertexStorageTextures); - SDL_zeroa(d3d12CommandBuffer->vertexStorageBuffers); + SDL_zeroa(d3d12CommandBuffer->vertexSamplerTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->vertexSamplerDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->vertexStorageTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->vertexStorageBufferDescriptorHandles); - SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextures); - SDL_zeroa(d3d12CommandBuffer->fragmentSamplers); - SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextures); - SDL_zeroa(d3d12CommandBuffer->fragmentStorageBuffers); + SDL_zeroa(d3d12CommandBuffer->fragmentSamplerTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->fragmentSamplerDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->fragmentStorageTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->fragmentStorageBufferDescriptorHandles); } // Compute Pass @@ -5342,6 +5347,7 @@ static void D3D12_BeginComputePass( D3D12_RESOURCE_STATE_UNORDERED_ACCESS); d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i] = subresource; + d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles[i] = subresource->uavHandle.cpuHandle; D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, @@ -5360,6 +5366,7 @@ static void D3D12_BeginComputePass( D3D12_RESOURCE_STATE_UNORDERED_ACCESS); d3d12CommandBuffer->computeReadWriteStorageBuffers[i] = buffer; + d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles[i] = buffer->uavDescriptor.cpuHandle; D3D12_INTERNAL_TrackBuffer( d3d12CommandBuffer, @@ -5401,7 +5408,7 @@ static void D3D12_BindComputePipeline( d3d12CommandBuffer->needComputeUniformBufferBind[i] = true; } - for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) { + for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) { if (d3d12CommandBuffer->computeUniformBuffers[i] == NULL) { d3d12CommandBuffer->computeUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool( d3d12CommandBuffer); @@ -5411,9 +5418,9 @@ static void D3D12_BindComputePipeline( D3D12_INTERNAL_TrackComputePipeline(d3d12CommandBuffer, pipeline); // Bind write-only resources after setting root signature - if (pipeline->numReadWriteStorageTextures > 0) { - for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) { - cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureSubresources[i]->uavHandle.cpuHandle; + if (pipeline->header.numReadWriteStorageTextures > 0) { + for (Uint32 i = 0; i < pipeline->header.numReadWriteStorageTextures; i += 1) { + cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( @@ -5429,9 +5436,9 @@ static void D3D12_BindComputePipeline( gpuDescriptorHandle); } - if (pipeline->numReadWriteStorageBuffers > 0) { - for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) { - cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBuffers[i]->uavDescriptor.cpuHandle; + if (pipeline->header.numReadWriteStorageBuffers > 0) { + for (Uint32 i = 0; i < pipeline->header.numReadWriteStorageBuffers; i += 1) { + cpuHandles[i] = d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( @@ -5460,21 +5467,21 @@ static void D3D12_BindComputeSamplers( D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; - if (d3d12CommandBuffer->computeSamplers[firstSlot + i] != sampler) { + if (d3d12CommandBuffer->computeSamplerDescriptorHandles[firstSlot + i].ptr != sampler->handle.cpuHandle.ptr) { D3D12_INTERNAL_TrackSampler( d3d12CommandBuffer, (D3D12Sampler *)textureSamplerBindings[i].sampler); - d3d12CommandBuffer->computeSamplers[firstSlot + i] = (D3D12Sampler *)textureSamplerBindings[i].sampler; + d3d12CommandBuffer->computeSamplerDescriptorHandles[firstSlot + i] = sampler->handle.cpuHandle; d3d12CommandBuffer->needComputeSamplerBind = true; } - if (d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] != container->activeTexture) { + if (d3d12CommandBuffer->computeSamplerTextureDescriptorHandles[firstSlot + i].ptr != container->activeTexture->srvHandle.cpuHandle.ptr) { D3D12_INTERNAL_TrackTexture( d3d12CommandBuffer, container->activeTexture); - d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->computeSamplerTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needComputeSamplerBind = true; } } @@ -5511,6 +5518,7 @@ static void D3D12_BindComputeStorageTextures( container->activeTexture); d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture; + d3d12CommandBuffer->computeReadOnlyStorageTextureDescriptorHandles[firstSlot + i] = container->activeTexture->srvHandle.cpuHandle; d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true; } } @@ -5548,6 +5556,7 @@ static void D3D12_BindComputeStorageBuffers( buffer); d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer; + d3d12CommandBuffer->computeReadOnlyStorageBufferDescriptorHandles[firstSlot + i] = buffer->srvDescriptor.cpuHandle; d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true; } } @@ -5583,16 +5592,16 @@ static void D3D12_INTERNAL_BindComputeResources( D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle; if (commandBuffer->needComputeSamplerBind) { - if (computePipeline->numSamplers > 0) { - for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) { - cpuHandles[i] = commandBuffer->computeSamplers[i]->handle.cpuHandle; + if (computePipeline->header.numSamplers > 0) { + for (Uint32 i = 0; i < computePipeline->header.numSamplers; i += 1) { + cpuHandles[i] = commandBuffer->computeSamplerDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, cpuHandles, - computePipeline->numSamplers, + computePipeline->header.numSamplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5600,15 +5609,15 @@ static void D3D12_INTERNAL_BindComputeResources( computePipeline->rootSignature->samplerRootIndex, gpuDescriptorHandle); - for (Uint32 i = 0; i < computePipeline->numSamplers; i += 1) { - cpuHandles[i] = commandBuffer->computeSamplerTextures[i]->srvHandle.cpuHandle; + for (Uint32 i = 0; i < computePipeline->header.numSamplers; i += 1) { + cpuHandles[i] = commandBuffer->computeSamplerTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - computePipeline->numSamplers, + computePipeline->header.numSamplers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5620,16 +5629,16 @@ static void D3D12_INTERNAL_BindComputeResources( } if (commandBuffer->needComputeReadOnlyStorageTextureBind) { - if (computePipeline->numReadOnlyStorageTextures > 0) { - for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageTextures; i += 1) { - cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextures[i]->srvHandle.cpuHandle; + if (computePipeline->header.numReadonlyStorageTextures > 0) { + for (Uint32 i = 0; i < computePipeline->header.numReadonlyStorageTextures; i += 1) { + cpuHandles[i] = commandBuffer->computeReadOnlyStorageTextureDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - computePipeline->numReadOnlyStorageTextures, + computePipeline->header.numReadonlyStorageTextures, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5641,16 +5650,16 @@ static void D3D12_INTERNAL_BindComputeResources( } if (commandBuffer->needComputeReadOnlyStorageBufferBind) { - if (computePipeline->numReadOnlyStorageBuffers > 0) { - for (Uint32 i = 0; i < computePipeline->numReadOnlyStorageBuffers; i += 1) { - cpuHandles[i] = commandBuffer->computeReadOnlyStorageBuffers[i]->srvDescriptor.cpuHandle; + if (computePipeline->header.numReadonlyStorageBuffers > 0) { + for (Uint32 i = 0; i < computePipeline->header.numReadonlyStorageBuffers; i += 1) { + cpuHandles[i] = commandBuffer->computeReadOnlyStorageBufferDescriptorHandles[i]; } D3D12_INTERNAL_WriteGPUDescriptors( commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, cpuHandles, - computePipeline->numReadOnlyStorageBuffers, + computePipeline->header.numReadonlyStorageBuffers, &gpuDescriptorHandle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( @@ -5663,7 +5672,7 @@ static void D3D12_INTERNAL_BindComputeResources( for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needComputeUniformBufferBind[i]) { - if (computePipeline->numUniformBuffers > i) { + if (computePipeline->header.numUniformBuffers > i) { ID3D12GraphicsCommandList_SetComputeRootConstantBufferView( commandBuffer->graphicsCommandList, computePipeline->rootSignature->uniformBufferRootIndex[i], @@ -5762,8 +5771,11 @@ static void D3D12_EndComputePass( } } - SDL_zeroa(d3d12CommandBuffer->computeSamplerTextures); - SDL_zeroa(d3d12CommandBuffer->computeSamplers); + SDL_zeroa(d3d12CommandBuffer->computeSamplerTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->computeSamplerDescriptorHandles); + + SDL_zeroa(d3d12CommandBuffer->computeReadWriteStorageTextureDescriptorHandles); + SDL_zeroa(d3d12CommandBuffer->computeReadWriteStorageBufferDescriptorHandles); d3d12CommandBuffer->currentComputePipeline = NULL; } @@ -7352,20 +7364,22 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer( SDL_zeroa(commandBuffer->vertexBufferOffsets); commandBuffer->vertexBufferCount = 0; - SDL_zeroa(commandBuffer->vertexSamplerTextures); - SDL_zeroa(commandBuffer->vertexSamplers); - SDL_zeroa(commandBuffer->vertexStorageTextures); - SDL_zeroa(commandBuffer->vertexStorageBuffers); + SDL_zeroa(commandBuffer->vertexSamplerTextureDescriptorHandles); + SDL_zeroa(commandBuffer->vertexSamplerDescriptorHandles); + SDL_zeroa(commandBuffer->vertexStorageTextureDescriptorHandles); + SDL_zeroa(commandBuffer->vertexStorageBufferDescriptorHandles); SDL_zeroa(commandBuffer->vertexUniformBuffers); - SDL_zeroa(commandBuffer->fragmentSamplerTextures); - SDL_zeroa(commandBuffer->fragmentSamplers); - SDL_zeroa(commandBuffer->fragmentStorageTextures); - SDL_zeroa(commandBuffer->fragmentStorageBuffers); + SDL_zeroa(commandBuffer->fragmentSamplerTextureDescriptorHandles); + SDL_zeroa(commandBuffer->fragmentSamplerDescriptorHandles); + SDL_zeroa(commandBuffer->fragmentStorageTextureDescriptorHandles); + SDL_zeroa(commandBuffer->fragmentStorageBufferDescriptorHandles); SDL_zeroa(commandBuffer->fragmentUniformBuffers); - SDL_zeroa(commandBuffer->computeSamplerTextures); - SDL_zeroa(commandBuffer->computeSamplers); + SDL_zeroa(commandBuffer->computeSamplerTextureDescriptorHandles); + SDL_zeroa(commandBuffer->computeSamplerDescriptorHandles); + SDL_zeroa(commandBuffer->computeReadOnlyStorageTextureDescriptorHandles); + SDL_zeroa(commandBuffer->computeReadOnlyStorageBufferDescriptorHandles); SDL_zeroa(commandBuffer->computeReadOnlyStorageTextures); SDL_zeroa(commandBuffer->computeReadOnlyStorageBuffers); SDL_zeroa(commandBuffer->computeReadWriteStorageTextureSubresources); @@ -8819,6 +8833,12 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD // Initialize the D3D12 debug layer, if applicable if (debugMode) { bool hasD3d12Debug = D3D12_INTERNAL_TryInitializeD3D12Debug(renderer); +#if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) + if (hasD3d12Debug) { + SDL_LogInfo( + SDL_LOG_CATEGORY_GPU, + "Validation layers enabled, expect debug level performance!"); +#else if (hasDxgiDebug && hasD3d12Debug) { SDL_LogInfo( SDL_LOG_CATEGORY_GPU, @@ -8827,6 +8847,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD SDL_LogWarn( SDL_LOG_CATEGORY_GPU, "Validation layers partially enabled, some warnings may not be available"); +#endif } else { SDL_LogWarn( SDL_LOG_CATEGORY_GPU, @@ -9159,8 +9180,23 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD return NULL; } + SDL_GPUShaderFormat shaderFormats = SDL_GPU_SHADERFORMAT_DXBC; + + D3D12_FEATURE_DATA_SHADER_MODEL shaderModel; + shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_0; + + res = ID3D12Device_CheckFeatureSupport( + renderer->device, + D3D12_FEATURE_SHADER_MODEL, + &shaderModel, + sizeof(shaderModel)); + if (SUCCEEDED(res) && shaderModel.HighestShaderModel >= D3D_SHADER_MODEL_6_0) { + shaderFormats |= SDL_GPU_SHADERFORMAT_DXIL; + } + ASSIGN_DRIVER(D3D12) result->driverData = (SDL_GPURenderer *)renderer; + result->shader_formats = shaderFormats; result->debug_mode = debugMode; renderer->sdlGPUDevice = result; diff --git a/third-party/SDL/src/gpu/metal/SDL_gpu_metal.m b/third-party/SDL/src/gpu/metal/SDL_gpu_metal.m index 0e3f6efa7e..7c2aefebb2 100644 --- a/third-party/SDL/src/gpu/metal/SDL_gpu_metal.m +++ b/third-party/SDL/src/gpu/metal/SDL_gpu_metal.m @@ -476,33 +476,21 @@ typedef struct MetalShader typedef struct MetalGraphicsPipeline { + GraphicsPipelineCommonHeader header; + id handle; SDL_GPURasterizerState rasterizerState; SDL_GPUPrimitiveType primitiveType; id depth_stencil_state; - - Uint32 vertexSamplerCount; - Uint32 vertexUniformBufferCount; - Uint32 vertexStorageBufferCount; - Uint32 vertexStorageTextureCount; - - Uint32 fragmentSamplerCount; - Uint32 fragmentUniformBufferCount; - Uint32 fragmentStorageBufferCount; - Uint32 fragmentStorageTextureCount; } MetalGraphicsPipeline; typedef struct MetalComputePipeline { + ComputePipelineCommonHeader header; + id handle; - Uint32 numSamplers; - Uint32 numReadonlyStorageTextures; - Uint32 numReadWriteStorageTextures; - Uint32 numReadonlyStorageBuffers; - Uint32 numReadWriteStorageBuffers; - Uint32 numUniformBuffers; Uint32 threadcountX; Uint32 threadcountY; Uint32 threadcountZ; @@ -1059,12 +1047,12 @@ static SDL_GPUComputePipeline *METAL_CreateComputePipeline( pipeline = SDL_calloc(1, sizeof(MetalComputePipeline)); pipeline->handle = handle; - pipeline->numSamplers = createinfo->num_samplers; - pipeline->numReadonlyStorageTextures = createinfo->num_readonly_storage_textures; - pipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; - pipeline->numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers; - pipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; - pipeline->numUniformBuffers = createinfo->num_uniform_buffers; + pipeline->header.numSamplers = createinfo->num_samplers; + pipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures; + pipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures; + pipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers; + pipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers; + pipeline->header.numUniformBuffers = createinfo->num_uniform_buffers; pipeline->threadcountX = createinfo->threadcount_x; pipeline->threadcountY = createinfo->threadcount_y; pipeline->threadcountZ = createinfo->threadcount_z; @@ -1207,14 +1195,14 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline( result->depth_stencil_state = depthStencilState; result->rasterizerState = createinfo->rasterizer_state; result->primitiveType = createinfo->primitive_type; - result->vertexSamplerCount = vertexShader->numSamplers; - result->vertexUniformBufferCount = vertexShader->numUniformBuffers; - result->vertexStorageBufferCount = vertexShader->numStorageBuffers; - result->vertexStorageTextureCount = vertexShader->numStorageTextures; - result->fragmentSamplerCount = fragmentShader->numSamplers; - result->fragmentUniformBufferCount = fragmentShader->numUniformBuffers; - result->fragmentStorageBufferCount = fragmentShader->numStorageBuffers; - result->fragmentStorageTextureCount = fragmentShader->numStorageTextures; + result->header.num_vertex_samplers = vertexShader->numSamplers; + result->header.num_vertex_uniform_buffers = vertexShader->numUniformBuffers; + result->header.num_vertex_storage_buffers = vertexShader->numStorageBuffers; + result->header.num_vertex_storage_textures = vertexShader->numStorageTextures; + result->header.num_fragment_samplers = fragmentShader->numSamplers; + result->header.num_fragment_uniform_buffers = fragmentShader->numUniformBuffers; + result->header.num_fragment_storage_buffers = fragmentShader->numStorageBuffers; + result->header.num_fragment_storage_textures = fragmentShader->numStorageTextures; return (SDL_GPUGraphicsPipeline *)result; } } @@ -2412,14 +2400,14 @@ static void METAL_BindGraphicsPipeline( metalCommandBuffer->needFragmentUniformBufferBind[i] = true; } - for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) { if (metalCommandBuffer->vertexUniformBuffers[i] == NULL) { metalCommandBuffer->vertexUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer); } } - for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) { + for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) { if (metalCommandBuffer->fragmentUniformBuffers[i] == NULL) { metalCommandBuffer->fragmentUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer); @@ -2650,11 +2638,11 @@ static void METAL_INTERNAL_BindGraphicsResources( // Vertex Samplers+Textures if (commandBuffer->needVertexSamplerBind) { - if (graphicsPipeline->vertexSamplerCount > 0) { + if (graphicsPipeline->header.num_vertex_samplers > 0) { [commandBuffer->renderEncoder setVertexSamplerStates:commandBuffer->vertexSamplers - withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)]; [commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexTextures - withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)]; } commandBuffer->needVertexSamplerBind = false; } @@ -2662,10 +2650,10 @@ static void METAL_INTERNAL_BindGraphicsResources( // Vertex Storage Textures if (commandBuffer->needVertexStorageTextureBind) { - if (graphicsPipeline->vertexStorageTextureCount > 0) { + if (graphicsPipeline->header.num_vertex_storage_textures > 0) { [commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexStorageTextures - withRange:NSMakeRange(graphicsPipeline->vertexSamplerCount, - graphicsPipeline->vertexStorageTextureCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_vertex_samplers, + graphicsPipeline->header.num_vertex_storage_textures)]; } commandBuffer->needVertexStorageTextureBind = false; } @@ -2673,20 +2661,20 @@ static void METAL_INTERNAL_BindGraphicsResources( // Vertex Storage Buffers if (commandBuffer->needVertexStorageBufferBind) { - if (graphicsPipeline->vertexStorageBufferCount > 0) { + if (graphicsPipeline->header.num_vertex_storage_buffers > 0) { [commandBuffer->renderEncoder setVertexBuffers:commandBuffer->vertexStorageBuffers offsets:offsets - withRange:NSMakeRange(graphicsPipeline->vertexUniformBufferCount, - graphicsPipeline->vertexStorageBufferCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_vertex_uniform_buffers, + graphicsPipeline->header.num_vertex_storage_buffers)]; } commandBuffer->needVertexStorageBufferBind = false; } // Vertex Uniform Buffers - for (Uint32 i = 0; i < graphicsPipeline->vertexUniformBufferCount; i += 1) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_uniform_buffers; i += 1) { if (commandBuffer->needVertexUniformBufferBind[i]) { - if (graphicsPipeline->vertexUniformBufferCount > i) { + if (graphicsPipeline->header.num_vertex_uniform_buffers > i) { [commandBuffer->renderEncoder setVertexBuffer:commandBuffer->vertexUniformBuffers[i]->handle offset:commandBuffer->vertexUniformBuffers[i]->drawOffset @@ -2699,11 +2687,11 @@ static void METAL_INTERNAL_BindGraphicsResources( // Fragment Samplers+Textures if (commandBuffer->needFragmentSamplerBind) { - if (graphicsPipeline->fragmentSamplerCount > 0) { + if (graphicsPipeline->header.num_fragment_samplers > 0) { [commandBuffer->renderEncoder setFragmentSamplerStates:commandBuffer->fragmentSamplers - withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)]; [commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentTextures - withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)]; + withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)]; } commandBuffer->needFragmentSamplerBind = false; } @@ -2711,10 +2699,10 @@ static void METAL_INTERNAL_BindGraphicsResources( // Fragment Storage Textures if (commandBuffer->needFragmentStorageTextureBind) { - if (graphicsPipeline->fragmentStorageTextureCount > 0) { + if (graphicsPipeline->header.num_fragment_storage_textures > 0) { [commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentStorageTextures - withRange:NSMakeRange(graphicsPipeline->fragmentSamplerCount, - graphicsPipeline->fragmentStorageTextureCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_fragment_samplers, + graphicsPipeline->header.num_fragment_storage_textures)]; } commandBuffer->needFragmentStorageTextureBind = false; } @@ -2722,20 +2710,20 @@ static void METAL_INTERNAL_BindGraphicsResources( // Fragment Storage Buffers if (commandBuffer->needFragmentStorageBufferBind) { - if (graphicsPipeline->fragmentStorageBufferCount > 0) { + if (graphicsPipeline->header.num_fragment_storage_buffers > 0) { [commandBuffer->renderEncoder setFragmentBuffers:commandBuffer->fragmentStorageBuffers offsets:offsets - withRange:NSMakeRange(graphicsPipeline->fragmentUniformBufferCount, - graphicsPipeline->fragmentStorageBufferCount)]; + withRange:NSMakeRange(graphicsPipeline->header.num_fragment_uniform_buffers, + graphicsPipeline->header.num_fragment_storage_buffers)]; } commandBuffer->needFragmentStorageBufferBind = false; } // Fragment Uniform Buffers - for (Uint32 i = 0; i < graphicsPipeline->fragmentUniformBufferCount; i += 1) { + for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_uniform_buffers; i += 1) { if (commandBuffer->needFragmentUniformBufferBind[i]) { - if (graphicsPipeline->fragmentUniformBufferCount > i) { + if (graphicsPipeline->header.num_fragment_uniform_buffers > i) { [commandBuffer->renderEncoder setFragmentBuffer:commandBuffer->fragmentUniformBuffers[i]->handle offset:commandBuffer->fragmentUniformBuffers[i]->drawOffset @@ -2754,38 +2742,38 @@ static void METAL_INTERNAL_BindComputeResources( NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 }; if (commandBuffer->needComputeSamplerBind) { - if (computePipeline->numSamplers > 0) { + if (computePipeline->header.numSamplers > 0) { [commandBuffer->computeEncoder setTextures:commandBuffer->computeSamplerTextures - withRange:NSMakeRange(0, computePipeline->numSamplers)]; + withRange:NSMakeRange(0, computePipeline->header.numSamplers)]; [commandBuffer->computeEncoder setSamplerStates:commandBuffer->computeSamplers - withRange:NSMakeRange(0, computePipeline->numSamplers)]; + withRange:NSMakeRange(0, computePipeline->header.numSamplers)]; } commandBuffer->needComputeSamplerBind = false; } if (commandBuffer->needComputeReadOnlyStorageTextureBind) { - if (computePipeline->numReadonlyStorageTextures > 0) { + if (computePipeline->header.numReadonlyStorageTextures > 0) { [commandBuffer->computeEncoder setTextures:commandBuffer->computeReadOnlyTextures withRange:NSMakeRange( - computePipeline->numSamplers, - computePipeline->numReadonlyStorageTextures)]; + computePipeline->header.numSamplers, + computePipeline->header.numReadonlyStorageTextures)]; } commandBuffer->needComputeReadOnlyStorageTextureBind = false; } if (commandBuffer->needComputeReadOnlyStorageBufferBind) { - if (computePipeline->numReadonlyStorageBuffers > 0) { + if (computePipeline->header.numReadonlyStorageBuffers > 0) { [commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadOnlyBuffers offsets:offsets - withRange:NSMakeRange(computePipeline->numUniformBuffers, - computePipeline->numReadonlyStorageBuffers)]; + withRange:NSMakeRange(computePipeline->header.numUniformBuffers, + computePipeline->header.numReadonlyStorageBuffers)]; } commandBuffer->needComputeReadOnlyStorageBufferBind = false; } for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) { if (commandBuffer->needComputeUniformBufferBind[i]) { - if (computePipeline->numUniformBuffers > i) { + if (computePipeline->header.numUniformBuffers > i) { [commandBuffer->computeEncoder setBuffer:commandBuffer->computeUniformBuffers[i]->handle offset:commandBuffer->computeUniformBuffers[i]->drawOffset @@ -3133,7 +3121,7 @@ static void METAL_BindComputePipeline( metalCommandBuffer->needComputeUniformBufferBind[i] = true; } - for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) { + for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) { if (metalCommandBuffer->computeUniformBuffers[i] == NULL) { metalCommandBuffer->computeUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer); @@ -3141,22 +3129,22 @@ static void METAL_BindComputePipeline( } // Bind write-only resources - if (pipeline->numReadWriteStorageTextures > 0) { + if (pipeline->header.numReadWriteStorageTextures > 0) { [metalCommandBuffer->computeEncoder setTextures:metalCommandBuffer->computeReadWriteTextures withRange:NSMakeRange( - pipeline->numSamplers + - pipeline->numReadonlyStorageTextures, - pipeline->numReadWriteStorageTextures)]; + pipeline->header.numSamplers + + pipeline->header.numReadonlyStorageTextures, + pipeline->header.numReadWriteStorageTextures)]; } NSUInteger offsets[MAX_COMPUTE_WRITE_BUFFERS] = { 0 }; - if (pipeline->numReadWriteStorageBuffers > 0) { + if (pipeline->header.numReadWriteStorageBuffers > 0) { [metalCommandBuffer->computeEncoder setBuffers:metalCommandBuffer->computeReadWriteBuffers offsets:offsets withRange:NSMakeRange( - pipeline->numUniformBuffers + - pipeline->numReadonlyStorageBuffers, - pipeline->numReadWriteStorageBuffers)]; + pipeline->header.numUniformBuffers + + pipeline->header.numReadonlyStorageBuffers, + pipeline->header.numReadWriteStorageBuffers)]; } } } @@ -4570,6 +4558,7 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD SDL_GPUDevice *result = SDL_calloc(1, sizeof(SDL_GPUDevice)); ASSIGN_DRIVER(METAL) result->driverData = (SDL_GPURenderer *)renderer; + result->shader_formats = SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB; renderer->sdlGPUDevice = result; return result; diff --git a/third-party/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c b/third-party/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c index fc10ba7621..4467ef801b 100644 --- a/third-party/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/third-party/SDL/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -822,13 +822,13 @@ typedef struct DescriptorSetLayout typedef struct GraphicsPipelineResourceLayoutHashTableKey { Uint32 vertexSamplerCount; - Uint32 vertexStorageBufferCount; Uint32 vertexStorageTextureCount; + Uint32 vertexStorageBufferCount; Uint32 vertexUniformBufferCount; Uint32 fragmentSamplerCount; - Uint32 fragmentStorageBufferCount; Uint32 fragmentStorageTextureCount; + Uint32 fragmentStorageBufferCount; Uint32 fragmentUniformBufferCount; } GraphicsPipelineResourceLayoutHashTableKey; @@ -846,18 +846,20 @@ typedef struct VulkanGraphicsPipelineResourceLayout DescriptorSetLayout *descriptorSetLayouts[4]; Uint32 vertexSamplerCount; - Uint32 vertexStorageBufferCount; Uint32 vertexStorageTextureCount; + Uint32 vertexStorageBufferCount; Uint32 vertexUniformBufferCount; Uint32 fragmentSamplerCount; - Uint32 fragmentStorageBufferCount; Uint32 fragmentStorageTextureCount; + Uint32 fragmentStorageBufferCount; Uint32 fragmentUniformBufferCount; } VulkanGraphicsPipelineResourceLayout; typedef struct VulkanGraphicsPipeline { + GraphicsPipelineCommonHeader header; + VkPipeline pipeline; SDL_GPUPrimitiveType primitiveType; @@ -901,6 +903,8 @@ typedef struct VulkanComputePipelineResourceLayout typedef struct VulkanComputePipeline { + ComputePipelineCommonHeader header; + VkShaderModule shaderModule; VkPipeline pipeline; VulkanComputePipelineResourceLayout *resourceLayout; @@ -1038,25 +1042,33 @@ typedef struct VulkanCommandBuffer Uint32 vertexBufferCount; bool needVertexBufferBind; - VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - VulkanBuffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + VkImageView vertexSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkSampler vertexSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkImageView vertexStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE]; + VkBuffer vertexStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE]; - VulkanTexture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanSampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanTexture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - VulkanBuffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + VkImageView fragmentSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkSampler fragmentSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkImageView fragmentStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE]; + VkBuffer fragmentStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE]; + VkImageView computeSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkSampler computeSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE]; + VkImageView readOnlyComputeStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE]; + VkBuffer readOnlyComputeStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE]; + + // Track these separately because barriers can happen mid compute pass + VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; + VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; + + VkImageView readWriteComputeStorageTextureViewBindings[MAX_COMPUTE_WRITE_TEXTURES]; + VkBuffer readWriteComputeStorageBufferBindings[MAX_COMPUTE_WRITE_BUFFERS]; + + // Track these separately because they are barriered when the compute pass begins VulkanTextureSubresource *readWriteComputeStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES]; Uint32 readWriteComputeStorageTextureSubresourceCount; VulkanBuffer *readWriteComputeStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS]; - VulkanTexture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanSampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; - VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; - VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; - // Uniform buffers VulkanUniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; @@ -5126,8 +5138,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pBufferInfo = NULL; - imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplers[i]->sampler; - imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextures[i]->fullView; + imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplerBindings[i]; + imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5150,7 +5162,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextures[i]->fullView; + imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5172,7 +5184,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -5245,8 +5257,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pBufferInfo = NULL; - imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplers[i]->sampler; - imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextures[i]->fullView; + imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplerBindings[i]; + imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5269,7 +5281,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextures[i]->fullView; + imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -5291,7 +5303,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -6565,6 +6577,16 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( &nameInfo); } + // Put this data in the pipeline we can do validation in gpu.c + graphicsPipeline->header.num_vertex_samplers = graphicsPipeline->resourceLayout->vertexSamplerCount; + graphicsPipeline->header.num_vertex_storage_buffers = graphicsPipeline->resourceLayout->vertexStorageBufferCount; + graphicsPipeline->header.num_vertex_storage_textures = graphicsPipeline->resourceLayout->vertexStorageTextureCount; + graphicsPipeline->header.num_vertex_uniform_buffers = graphicsPipeline->resourceLayout->vertexUniformBufferCount; + graphicsPipeline->header.num_fragment_samplers = graphicsPipeline->resourceLayout->fragmentSamplerCount; + graphicsPipeline->header.num_fragment_storage_buffers = graphicsPipeline->resourceLayout->fragmentStorageBufferCount; + graphicsPipeline->header.num_fragment_storage_textures = graphicsPipeline->resourceLayout->fragmentStorageTextureCount; + graphicsPipeline->header.num_fragment_uniform_buffers = graphicsPipeline->resourceLayout->fragmentUniformBufferCount; + return (SDL_GPUGraphicsPipeline *)graphicsPipeline; } @@ -6659,6 +6681,14 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline( &nameInfo); } + // Track these here for debug layer + vulkanComputePipeline->header.numSamplers = vulkanComputePipeline->resourceLayout->numSamplers; + vulkanComputePipeline->header.numReadonlyStorageTextures = vulkanComputePipeline->resourceLayout->numReadonlyStorageTextures; + vulkanComputePipeline->header.numReadonlyStorageBuffers = vulkanComputePipeline->resourceLayout->numReadonlyStorageBuffers; + vulkanComputePipeline->header.numReadWriteStorageTextures = vulkanComputePipeline->resourceLayout->numReadWriteStorageTextures; + vulkanComputePipeline->header.numReadWriteStorageBuffers = vulkanComputePipeline->resourceLayout->numReadWriteStorageBuffers; + vulkanComputePipeline->header.numUniformBuffers = vulkanComputePipeline->resourceLayout->numUniformBuffers; + return (SDL_GPUComputePipeline *)vulkanComputePipeline; } @@ -7457,21 +7487,21 @@ static void VULKAN_BindVertexSamplers( VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler; - if (vulkanCommandBuffer->vertexSamplers[firstSlot + i] != sampler) { + if (vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] != sampler->sampler) { VULKAN_INTERNAL_TrackSampler( vulkanCommandBuffer, (VulkanSampler *)textureSamplerBindings[i].sampler); - vulkanCommandBuffer->vertexSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler; + vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] = sampler->sampler; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } - if (vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } } @@ -7488,12 +7518,12 @@ static void VULKAN_BindVertexStorageTextures( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; - if (vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } } @@ -7510,12 +7540,12 @@ static void VULKAN_BindVertexStorageBuffers( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanBufferContainer *bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; - if (vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) { + if (vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) { VULKAN_INTERNAL_TrackBuffer( vulkanCommandBuffer, bufferContainer->activeBuffer); - vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; + vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; } } @@ -7533,21 +7563,21 @@ static void VULKAN_BindFragmentSamplers( VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler; - if (vulkanCommandBuffer->fragmentSamplers[firstSlot + i] != sampler) { + if (vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] != sampler->sampler) { VULKAN_INTERNAL_TrackSampler( vulkanCommandBuffer, (VulkanSampler *)textureSamplerBindings[i].sampler); - vulkanCommandBuffer->fragmentSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler; + vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] = sampler->sampler; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } - if (vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } } @@ -7564,12 +7594,12 @@ static void VULKAN_BindFragmentStorageTextures( for (Uint32 i = 0; i < numBindings; i += 1) { VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; - if (vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } } @@ -7588,12 +7618,12 @@ static void VULKAN_BindFragmentStorageBuffers( for (i = 0; i < numBindings; i += 1) { bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; - if (vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) { + if (vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) { VULKAN_INTERNAL_TrackBuffer( vulkanCommandBuffer, bufferContainer->activeBuffer); - vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; + vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; } } @@ -8107,15 +8137,15 @@ static void VULKAN_EndRenderPass( SDL_zeroa(vulkanCommandBuffer->vertexBufferOffsets); vulkanCommandBuffer->vertexBufferCount = 0; - SDL_zeroa(vulkanCommandBuffer->vertexSamplers); - SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextures); - SDL_zeroa(vulkanCommandBuffer->vertexStorageTextures); - SDL_zeroa(vulkanCommandBuffer->vertexStorageBuffers); + SDL_zeroa(vulkanCommandBuffer->vertexSamplerBindings); + SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->vertexStorageTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->vertexStorageBufferBindings); - SDL_zeroa(vulkanCommandBuffer->fragmentSamplers); - SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextures); - SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextures); - SDL_zeroa(vulkanCommandBuffer->fragmentStorageBuffers); + SDL_zeroa(vulkanCommandBuffer->fragmentSamplerBindings); + SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->fragmentStorageBufferBindings); } static void VULKAN_BeginComputePass( @@ -8145,6 +8175,7 @@ static void VULKAN_BeginComputePass( VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE); vulkanCommandBuffer->readWriteComputeStorageTextureSubresources[i] = subresource; + vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings[i] = subresource->computeWriteView; VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, @@ -8161,6 +8192,7 @@ static void VULKAN_BeginComputePass( VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE); vulkanCommandBuffer->readWriteComputeStorageBuffers[i] = buffer; + vulkanCommandBuffer->readWriteComputeStorageBufferBindings[i] = buffer->buffer; VULKAN_INTERNAL_TrackBuffer( vulkanCommandBuffer, @@ -8212,21 +8244,21 @@ static void VULKAN_BindComputeSamplers( VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler; - if (vulkanCommandBuffer->computeSamplers[firstSlot + i] != sampler) { + if (vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] != sampler->sampler) { VULKAN_INTERNAL_TrackSampler( vulkanCommandBuffer, sampler); - vulkanCommandBuffer->computeSamplers[firstSlot + i] = sampler; + vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] = sampler->sampler; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } - if (vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] != textureContainer->activeTexture) { + if (vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) { VULKAN_INTERNAL_TrackTexture( vulkanCommandBuffer, textureContainer->activeTexture); - vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } } @@ -8267,6 +8299,7 @@ static void VULKAN_BindComputeStorageTextures( textureContainer->activeTexture); vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] = textureContainer->activeTexture; + vulkanCommandBuffer->readOnlyComputeStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } } @@ -8306,6 +8339,7 @@ static void VULKAN_BindComputeStorageBuffers( bufferContainer->activeBuffer); vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; + vulkanCommandBuffer->readOnlyComputeStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; } } @@ -8380,8 +8414,8 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pBufferInfo = NULL; - imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplers[i]->sampler; - imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextures[i]->fullView; + imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplerBindings[i]; + imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -8404,7 +8438,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextures[i]->fullView; + imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -8426,7 +8460,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -8461,7 +8495,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pBufferInfo = NULL; imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE; - imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureSubresources[i]->computeWriteView; + imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureViewBindings[i]; imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL; currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount]; @@ -8483,7 +8517,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets( currentWriteDescriptorSet->pTexelBufferView = NULL; currentWriteDescriptorSet->pImageInfo = NULL; - bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBuffers[i]->buffer; + bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBufferBindings[i]; bufferInfos[bufferInfoCount].offset = 0; bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE; @@ -8650,9 +8684,12 @@ static void VULKAN_EndComputePass( } } - // we don't need a barrier because sampler state is always the default if sampler bit is set - SDL_zeroa(vulkanCommandBuffer->computeSamplerTextures); - SDL_zeroa(vulkanCommandBuffer->computeSamplers); + // we don't need a barrier for sampler resources because sampler state is always the default if sampler bit is set + SDL_zeroa(vulkanCommandBuffer->computeSamplerTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->computeSamplerBindings); + + SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings); + SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageBufferBindings); vulkanCommandBuffer->currentComputePipeline = NULL; @@ -9518,21 +9555,23 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer( SDL_zeroa(commandBuffer->vertexBufferOffsets); commandBuffer->vertexBufferCount = 0; - SDL_zeroa(commandBuffer->vertexSamplerTextures); - SDL_zeroa(commandBuffer->vertexSamplers); - SDL_zeroa(commandBuffer->vertexStorageTextures); - SDL_zeroa(commandBuffer->vertexStorageBuffers); + SDL_zeroa(commandBuffer->vertexSamplerTextureViewBindings); + SDL_zeroa(commandBuffer->vertexSamplerBindings); + SDL_zeroa(commandBuffer->vertexStorageTextureViewBindings); + SDL_zeroa(commandBuffer->vertexStorageBufferBindings); - SDL_zeroa(commandBuffer->fragmentSamplerTextures); - SDL_zeroa(commandBuffer->fragmentSamplers); - SDL_zeroa(commandBuffer->fragmentStorageTextures); - SDL_zeroa(commandBuffer->fragmentStorageBuffers); + SDL_zeroa(commandBuffer->fragmentSamplerTextureViewBindings); + SDL_zeroa(commandBuffer->fragmentSamplerBindings); + SDL_zeroa(commandBuffer->fragmentStorageTextureViewBindings); + SDL_zeroa(commandBuffer->fragmentStorageBufferBindings); SDL_zeroa(commandBuffer->readWriteComputeStorageTextureSubresources); commandBuffer->readWriteComputeStorageTextureSubresourceCount = 0; SDL_zeroa(commandBuffer->readWriteComputeStorageBuffers); - SDL_zeroa(commandBuffer->computeSamplerTextures); - SDL_zeroa(commandBuffer->computeSamplers); + SDL_zeroa(commandBuffer->computeSamplerTextureViewBindings); + SDL_zeroa(commandBuffer->computeSamplerBindings); + SDL_zeroa(commandBuffer->readOnlyComputeStorageTextureViewBindings); + SDL_zeroa(commandBuffer->readOnlyComputeStorageBufferBindings); SDL_zeroa(commandBuffer->readOnlyComputeStorageTextures); SDL_zeroa(commandBuffer->readOnlyComputeStorageBuffers); @@ -11693,6 +11732,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S ASSIGN_DRIVER(VULKAN) result->driverData = (SDL_GPURenderer *)renderer; + result->shader_formats = SDL_GPU_SHADERFORMAT_SPIRV; /* * Create initial swapchain array diff --git a/third-party/SDL/src/joystick/SDL_gamepad.c b/third-party/SDL/src/joystick/SDL_gamepad.c index 86dd062769..385e890cf9 100644 --- a/third-party/SDL/src/joystick/SDL_gamepad.c +++ b/third-party/SDL/src/joystick/SDL_gamepad.c @@ -2754,6 +2754,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) gamepad->joystick = SDL_OpenJoystick(instance_id); if (!gamepad->joystick) { + SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false); SDL_free(gamepad); SDL_UnlockJoysticks(); return NULL; @@ -2762,6 +2763,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) if (gamepad->joystick->naxes) { gamepad->last_match_axis = (SDL_GamepadBinding **)SDL_calloc(gamepad->joystick->naxes, sizeof(*gamepad->last_match_axis)); if (!gamepad->last_match_axis) { + SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false); SDL_CloseJoystick(gamepad->joystick); SDL_free(gamepad); SDL_UnlockJoysticks(); @@ -2771,6 +2773,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) if (gamepad->joystick->nhats) { gamepad->last_hat_mask = (Uint8 *)SDL_calloc(gamepad->joystick->nhats, sizeof(*gamepad->last_hat_mask)); if (!gamepad->last_hat_mask) { + SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false); SDL_CloseJoystick(gamepad->joystick); SDL_free(gamepad->last_match_axis); SDL_free(gamepad); diff --git a/third-party/SDL/src/joystick/SDL_joystick.c b/third-party/SDL/src/joystick/SDL_joystick.c index 7878b7cc68..921576854e 100644 --- a/third-party/SDL/src/joystick/SDL_joystick.c +++ b/third-party/SDL/src/joystick/SDL_joystick.c @@ -1190,9 +1190,35 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id) // If this joystick is known to have all zero centered axes, skip the auto-centering code if (SDL_JoystickAxesCenteredAtZero(joystick)) { - int i; + for (int i = 0; i < joystick->naxes; ++i) { + joystick->axes[i].has_initial_value = true; + } + } - for (i = 0; i < joystick->naxes; ++i) { + // We know the initial values for HIDAPI and XInput joysticks + if ((SDL_IsJoystickHIDAPI(joystick->guid) || + SDL_IsJoystickXInput(joystick->guid) || + SDL_IsJoystickRAWINPUT(joystick->guid) || + SDL_IsJoystickWGI(joystick->guid)) && + joystick->naxes >= SDL_GAMEPAD_AXIS_COUNT) { + int left_trigger, right_trigger; + if (SDL_IsJoystickXInput(joystick->guid)) { + left_trigger = 2; + right_trigger = 5; + } else { + left_trigger = SDL_GAMEPAD_AXIS_LEFT_TRIGGER; + right_trigger = SDL_GAMEPAD_AXIS_RIGHT_TRIGGER; + } + for (int i = 0; i < SDL_GAMEPAD_AXIS_COUNT; ++i) { + int initial_value; + if (i == left_trigger || i == right_trigger) { + initial_value = SDL_MIN_SINT16; + } else { + initial_value = 0; + } + joystick->axes[i].value = initial_value; + joystick->axes[i].zero = initial_value; + joystick->axes[i].initial_value = initial_value; joystick->axes[i].has_initial_value = true; } } diff --git a/third-party/SDL/src/joystick/hidapi/SDL_hidapijoystick.c b/third-party/SDL/src/joystick/hidapi/SDL_hidapijoystick.c index 6293519ca6..c7607aeadf 100644 --- a/third-party/SDL/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/third-party/SDL/src/joystick/hidapi/SDL_hidapijoystick.c @@ -751,11 +751,12 @@ bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoysti ++SDL_HIDAPI_numjoysticks; - SDL_PrivateJoystickAdded(joystickID); - if (pJoystickID) { *pJoystickID = joystickID; } + + SDL_PrivateJoystickAdded(joystickID); + return true; } @@ -1051,6 +1052,11 @@ static bool HIDAPI_CreateCombinedJoyCons(void) info.usage = USB_USAGE_GENERIC_GAMEPAD; info.manufacturer_string = L"Nintendo"; info.product_string = L"Switch Joy-Con (L/R)"; + if (children[0]->is_bluetooth || children[1]->is_bluetooth) { + info.bus_type = SDL_HID_API_BUS_BLUETOOTH; + } else { + info.bus_type = SDL_HID_API_BUS_USB; + } combined = HIDAPI_AddDevice(&info, 2, children); if (combined && combined->driver) { diff --git a/third-party/SDL/src/joystick/windows/SDL_rawinputjoystick.c b/third-party/SDL/src/joystick/windows/SDL_rawinputjoystick.c index f37a1d81ce..8590d9a836 100644 --- a/third-party/SDL/src/joystick/windows/SDL_rawinputjoystick.c +++ b/third-party/SDL/src/joystick/windows/SDL_rawinputjoystick.c @@ -1030,7 +1030,7 @@ static bool RAWINPUT_JoystickInit(void) { SDL_assert(!SDL_RAWINPUT_inited); - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, true)) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false)) { return true; } diff --git a/third-party/SDL/src/render/ps2/SDL_render_ps2.c b/third-party/SDL/src/render/ps2/SDL_render_ps2.c index 713192c908..f414fbd0cd 100644 --- a/third-party/SDL/src/render/ps2/SDL_render_ps2.c +++ b/third-party/SDL/src/render/ps2/SDL_render_ps2.c @@ -60,7 +60,7 @@ typedef struct static int vsync_sema_id = 0; // PRIVATE METHODS -static int vsync_handler(void) +static int vsync_handler(int reason) { iSignalSema(vsync_sema_id); diff --git a/third-party/SDL/src/storage/SDL_storage.c b/third-party/SDL/src/storage/SDL_storage.c index 75952ffd23..7c395b36a8 100644 --- a/third-party/SDL/src/storage/SDL_storage.c +++ b/third-party/SDL/src/storage/SDL_storage.c @@ -34,6 +34,9 @@ static TitleStorageBootStrap *titlebootstrap[] = { static UserStorageBootStrap *userbootstrap[] = { #ifdef SDL_STORAGE_STEAM &STEAM_userbootstrap, +#endif +#ifdef SDL_STORAGE_PRIVATE + &PRIVATE_userbootstrap, #endif &GENERIC_userbootstrap, NULL diff --git a/third-party/SDL/src/storage/SDL_sysstorage.h b/third-party/SDL/src/storage/SDL_sysstorage.h index 57d60d6474..f047e551f9 100644 --- a/third-party/SDL/src/storage/SDL_sysstorage.h +++ b/third-party/SDL/src/storage/SDL_sysstorage.h @@ -44,6 +44,7 @@ extern TitleStorageBootStrap GENERIC_titlebootstrap; // Steam does not have title storage APIs extern UserStorageBootStrap GENERIC_userbootstrap; +extern UserStorageBootStrap PRIVATE_userbootstrap; extern UserStorageBootStrap STEAM_userbootstrap; extern SDL_Storage *GENERIC_OpenFileStorage(const char *path); diff --git a/third-party/SDL/src/tray/unix/SDL_tray.c b/third-party/SDL/src/tray/unix/SDL_tray.c index 1c305a966c..e8a7b0d7ee 100644 --- a/third-party/SDL/src/tray/unix/SDL_tray.c +++ b/third-party/SDL/src/tray/unix/SDL_tray.c @@ -541,7 +541,7 @@ SDL_TrayMenu *SDL_CreateTraySubmenu(SDL_TrayEntry *entry) return NULL; } - entry->submenu->menu = (GtkMenuShell *)gtk_menu_new(); + entry->submenu->menu = g_object_ref_sink(gtk_menu_new()); entry->submenu->parent_tray = NULL; entry->submenu->parent_entry = entry; entry->submenu->nEntries = 0; diff --git a/third-party/SDL/src/video/SDL_sysvideo.h b/third-party/SDL/src/video/SDL_sysvideo.h index 6da8bd2e18..ad5bed288b 100644 --- a/third-party/SDL/src/video/SDL_sysvideo.h +++ b/third-party/SDL/src/video/SDL_sysvideo.h @@ -396,8 +396,7 @@ struct SDL_VideoDevice bool checked_texture_framebuffer; bool is_dummy; bool suspend_screensaver; - SDL_Window *wakeup_window; - SDL_Mutex *wakeup_lock; // Initialized only if WaitEventTimeout/SendWakeupEvent are supported + void *wakeup_window; int num_displays; SDL_VideoDisplay **displays; SDL_Rect desktop_bounds; diff --git a/third-party/SDL/src/video/SDL_video.c b/third-party/SDL/src/video/SDL_video.c index abeb2cb6b5..db38a19d0d 100644 --- a/third-party/SDL/src/video/SDL_video.c +++ b/third-party/SDL/src/video/SDL_video.c @@ -2513,7 +2513,9 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props) SDL_UpdateWindowHierarchy(window, parent); if (_this->CreateSDLWindow && !_this->CreateSDLWindow(_this, window, props)) { + PUSH_SDL_ERROR() SDL_DestroyWindow(window); + POP_SDL_ERROR() return NULL; } @@ -2761,7 +2763,7 @@ SDL_Window *SDL_GetWindowFromID(SDL_WindowID id) } } } - SDL_SetError("Invalid window ID"); \ + SDL_SetError("Invalid window ID"); return NULL; } @@ -4279,9 +4281,7 @@ void SDL_DestroyWindow(SDL_Window *window) _this->current_glwin = NULL; } - if (_this->wakeup_window == window) { - _this->wakeup_window = NULL; - } + SDL_CompareAndSwapAtomicPointer(&_this->wakeup_window, window, NULL); // Now invalidate magic SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, false); @@ -5034,8 +5034,7 @@ bool SDL_GL_GetAttribute(SDL_GLAttr attr, int *value) } if (fbo_type != GL_NONE) { glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *)value); - } - else { + } else { *value = 0; } if (glBindFramebufferFunc && (current_fbo != 0)) { @@ -5266,7 +5265,7 @@ bool SDL_GL_SwapWindow(SDL_Window *window) bool SDL_GL_DestroyContext(SDL_GLContext context) { if (!_this) { - return SDL_UninitializedVideo(); \ + return SDL_UninitializedVideo(); } if (!context) { return SDL_InvalidParamError("context"); diff --git a/third-party/SDL/src/video/cocoa/SDL_cocoaclipboard.m b/third-party/SDL/src/video/cocoa/SDL_cocoaclipboard.m index 42c2ad64ba..7039ff6ad5 100644 --- a/third-party/SDL/src/video/cocoa/SDL_cocoaclipboard.m +++ b/third-party/SDL/src/video/cocoa/SDL_cocoaclipboard.m @@ -158,6 +158,17 @@ bool Cocoa_SetClipboardData(SDL_VideoDevice *_this) @autoreleasepool { SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal; NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + + // SetClipboardText specialization so text is available after the app quits + if (_this->clipboard_callback && _this->num_clipboard_mime_types == 1) { + if (SDL_strncmp(_this->clipboard_mime_types[0], "text/plain;charset=utf-8", 24) == 0) { + [pasteboard declareTypes:@[ NSPasteboardTypeString ] owner:nil]; + [pasteboard setString:@((char *)_this->clipboard_userdata) forType:NSPasteboardTypeString]; + data.clipboard_count = [pasteboard changeCount]; + return true; + } + } + NSPasteboardItem *newItem = [NSPasteboardItem new]; NSMutableArray *utiTypes = [NSMutableArray new]; Cocoa_PasteboardDataProvider *provider = [[Cocoa_PasteboardDataProvider alloc] initWith: _this->clipboard_callback userData: _this->clipboard_userdata]; diff --git a/third-party/SDL/src/video/cocoa/SDL_cocoamouse.m b/third-party/SDL/src/video/cocoa/SDL_cocoamouse.m index 530ca0c874..f8f582972f 100644 --- a/third-party/SDL/src/video/cocoa/SDL_cocoamouse.m +++ b/third-party/SDL/src/video/cocoa/SDL_cocoamouse.m @@ -450,12 +450,18 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event) // All events except NSEventTypeMouseExited can only happen if the window // has mouse focus, so we'll always set the focus even if we happen to miss // NSEventTypeMouseEntered, which apparently happens if the window is - // created under the mouse on macOS 12.7 + // created under the mouse on macOS 12.7. But, only set the focus if + // the event acutally has a non-NULL window, otherwise what would happen + // is that after an NSEventTypeMouseEntered there would sometimes be + // NSEventTypeMouseMoved without a window causing us to suppress subsequent + // mouse move events. NSEventType event_type = [event type]; if (event_type == NSEventTypeMouseExited) { Cocoa_MouseFocus = NULL; } else { - Cocoa_MouseFocus = [event window]; + if ([event window] != NULL) { + Cocoa_MouseFocus = [event window]; + } } switch (event_type) { diff --git a/third-party/SDL/src/video/cocoa/SDL_cocoavideo.m b/third-party/SDL/src/video/cocoa/SDL_cocoavideo.m index 81baf7825f..aed193df44 100644 --- a/third-party/SDL/src/video/cocoa/SDL_cocoavideo.m +++ b/third-party/SDL/src/video/cocoa/SDL_cocoavideo.m @@ -49,9 +49,6 @@ static void Cocoa_VideoQuit(SDL_VideoDevice *_this); static void Cocoa_DeleteDevice(SDL_VideoDevice *device) { @autoreleasepool { - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } CFBridgingRelease(device->internal); SDL_free(device); } @@ -81,7 +78,6 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void) return NULL; } device->internal = (SDL_VideoData *)CFBridgingRetain(data); - device->wakeup_lock = SDL_CreateMutex(); device->system_theme = Cocoa_GetSystemTheme(); // Set the function pointers diff --git a/third-party/SDL/src/video/cocoa/SDL_cocoawindow.m b/third-party/SDL/src/video/cocoa/SDL_cocoawindow.m index 3e9642a3c0..7be564af0f 100644 --- a/third-party/SDL/src/video/cocoa/SDL_cocoawindow.m +++ b/third-party/SDL/src/video/cocoa/SDL_cocoawindow.m @@ -2022,6 +2022,7 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL @interface SDL3View : NSView { SDL_Window *_sdlWindow; + NSTrackingArea *_trackingArea; // only used on macOS <= 11.0 } - (void)setSDLWindow:(SDL_Window *)window; @@ -2033,6 +2034,7 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent; - (BOOL)wantsUpdateLayer; - (void)updateLayer; +- (void)updateTrackingAreas; @end @implementation SDL3View @@ -2113,6 +2115,21 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL } } +- (void)updateTrackingAreas +{ + [super updateTrackingAreas]; + + if (@available(macOS 12.0, *)) { + // we (currently) use the tracking areas as a workaround for older macOSes, but we might be safe everywhere... + } else { + SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)_sdlWindow->internal; + if (_trackingArea) { + [self removeTrackingArea:_trackingArea]; + } + _trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:windata.listener userInfo:nil]; + [self addTrackingArea:_trackingArea]; + } +} @end static void Cocoa_UpdateMouseFocus() diff --git a/third-party/SDL/src/video/emscripten/SDL_emscriptenvideo.c b/third-party/SDL/src/video/emscripten/SDL_emscriptenvideo.c index 1496268610..e735ee8215 100644 --- a/third-party/SDL/src/video/emscripten/SDL_emscriptenvideo.c +++ b/third-party/SDL/src/video/emscripten/SDL_emscriptenvideo.c @@ -64,7 +64,7 @@ static SDL_SystemTheme Emscripten_GetSystemTheme(void) /* Technically, light theme can mean explicit light theme or no preference. https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme#syntax */ - int theme_code = EM_ASM_INT({ + int theme_code = MAIN_THREAD_EM_ASM_INT({ if (!window.matchMedia) { return -1; } diff --git a/third-party/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c b/third-party/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c index be1db82bd4..adca91c9fd 100644 --- a/third-party/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/third-party/SDL/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1368,9 +1368,14 @@ bool KMSDRM_CreateSurfaces(SDL_VideoDevice *_this, SDL_Window *window) windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, dispdata->mode.hdisplay, dispdata->mode.vdisplay, surface_fmt, surface_flags); - + if (!windata->gs && errno == ENOSYS) { + // Try again without the scanout flags, needed on NVIDIA drivers + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, + dispdata->mode.hdisplay, dispdata->mode.vdisplay, + surface_fmt, 0); + } if (!windata->gs) { - return SDL_SetError("Could not create GBM surface"); + return SDL_SetError("Could not create GBM surface: %s", strerror(errno)); } /* We can't get the EGL context yet because SDL_CreateRenderer has not been called, @@ -1729,9 +1734,9 @@ bool KMSDRM_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Propert } /* Create the window surfaces with the size we have just chosen. - Needs the window diverdata in place. */ + Needs the window driverdata in place. */ if (!KMSDRM_CreateSurfaces(_this, window)) { - return SDL_SetError("Can't window GBM/EGL surfaces on window creation."); + return false; } } // NON-Vulkan block ends. diff --git a/third-party/SDL/src/video/psp/SDL_pspvideo.c b/third-party/SDL/src/video/psp/SDL_pspvideo.c index 2458235ee2..afdb6bbae3 100644 --- a/third-party/SDL/src/video/psp/SDL_pspvideo.c +++ b/third-party/SDL/src/video/psp/SDL_pspvideo.c @@ -118,6 +118,8 @@ static SDL_VideoDevice *PSP_Create(void) device->PumpEvents = PSP_PumpEvents; + device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY; + return device; } diff --git a/third-party/SDL/src/video/vita/SDL_vitavideo.c b/third-party/SDL/src/video/vita/SDL_vitavideo.c index 6b5dbd78d0..3455dba300 100644 --- a/third-party/SDL/src/video/vita/SDL_vitavideo.c +++ b/third-party/SDL/src/video/vita/SDL_vitavideo.c @@ -153,6 +153,8 @@ static SDL_VideoDevice *VITA_Create(void) device->PumpEvents = VITA_PumpEvents; + device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY; + return device; } diff --git a/third-party/SDL/src/video/vita/SDL_vitavideo.h b/third-party/SDL/src/video/vita/SDL_vitavideo.h index 268bed84ae..f5b397b34d 100644 --- a/third-party/SDL/src/video/vita/SDL_vitavideo.h +++ b/third-party/SDL/src/video/vita/SDL_vitavideo.h @@ -60,8 +60,6 @@ extern SDL_Window *Vita_Window; // Display and window functions extern bool VITA_VideoInit(SDL_VideoDevice *_this); extern void VITA_VideoQuit(SDL_VideoDevice *_this); -extern bool VITA_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display); -extern bool VITA_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); extern bool VITA_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); extern void VITA_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); extern bool VITA_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/third-party/SDL/src/video/wayland/SDL_waylandevents.c b/third-party/SDL/src/video/wayland/SDL_waylandevents.c index ce32eb1aa9..291a467647 100644 --- a/third-party/SDL/src/video/wayland/SDL_waylandevents.c +++ b/third-party/SDL/src/video/wayland/SDL_waylandevents.c @@ -199,7 +199,6 @@ static Uint64 Wayland_EventTimestampMSToNS(Uint32 wl_timestamp_ms) timestamp_offset += SDL_MS_TO_NS(SDL_UINT64_C(0x100000000)); } last = wl_timestamp_ms; - wl_timestamp_ms += timestamp_offset; return SDL_MS_TO_NS(wl_timestamp_ms) + timestamp_offset; } @@ -213,11 +212,6 @@ static Uint64 Wayland_GetKeyboardTimestamp(struct SDL_WaylandInput *input, Uint3 return 0; } -static Uint64 Wayland_GetKeyboardTimestampRaw(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms) -{ - return input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : Wayland_EventTimestampMSToNS(wl_timestamp_ms); -} - static Uint64 Wayland_GetPointerTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms) { if (wl_timestamp_ms) { @@ -273,10 +267,11 @@ void Wayland_CreateCursorShapeDevice(struct SDL_WaylandInput *input) static bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, Uint64 elapsed) { bool ret = false; + while (elapsed >= repeat_info->next_repeat_ns) { if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) { - const Uint64 timestamp = repeat_info->wl_press_time_ns + repeat_info->next_repeat_ns; - SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetEventTimestamp(timestamp), repeat_info->keyboard_id, repeat_info->key, repeat_info->scancode, true); + const Uint64 timestamp = repeat_info->base_time_ns + repeat_info->next_repeat_ns; + SDL_SendKeyboardKeyIgnoreModifiers(timestamp, repeat_info->keyboard_id, repeat_info->key, repeat_info->scancode, true); } if (repeat_info->text[0]) { SDL_SendKeyboardText(repeat_info->text); @@ -295,8 +290,8 @@ static void keyboard_repeat_clear(SDL_WaylandKeyboardRepeat *repeat_info) repeat_info->is_key_down = false; } -static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, Uint32 keyboard_id, uint32_t key, Uint64 wl_press_time_ns, - uint32_t scancode, bool has_text, char text[8]) +static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, Uint32 keyboard_id, uint32_t key, Uint32 wl_press_time_ms, + Uint64 base_time_ns, uint32_t scancode, bool has_text, char text[8]) { if (!repeat_info->is_initialized || !repeat_info->repeat_rate) { return; @@ -304,12 +299,13 @@ static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, Uint32 k repeat_info->is_key_down = true; repeat_info->keyboard_id = keyboard_id; repeat_info->key = key; - repeat_info->wl_press_time_ns = wl_press_time_ns; + repeat_info->wl_press_time_ms = wl_press_time_ms; + repeat_info->base_time_ns = base_time_ns; repeat_info->sdl_press_time_ns = SDL_GetTicksNS(); repeat_info->next_repeat_ns = SDL_MS_TO_NS(repeat_info->repeat_delay_ms); repeat_info->scancode = scancode; if (has_text) { - SDL_copyp(repeat_info->text, text); + SDL_memcpy(repeat_info->text, text, sizeof(repeat_info->text)); } else { repeat_info->text[0] = '\0'; } @@ -1859,7 +1855,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, char text[8]; bool has_text = false; bool handled_by_ime = false; - const Uint64 timestamp_raw_ns = Wayland_GetKeyboardTimestampRaw(input, time); + const Uint64 timestamp_ns = Wayland_GetKeyboardTimestamp(input, time); Wayland_UpdateImplicitGrabSerial(input, serial); @@ -1875,7 +1871,8 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, * Using SDL_GetTicks would be wrong, as it would report when the release event is processed, * which may be off if the application hasn't pumped events for a while. */ - keyboard_repeat_handle(&input->keyboard_repeat, timestamp_raw_ns - input->keyboard_repeat.wl_press_time_ns); + const Uint64 elapsed = SDL_MS_TO_NS(time - input->keyboard_repeat.wl_press_time_ms); + keyboard_repeat_handle(&input->keyboard_repeat, elapsed); keyboard_repeat_clear(&input->keyboard_repeat); } keyboard_input_get_text(text, input, key, false, &handled_by_ime); @@ -1883,9 +1880,8 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, const SDL_Scancode scancode = Wayland_GetScancodeForKey(input, key); Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); - Uint64 timestamp = Wayland_GetKeyboardTimestamp(input, time); - SDL_SendKeyboardKeyIgnoreModifiers(timestamp, input->keyboard_id, key, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); + SDL_SendKeyboardKeyIgnoreModifiers(timestamp_ns, input->keyboard_id, key, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (has_text && !(SDL_GetModState() & (SDL_KMOD_CTRL | SDL_KMOD_ALT))) { @@ -1894,7 +1890,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, } } if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) { - keyboard_repeat_set(&input->keyboard_repeat, input->keyboard_id, key, timestamp_raw_ns, scancode, has_text, text); + keyboard_repeat_set(&input->keyboard_repeat, input->keyboard_id, key, time, timestamp_ns, scancode, has_text, text); } } } diff --git a/third-party/SDL/src/video/wayland/SDL_waylandevents_c.h b/third-party/SDL/src/video/wayland/SDL_waylandevents_c.h index 6158882ac5..d961b37ce5 100644 --- a/third-party/SDL/src/video/wayland/SDL_waylandevents_c.h +++ b/third-party/SDL/src/video/wayland/SDL_waylandevents_c.h @@ -49,17 +49,18 @@ typedef struct SDL_WaylandTabletInput typedef struct { - int32_t repeat_rate; // Repeat rate in range of [1, 1000] character(s) per second - int32_t repeat_delay_ms; // Time to first repeat event in milliseconds - Uint32 keyboard_id; // ID of the source keyboard. + Sint32 repeat_rate; // Repeat rate in range of [1, 1000] character(s) per second + Sint32 repeat_delay_ms; // Time to first repeat event in milliseconds + Uint32 keyboard_id; // ID of the source keyboard. bool is_initialized; bool is_key_down; - uint32_t key; - Uint64 wl_press_time_ns; // Key press time as reported by the Wayland API + Uint32 key; + Uint32 wl_press_time_ms; // Key press time as reported by the Wayland API in milliseconds + Uint64 base_time_ns; // Key press time as reported by the Wayland API in nanoseconds Uint64 sdl_press_time_ns; // Key press time expressed in SDL ticks Uint64 next_repeat_ns; // Next repeat event in nanoseconds - uint32_t scancode; + Uint32 scancode; char text[8]; } SDL_WaylandKeyboardRepeat; diff --git a/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.c b/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.c index df1628cd5b..6712f9d8c4 100644 --- a/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.c +++ b/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.c @@ -58,7 +58,7 @@ bool Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop if (internal->text_input_manager) { if (input && input->text_input) { - const SDL_Rect *rect = &input->text_input->cursor_rect; + const SDL_Rect *rect = &input->text_input->text_input_rect; enum zwp_text_input_v3_content_hint hint = ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE; enum zwp_text_input_v3_content_purpose purpose; @@ -125,12 +125,21 @@ bool Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop // Now that it's enabled, set the input properties zwp_text_input_v3_set_content_type(input->text_input->text_input, hint, purpose); if (!SDL_RectEmpty(rect)) { - // This gets reset on enable so we have to cache it + SDL_WindowData *wind = window->internal; + const SDL_Rect scaled_rect = { + (int)SDL_floor(window->text_input_rect.x / wind->pointer_scale.x), + (int)SDL_floor(window->text_input_rect.y / wind->pointer_scale.y), + (int)SDL_ceil(window->text_input_rect.w / wind->pointer_scale.x), + (int)SDL_ceil(window->text_input_rect.h / wind->pointer_scale.y) + }; + const int scaled_cursor = (int)SDL_floor(window->text_input_cursor / wind->pointer_scale.x); + + // Clamp the x value so it doesn't run too far past the end of the text input area. zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, - rect->x, - rect->y, - rect->w, - rect->h); + SDL_min(scaled_rect.x + scaled_cursor, scaled_rect.x + scaled_rect.w), + scaled_rect.y, + 1, + scaled_rect.h); } zwp_text_input_v3_commit(input->text_input->text_input); } @@ -174,13 +183,24 @@ bool Wayland_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) if (internal->text_input_manager) { struct SDL_WaylandInput *input = internal->input; if (input && input->text_input) { - if (!SDL_RectsEqual(&window->text_input_rect, &input->text_input->cursor_rect)) { - SDL_copyp(&input->text_input->cursor_rect, &window->text_input_rect); + SDL_WindowData *wind = window->internal; + const SDL_Rect scaled_rect = { + (int)SDL_floor(window->text_input_rect.x / wind->pointer_scale.x), + (int)SDL_floor(window->text_input_rect.y / wind->pointer_scale.y), + (int)SDL_ceil(window->text_input_rect.w / wind->pointer_scale.x), + (int)SDL_ceil(window->text_input_rect.h / wind->pointer_scale.y) + }; + const int scaled_cursor = (int)SDL_floor(window->text_input_cursor / wind->pointer_scale.x); + if (!SDL_RectsEqual(&scaled_rect, &input->text_input->text_input_rect) || scaled_cursor != input->text_input->text_input_cursor) { + SDL_copyp(&input->text_input->text_input_rect, &scaled_rect); + input->text_input->text_input_cursor = scaled_cursor; + + // Clamp the x value so it doesn't run too far past the end of the text input area. zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, - window->text_input_rect.x, - window->text_input_rect.y, - window->text_input_rect.w, - window->text_input_rect.h); + SDL_min(scaled_rect.x + scaled_cursor, scaled_rect.x + scaled_rect.w), + scaled_rect.y, + 1, + scaled_rect.h); zwp_text_input_v3_commit(input->text_input->text_input); } } diff --git a/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.h b/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.h index f570edb32f..a1ea076b7b 100644 --- a/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.h +++ b/third-party/SDL/src/video/wayland/SDL_waylandkeyboard.h @@ -26,7 +26,8 @@ typedef struct SDL_WaylandTextInput { struct zwp_text_input_v3 *text_input; - SDL_Rect cursor_rect; + SDL_Rect text_input_rect; + int text_input_cursor; bool has_preedit; } SDL_WaylandTextInput; diff --git a/third-party/SDL/src/video/wayland/SDL_waylandvideo.c b/third-party/SDL/src/video/wayland/SDL_waylandvideo.c index 43019535f5..47971e6a30 100644 --- a/third-party/SDL/src/video/wayland/SDL_waylandvideo.c +++ b/third-party/SDL/src/video/wayland/SDL_waylandvideo.c @@ -446,9 +446,6 @@ static void Wayland_DeleteDevice(SDL_VideoDevice *device) WAYLAND_wl_display_disconnect(data->display); SDL_ClearProperty(SDL_GetGlobalProperties(), SDL_PROP_GLOBAL_VIDEO_WAYLAND_WL_DISPLAY_POINTER); } - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(data); SDL_free(device); SDL_WAYLAND_UnloadSymbols(); @@ -589,7 +586,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols) } device->internal = data; - device->wakeup_lock = SDL_CreateMutex(); // Set the function pointers device->VideoInit = Wayland_VideoInit; diff --git a/third-party/SDL/src/video/windows/SDL_windowsvideo.c b/third-party/SDL/src/video/windows/SDL_windowsvideo.c index 6103d52334..841a9ecba5 100644 --- a/third-party/SDL/src/video/windows/SDL_windowsvideo.c +++ b/third-party/SDL/src/video/windows/SDL_windowsvideo.c @@ -120,9 +120,6 @@ static void WIN_DeleteDevice(SDL_VideoDevice *device) SDL_UnloadObject(data->dxgiDLL); } #endif - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->internal->rawinput); SDL_free(device->internal); SDL_free(device); @@ -148,7 +145,6 @@ static SDL_VideoDevice *WIN_CreateDevice(void) return NULL; } device->internal = data; - device->wakeup_lock = SDL_CreateMutex(); device->system_theme = WIN_GetSystemTheme(); #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) diff --git a/third-party/SDL/src/video/x11/SDL_x11dyn.h b/third-party/SDL/src/video/x11/SDL_x11dyn.h index e9831fcd60..7cd1e0eecb 100644 --- a/third-party/SDL/src/video/x11/SDL_x11dyn.h +++ b/third-party/SDL/src/video/x11/SDL_x11dyn.h @@ -71,6 +71,9 @@ #ifdef SDL_VIDEO_DRIVER_X11_XSHAPE #include #endif +#ifdef SDL_VIDEO_DRIVER_X11_XTEST +#include +#endif #ifdef __cplusplus extern "C" { diff --git a/third-party/SDL/src/video/x11/SDL_x11keyboard.c b/third-party/SDL/src/video/x11/SDL_x11keyboard.c index c48e82917f..2534092e41 100644 --- a/third-party/SDL/src/video/x11/SDL_x11keyboard.c +++ b/third-party/SDL/src/video/x11/SDL_x11keyboard.c @@ -762,7 +762,9 @@ void X11_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_Prop break; } (void)SDL_snprintf(deeplink, sizeof(deeplink), - "steam://open/keyboard?XPosition=0&YPosition=0&Width=0&Height=0&Mode=%d", + "steam://open/keyboard?XPosition=%i&YPosition=%i&Width=%i&Height=%i&Mode=%d", + window->text_input_rect.x, window->text_input_rect.y, + window->text_input_rect.w, window->text_input_rect.h, mode); SDL_OpenURL(deeplink); videodata->steam_keyboard_open = true; diff --git a/third-party/SDL/src/video/x11/SDL_x11pen.c b/third-party/SDL/src/video/x11/SDL_x11pen.c index f16da51c5a..c29c629c4a 100644 --- a/third-party/SDL/src/video/x11/SDL_x11pen.c +++ b/third-party/SDL/src/video/x11/SDL_x11pen.c @@ -283,14 +283,16 @@ static X11_PenHandle *X11_MaybeAddPen(SDL_VideoDevice *_this, const XIDeviceInfo X11_PenHandle *X11_MaybeAddPenByDeviceID(SDL_VideoDevice *_this, int deviceid) { - SDL_VideoData *data = _this->internal; - int num_device_info = 0; - XIDeviceInfo *device_info = X11_XIQueryDevice(data->display, deviceid, &num_device_info); - if (device_info) { - SDL_assert(num_device_info == 1); - X11_PenHandle *handle = X11_MaybeAddPen(_this, device_info); - X11_XIFreeDeviceInfo(device_info); - return handle; + if (X11_Xinput2IsInitialized()) { + SDL_VideoData *data = _this->internal; + int num_device_info = 0; + XIDeviceInfo *device_info = X11_XIQueryDevice(data->display, deviceid, &num_device_info); + if (device_info) { + SDL_assert(num_device_info == 1); + X11_PenHandle *handle = X11_MaybeAddPen(_this, device_info); + X11_XIFreeDeviceInfo(device_info); + return handle; + } } return NULL; } @@ -306,6 +308,10 @@ void X11_RemovePenByDeviceID(int deviceid) void X11_InitPen(SDL_VideoDevice *_this) { + if (!X11_Xinput2IsInitialized()) { + return; // we need XIQueryDevice() for this. + } + SDL_VideoData *data = _this->internal; #define LOOKUP_PEN_ATOM(X) X11_XInternAtom(data->display, X, False) diff --git a/third-party/SDL/src/video/x11/SDL_x11video.c b/third-party/SDL/src/video/x11/SDL_x11video.c index c188f91f43..86f5b860ee 100644 --- a/third-party/SDL/src/video/x11/SDL_x11video.c +++ b/third-party/SDL/src/video/x11/SDL_x11video.c @@ -63,9 +63,6 @@ static void X11_DeleteDevice(SDL_VideoDevice *device) X11_XCloseDisplay(data->request_display); } SDL_free(data->windowlist); - if (device->wakeup_lock) { - SDL_DestroyMutex(device->wakeup_lock); - } SDL_free(device->internal); SDL_free(device); @@ -78,23 +75,6 @@ static bool X11_IsXWayland(Display *d) return X11_XQueryExtension(d, "XWAYLAND", &opcode, &event, &error) == True; } -static bool X11_CheckCurrentDesktop(const char *name) -{ - SDL_Environment *env = SDL_GetEnvironment(); - - const char *desktopVar = SDL_GetEnvironmentVariable(env, "DESKTOP_SESSION"); - if (desktopVar && SDL_strcasecmp(desktopVar, name) == 0) { - return true; - } - - desktopVar = SDL_GetEnvironmentVariable(env, "XDG_CURRENT_DESKTOP"); - if (desktopVar && SDL_strcasestr(desktopVar, name)) { - return true; - } - - return false; -} - static SDL_VideoDevice *X11_CreateDevice(void) { SDL_VideoDevice *device; @@ -146,8 +126,6 @@ static SDL_VideoDevice *X11_CreateDevice(void) return NULL; } - device->wakeup_lock = SDL_CreateMutex(); - #ifdef X11_DEBUG X11_XSynchronize(data->display, True); #endif @@ -275,17 +253,11 @@ static SDL_VideoDevice *X11_CreateDevice(void) device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT; - /* Openbox doesn't send the new window dimensions when entering fullscreen, so the events must be synthesized. - * This is otherwise not wanted, as it can break fullscreen window positioning on multi-monitor configurations. - */ - if (!X11_CheckCurrentDesktop("openbox")) { - device->device_caps |= VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS; - } - data->is_xwayland = X11_IsXWayland(x11_display); if (data->is_xwayland) { device->device_caps |= VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED | - VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS; + VIDEO_DEVICE_CAPS_DISABLE_MOUSE_WARP_ON_FULLSCREEN_TRANSITIONS | + VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS; } return device; diff --git a/third-party/SDL/src/video/x11/SDL_x11window.c b/third-party/SDL/src/video/x11/SDL_x11window.c index 7e15433499..3a6b4ae78d 100644 --- a/third-party/SDL/src/video/x11/SDL_x11window.c +++ b/third-party/SDL/src/video/x11/SDL_x11window.c @@ -1574,6 +1574,12 @@ void X11_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) X11_PumpEvents(_this); data->size_move_event_flags = 0; + /* A MapNotify or PropertyNotify may not have arrived, so ensure that the shown event is dispatched + * to apply pending state before clearing the flag. + */ + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0); + data->was_shown = true; + // If a configure event was received (type is non-zero), send the final window size and coordinates. if (data->last_xconfigure.type) { int x, y; diff --git a/vendor.yaml b/vendor.yaml index 47f1bab810..ce69925abf 100644 --- a/vendor.yaml +++ b/vendor.yaml @@ -28,7 +28,7 @@ third-party/sqlite3: third-party/fmt: git: https://github.com/fmtlib/fmt/tree/11.1.4 third-party/SDL: - git: https://github.com/libsdl-org/SDL/tree/release-3.2.14 + git: https://github.com/libsdl-org/SDL/tree/release-3.2.16 third-party/imgui: git: https://github.com/ocornut/imgui/releases/tag/v1.91.8 third-party/tree-sitter: From 7320bfc068acfa385f929b176f61caf3b7aabbbe Mon Sep 17 00:00:00 2001 From: Soggy_Pancake <54160598+Soggy-Pancake@users.noreply.github.com> Date: Wed, 2 Jul 2025 20:19:21 -0700 Subject: [PATCH 14/18] g/jak1: Extract ambient data to json (#3945) I added extraction of ambients to json files when extracting the levels. All of the ambient json files are written to the same folder as actors are. Ambients aren't used in jak2 and 3 so it only is used on jak1. ![image](https://github.com/user-attachments/assets/26e5d655-6a31-49eb-8514-3374b41f72dd) --------- Co-authored-by: Tyler Wilding --- decompiler/level_extractor/BspHeader.cpp | 116 ++++++++++++++++++ decompiler/level_extractor/BspHeader.h | 33 +++++ decompiler/level_extractor/extract_actors.cpp | 91 ++++++++++++++ decompiler/level_extractor/extract_actors.h | 3 +- decompiler/level_extractor/extract_level.cpp | 4 + 5 files changed, 246 insertions(+), 1 deletion(-) diff --git a/decompiler/level_extractor/BspHeader.cpp b/decompiler/level_extractor/BspHeader.cpp index f69c4eef99..9884ec3fa6 100644 --- a/decompiler/level_extractor/BspHeader.cpp +++ b/decompiler/level_extractor/BspHeader.cpp @@ -527,6 +527,13 @@ std::string DrawableActor::print(const PrintSettings& /*settings*/, int indent) return result; } +std::string DrawableAmbient::print(const PrintSettings& /*settings*/, int indent) const { + std::string is(indent, ' '); + std::string result; + result += fmt::format("{}bsphere: {}", is, bsphere.print_meters()); + return result; +} + void InstanceTie::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts, GameVersion /*version*/) { @@ -1952,6 +1959,110 @@ void DrawableInlineArrayActor::read_from_file(TypedRef ref, } } +void EntityAmbient::read_from_file(TypedRef ref, + const decompiler::DecompilerTypeSystem& dts, + GameVersion /*version*/) { + trans.read_from_file(get_field_ref(ref, "trans", dts)); + aid = read_plain_data_field(ref, "aid", dts); + // ambientData = read_plain_data_field(ref, "extra", dts); // to-do: get ambient-data, not + // sure if nessecary tho + + int res_length = read_plain_data_field(ref, "length", dts); + // int res_allocated_length = read_plain_data_field(ref, "allocated-length", dts); + + auto tags = deref_label(get_field_ref(ref, "tag", dts)); + auto data_base = deref_label(get_field_ref(ref, "data-base", dts)); + + for (int i = 0; i < res_length; i++) { + auto& res = res_list.emplace_back(); + res.name = read_symbol(tags); + tags.byte_offset += 4; + res.key_frame = deref_float(tags, 0); + tags.byte_offset += 4; + res.elt_type = read_type(tags); + tags.byte_offset += 4; + const u32 vals = deref_u32(tags, 0); + const u32 offset = vals & 0xffff; // 16 bits + res.count = (vals >> 16) & 0x7fff; // 15 bits + res.inlined = vals & 0x8000'0000; + + Ref data = data_base; + data.byte_offset += offset; + + if (res.elt_type == "string") { + ASSERT(!res.inlined); + for (int j = 0; j < res.count; j++) { + res.strings.push_back(read_string_ref(data)); + data.byte_offset += 4; + } + } else if (res.elt_type == "symbol") { + ASSERT(!res.inlined); + for (int j = 0; j < res.count; j++) { + res.strings.push_back(read_symbol(data)); + data.byte_offset += 4; + } + } else if (res.elt_type == "type") { + ASSERT(!res.inlined); + for (int j = 0; j < res.count; j++) { + res.strings.push_back(read_type(data)); + data.byte_offset += 4; + } + } else if (res.elt_type == "vector") { + ASSERT(res.inlined); + res.inlined_storage = bytes_from_plain_data(data, 16 * res.count); + } else if (res.elt_type == "float") { + fill_res_with_value_types(res, data); + } else if (res.elt_type == "int32") { + fill_res_with_value_types(res, data); + } else if (res.elt_type == "int16") { + fill_res_with_value_types(res, data); + } else if (res.elt_type == "int8") { + fill_res_with_value_types(res, data); + } else if (res.elt_type == "uint32") { + fill_res_with_value_types(res, data); + } else if (res.elt_type == "uint8") { + fill_res_with_value_types(res, data); + } else if (res.elt_type == "actor-group") { + // TODO: unsupported. + } else if (res.elt_type == "pair") { + ASSERT(res.count == 1); + ASSERT(!res.inlined); + data = deref_label(data); + res.script = data.data->to_form_script(data.seg, (data.byte_offset) / 4, nullptr); + } else { + fmt::print("unhandled elt_type: {}\n", res.elt_type); + ASSERT_NOT_REACHED(); + } + + tags.byte_offset += 4; + } +} + +void DrawableAmbient::read_from_file(TypedRef ref, + const decompiler::DecompilerTypeSystem& dts, + GameVersion version) { + bsphere.read_from_file(get_field_ref(ref, "bsphere", dts)); + ambient.read_from_file(get_and_check_ref_to_basic(ref, "ambient", "entity-ambient", dts), dts, + version); +} + +void DrawableInlineArrayAmbient::read_from_file(TypedRef ref, + const decompiler::DecompilerTypeSystem& dts, + GameVersion version) { + int numAmbients = read_plain_data_field(ref, "length", dts); + auto data_ref = get_field_ref(ref, "data", dts); + for (int i = 0; i < numAmbients; i++) { + Ref obj_ref = data_ref; + obj_ref.byte_offset += 32 * i; // todo not a constant here + auto type = get_type_of_basic(obj_ref); + if (type != "drawable-ambient") { + throw Error("bad drawable-ambient type: {}", type); + } + drawable_ambients.emplace_back(); + drawable_ambients.back().read_from_file(typed_ref_from_basic(obj_ref, dts), dts, version); + } +} + void CollideHash::read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts, GameVersion /*version*/) { @@ -2065,6 +2176,11 @@ void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file, actors.read_from_file( get_and_check_ref_to_basic(ref, "actors", "drawable-inline-array-actor", dts), dts, version); + if (get_word_kind_for_field(ref, "ambients", dts) == decompiler::LinkedWord::PTR) { + ambients.read_from_file( + get_and_check_ref_to_basic(ref, "ambients", "drawable-inline-array-ambient", dts), dts, + version); + } } if (version > GameVersion::Jak1 && diff --git a/decompiler/level_extractor/BspHeader.h b/decompiler/level_extractor/BspHeader.h index e0b47969ff..aa7f73f0b7 100644 --- a/decompiler/level_extractor/BspHeader.h +++ b/decompiler/level_extractor/BspHeader.h @@ -189,6 +189,31 @@ struct DrawableActor : public Drawable { std::string my_type() const override { return "drawable-actor"; } }; +struct EntityAmbient { + Vector trans; + u32 aid = 0; + + u128 ambientData; + + std::vector res_list; + + void read_from_file(TypedRef ref, + const decompiler::DecompilerTypeSystem& dts, + GameVersion version); +}; + +struct DrawableAmbient : public Drawable { + Vector bsphere; + + EntityAmbient ambient; + + void read_from_file(TypedRef ref, + const decompiler::DecompilerTypeSystem& dts, + GameVersion version) override; + std::string print(const PrintSettings& settings, int indent) const override; + std::string my_type() const override { return "drawable-ambient"; } +}; + struct DrawableTreeActor : public DrawableTree { void read_from_file(TypedRef ref, const decompiler::DecompilerTypeSystem& dts, @@ -765,6 +790,13 @@ struct DrawableInlineArrayActor { GameVersion version); }; +struct DrawableInlineArrayAmbient { + std::vector drawable_ambients; + void read_from_file(TypedRef ref, + const decompiler::DecompilerTypeSystem& dts, + GameVersion version); +}; + struct CollideHash { Ref item_array; int num_items = 0; @@ -912,6 +944,7 @@ struct BspHeader { // (boxes box8s-array :offset-assert 148) // (current-bsp-back-flags uint32 :offset-assert 152) // (ambients drawable-inline-array-ambient :offset-assert 156) + DrawableInlineArrayAmbient ambients; // (unk-data-4 float :offset-assert 160) // (unk-data-5 float :offset-assert 164) // (adgifs adgif-shader-array :offset-assert 168) diff --git a/decompiler/level_extractor/extract_actors.cpp b/decompiler/level_extractor/extract_actors.cpp index fd2d1a822a..2bd365a743 100644 --- a/decompiler/level_extractor/extract_actors.cpp +++ b/decompiler/level_extractor/extract_actors.cpp @@ -146,4 +146,95 @@ std::string extract_actors_to_json(const level_tools::DrawableInlineArrayActor& return json.dump(2); } +std::string extract_ambients_to_json(const level_tools::DrawableInlineArrayAmbient& actors) { + nlohmann::json json; + + for (const auto& damb : actors.drawable_ambients) { + const auto& ambient = damb.ambient; + auto& json_ambient = json.emplace_back(); + json_ambient["bsphere"] = vectorm_json(damb.bsphere); + // drawable ID? + + json_ambient["trans"] = vectorm_json(ambient.trans); + json_ambient["aid"] = ambient.aid; // aid + + auto& json_lump = json_ambient["lump"]; + + nlohmann::json effects; + int effectCount = 0, + effectParamCount = + 0; // just to keep track since names cound all be together and then params + + for (const auto& res : ambient.res_list) { + if (res.elt_type == "string") { + if (res.name == "name") + json_lump[res.name] = strings_json(res.strings, false); + else + json_lump[res.name] = strings_json(res.strings, true); + } else if (res.elt_type == "symbol") { + if (res.name == "effect-name") { + if (++effectCount > effectParamCount) { + nlohmann::json effect; + effect["name"] = strings_json(res.strings, false); + effects.push_back(effect); + } else { + auto& effect = effects[effectCount - 1]; + effect["name"] = strings_json(res.strings, false); + } + } else { + json_lump[res.name] = strings_json(res.strings, false); + } + } else if (res.elt_type == "type") { + // TODO: confusion with symbols + json_lump[res.name] = strings_json(res.strings, true); + } else if (res.elt_type == "vector") { + const float* data = (const float*)res.inlined_storage.data(); + if (res.count == 1) { + json_lump[res.name] = vector_json(data); + } else { + for (int i = 0; i < res.count; i++) { + json_lump[res.name].push_back(vector_json(data + 4 * i)); + } + } + } else if (res.elt_type == "pair") { + json_lump[res.name] = pretty_print::to_string(res.script); + } else if (res.elt_type == "float") { + if (res.name == "effect-param") { + if (++effectParamCount > effectCount) { + nlohmann::json effect; + effect["params"] = value_json(res.inlined_storage, res.count); + effects.push_back(effect); + } else { + auto& effect = effects[effectParamCount - 1]; + effect["params"] = value_json(res.inlined_storage, res.count); + } + } else { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } + } else if (res.elt_type == "int32") { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } else if (res.elt_type == "int16") { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } else if (res.elt_type == "int8") { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } else if (res.elt_type == "uint32") { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } else if (res.elt_type == "uint16") { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } else if (res.elt_type == "uint8") { + json_lump[res.name] = value_json(res.inlined_storage, res.count); + } else if (res.elt_type == "actor-group") { + // not supported. + } else { + ASSERT_NOT_REACHED(); + } + } + + if (effectCount || effectParamCount) + json_lump["effects"] = effects; + } + + return json.dump(2); +} + } // namespace decompiler diff --git a/decompiler/level_extractor/extract_actors.h b/decompiler/level_extractor/extract_actors.h index 6066b5cd22..2fc756ea82 100644 --- a/decompiler/level_extractor/extract_actors.h +++ b/decompiler/level_extractor/extract_actors.h @@ -5,5 +5,6 @@ namespace decompiler { std::string extract_actors_to_json(const level_tools::DrawableInlineArrayActor& actors); +std::string extract_ambients_to_json(const level_tools::DrawableInlineArrayAmbient& actors); -} \ No newline at end of file +} // namespace decompiler diff --git a/decompiler/level_extractor/extract_level.cpp b/decompiler/level_extractor/extract_level.cpp index 43e792dcbd..7471920c88 100644 --- a/decompiler/level_extractor/extract_level.cpp +++ b/decompiler/level_extractor/extract_level.cpp @@ -389,6 +389,10 @@ void extract_from_level(const ObjectFileDB& db, } file_util::write_text_file(entities_folder / fmt::format("{}-actors.json", level_data.level_name), extract_actors_to_json(bsp_header.actors)); + if (config.game_version == GameVersion::Jak1) + file_util::write_text_file( + entities_folder / fmt::format("{}-ambients.json", level_data.level_name), + extract_ambients_to_json(bsp_header.ambients)); } void extract_all_levels(const ObjectFileDB& db, From d5eebdcdfe14086f1b8b2a4b9c6193f88b4c6234 Mon Sep 17 00:00:00 2001 From: OpenGOAL Bot <99294829+OpenGOALBot@users.noreply.github.com> Date: Fri, 11 Jul 2025 20:39:30 -0400 Subject: [PATCH 15/18] CI: Periodic Controller Database Update (#3977) Updating Controller Database Co-authored-by: OpenGOALBot --- game/assets/sdl_controller_db.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/game/assets/sdl_controller_db.txt b/game/assets/sdl_controller_db.txt index 8758aac8e8..982870a47e 100644 --- a/game/assets/sdl_controller_db.txt +++ b/game/assets/sdl_controller_db.txt @@ -112,6 +112,7 @@ 03000000020500000913000000000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000373500000710000000000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000373500004610000000000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000190e00000110000000000000,Aquaplus Piece,a:b1,b:b0,back:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b2,platform:Windows, 03000000830500000160000000000000,Arcade,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b4,platform:Windows, 03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000490b00004406000000000000,ASCII Seamic Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, @@ -232,6 +233,7 @@ 03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000ac0500001a06000000000000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, +03000000373500009410000000000000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 0300000047530000616d000000000000,GameStop,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, @@ -340,6 +342,7 @@ 03000000242f00000a20000000000000,Hyperkin Scout,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, 03000000242e00000a20000000000000,Hyperkin Scout Premium SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, 03000000242e00006a38000000000000,Hyperkin Trooper 2,a:b0,b:b1,back:b4,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b3,start:b5,platform:Windows, +03000000f00300008d04000000000000,HyperX Clutch,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:-a2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:+a5,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows, 03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, @@ -1236,6 +1239,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000020500000913000010010000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000373500000710000010010000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000373500004610000001000000,Anbernic RG P01,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +03000000190e00000110000010010000,Aquaplus Piece,a:b1,b:b0,back:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b2,platform:Linux, 03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, @@ -1305,6 +1309,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 03000000373500009710000001020000,GameSir Kaleid Flux,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000ac0500001a06000011010000,GameSir T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, +03000000373500009410000010010000,GameSir Tegenaria Lite,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, @@ -1501,7 +1506,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, 05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, -050000005a1d00000218000003000000,Nokia GC 5000,a:b9,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005a1d00000218000003000000,Nokia GC 5000,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, 030000007e0500007320000011010000,NSO GameCube Controller,a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:b12,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b4,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,platform:Linux, 030000007e0500001920000011810000,NSO N64 Controller,+rightx:b2,+righty:b3,-rightx:b4,-righty:b10,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b9,start:b11,platform:Linux, @@ -1824,6 +1829,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, +03000000120c0000182e000011010000,Zeroplus PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, # Android 38653964633230666463343334313533,8BitDo Adapter,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b17,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b18,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android, From a34ab9aa3038668d911a4844de1d81ab4c9538d4 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Thu, 17 Jul 2025 01:00:51 -0400 Subject: [PATCH 16/18] game: fix refresh rate filtering comparison (#3984) It helps to compare in the right direction -- was having the inverse effect. --- game/main.cpp | 3 +++ game/system/hid/display_manager.cpp | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/game/main.cpp b/game/main.cpp index f4048709e3..035ea2c179 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -138,6 +138,9 @@ int main(int argc, char** argv) { app.allow_extras(); CLI11_PARSE(app, argc, argv); + // Log the version the game is compiled against so we don't have to guess + lg::info("Compiled Version: {}", build_revision()); + // Override the user's config dir, potentially (either because it was explicitly provided // or because it's portable mode) if (enable_portable) { diff --git a/game/system/hid/display_manager.cpp b/game/system/hid/display_manager.cpp index c2072dcbe1..0901a5da2e 100644 --- a/game/system/hid/display_manager.cpp +++ b/game/system/hid/display_manager.cpp @@ -495,10 +495,13 @@ void DisplayManager::update_resolutions() { // Skip resolutions that aren't using the current refresh rate, they won't work. // For example if your monitor is currently set to `60hz` and the monitor _could_ support // resolution X but only at `30hz`...then there's no reason for us to consider it as an option. - if (std::abs(display_mode->refresh_rate - active_refresh_rate) < 1.0) { + const auto comparison = std::abs(display_mode->refresh_rate - active_refresh_rate); + if (comparison > 1.0) { lg::debug( - "[DISPLAY]: Skipping {}x{} as it requires {}hz but the monitor is currently set to {}hz", - display_mode->w, display_mode->h, display_mode->refresh_rate, active_refresh_rate); + "[DISPLAY]: Skipping {}x{} as it requires {:f}hz but the monitor is currently set to " + "{:f}hz. Difference: {:f}", + display_mode->w, display_mode->h, display_mode->refresh_rate, active_refresh_rate, + comparison); // Allow it for windowed mode though m_available_window_sizes.push_back(new_res); continue; From 690cc04625e77d3842053d98348c004fe8f01a5f Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Tue, 22 Jul 2025 11:07:36 -0700 Subject: [PATCH 17/18] [jak1] Allow skipping credits in speedrunner mode (#3981) Speedrunners have seen the Jak 1 credits once or twice, I think we can let them skip --- goal_src/jak1/levels/finalboss/sage-finalboss.gc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/goal_src/jak1/levels/finalboss/sage-finalboss.gc b/goal_src/jak1/levels/finalboss/sage-finalboss.gc index ebe5186e3d..3acf74356b 100644 --- a/goal_src/jak1/levels/finalboss/sage-finalboss.gc +++ b/goal_src/jak1/levels/finalboss/sage-finalboss.gc @@ -47,7 +47,6 @@ (speed float) (touch-time time-frame))) - (defmethod get-unlit-skel ((this plat-eco-finalboss)) *plat-eco-finalboss-unlit-sg*) @@ -115,7 +114,6 @@ (active symbol)) :allow-misaligned) - (deftype sage-finalboss (process-taskable) ((redsage handle) (bluesage handle) @@ -137,7 +135,6 @@ (:states sage-finalboss-credits)) - (defmethod relocate ((this sage-finalboss) (offset int)) (dotimes (v1-0 9) (if (nonzero? (-> this particle v1-0 part)) (&+! (-> this particle v1-0 part) offset))) @@ -606,7 +603,8 @@ (set! (-> self credit-fade) 1.0) (sage-finalboss-credit-particle) (set! s5-0 (draw-end-credits (the int f30-0))) - (if (and *cheat-mode* (cpad-pressed? 0 triangle)) (set! s5-0 #t)) + ;; og:preserve-this allow credits skip in speedrunner mode + (if (and (or *cheat-mode* (-> *pc-settings* speedrunner-mode?)) (cpad-pressed? 0 triangle)) (set! s5-0 #t)) (cond ((paused?)) ((and (< 1300.0 f30-0) (cpad-hold? 0 circle x)) From b93caabd1d3c5478eeb6c37efef5635fe0eec677 Mon Sep 17 00:00:00 2001 From: OpenGOAL Bot <99294829+OpenGOALBot@users.noreply.github.com> Date: Wed, 23 Jul 2025 19:18:11 -0400 Subject: [PATCH 18/18] CI: Periodic Controller Database Update (#3982) Updating Controller Database Co-authored-by: OpenGOALBot --- game/assets/sdl_controller_db.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/game/assets/sdl_controller_db.txt b/game/assets/sdl_controller_db.txt index 982870a47e..f0867535b0 100644 --- a/game/assets/sdl_controller_db.txt +++ b/game/assets/sdl_controller_db.txt @@ -262,6 +262,8 @@ 030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows, 03000000ac0500006b05000000000000,GT2a,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, +030000008a2e0000dd10000000000000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Windows, +030000008a2e0000df10000000000000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Windows, 030000000d0f00004900000000000000,Hatsune Miku Sho PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows, 030000000d0f00000c00000000000000,HEXT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, @@ -1130,6 +1132,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, +030000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X, 03000000c62400003a54000000000000,Xbox One PowerA Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X, 030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, 030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X, @@ -1329,6 +1332,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, +030000008a2e0000dd10000011010000,Hand Held Legend GC Ultimate,a:b0,b:b2,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,misc2:b24,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b1,y:b3,platform:Linux, +030000008a2e0000df10000011010000,Hand Held Legend ProGCC,a:b1,b:b0,back:b17,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,guide:b18,leftshoulder:b10,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b19,paddle1:b13,paddle2:b12,rightshoulder:b11,rightstick:b9,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b3,y:b2,platform:Linux, 06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, 03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, @@ -1793,6 +1798,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e040000ea02000011050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000ea02000015050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, +030000005e040000ea02000017050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000ea02000016050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, @@ -1821,6 +1827,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2, 050000005e040000130b000022050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000200b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, +050000005e040000200b000023050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,