From 86cfaa4a6b257db9c8ad30798d34f0734c6ccf08 Mon Sep 17 00:00:00 2001 From: SpeedBreaker Project Date: Thu, 22 Oct 2026 14:02:14 +0000 Subject: [PATCH] SpeedBreaker v0.1.8 Co-authored-by: byteofmydream <12628004+byteofmydream@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 45 + CMakeLists.txt | 2 +- README.md | 33 +- docs/TESTING.md | 4 + runtime/apu/ea_cpu_budget.cpp | 59 ++ runtime/apu/ea_cpu_budget.h | 100 ++ runtime/game/cover_callers.cpp | 157 +++ runtime/game/cover_callers.h | 47 + runtime/game/hfr.cpp | 1497 +++++++++++++++++++++++++++++ runtime/game/hfr.h | 61 ++ runtime/game/hfr_blend.h | 150 +++ runtime/game/hfr_diag.cpp | 230 +++++ runtime/game/hfr_grid.h | 38 + runtime/game/hfr_writeset.cpp | 304 ++++++ runtime/game/light_trails.cpp | 6 +- runtime/game/split_screen.cpp | 43 + runtime/game/split_screen.h | 62 ++ runtime/gpu/command_processor.cpp | 73 +- runtime/gpu/covers.h | 265 +++++ runtime/gpu/edge_bars.h | 104 +- runtime/gpu/imports_video.cpp | 26 +- runtime/gpu/renderer.cpp | 651 ++++++++++++- runtime/gpu/renderer.h | 13 +- runtime/gpu/shader_translator.cpp | 16 + runtime/gpu/shader_translator.h | 11 + runtime/gpu/split_views.h | 79 ++ runtime/hid/input.cpp | 762 +++++++++++++-- runtime/hid/input.h | 22 + runtime/hid/player_slots.h | 187 ++++ runtime/hid/wheel.cpp | 1116 +++++++++++++++++++++ runtime/hid/wheel.h | 150 +++ runtime/hid/wheel_map.h | 1151 ++++++++++++++++++++++ runtime/kernel/vmem.cpp | 37 +- runtime/kernel/vmem.h | 19 + runtime/kernel/write_watch.cpp | 27 +- runtime/main.cpp | 2 + runtime/ui/settings_menu.cpp | 176 +++- runtime/ui/ui.cpp | 153 ++- runtime/user/settings.cpp | 116 ++- runtime/user/settings.h | 41 +- runtime/video/hfr_schedule.h | 88 ++ runtime/video/presenter.cpp | 386 +++++++- runtime/video/presenter.h | 37 +- runtime/video/refresh_notice.h | 3 + runtime/video/vblank_lock.cpp | 10 +- runtime/video/vblank_lock.h | 10 +- tests/CMakeLists.txt | 38 + tests/covers_test.cpp | 211 ++++ tests/ea_cpu_budget_test.cpp | 206 ++++ tests/fade_layers_test.cpp | 393 ++++++++ tests/hfr_blend_test.cpp | 209 ++++ tests/hfr_grid_test.cpp | 91 ++ tests/hfr_schedule_test.cpp | 73 ++ tests/player_slots_test.cpp | 161 ++++ tests/refresh_notice_test.cpp | 3 + tests/settings_keys_test.cpp | 4 +- tests/split_views_test.cpp | 132 +++ tests/vmem_host_pages_test.cpp | 297 ++++++ tests/wheel_map_test.cpp | 880 +++++++++++++++++ tests/write_watch_test.cpp | 27 +- 60 files changed, 11082 insertions(+), 212 deletions(-) create mode 100644 runtime/apu/ea_cpu_budget.cpp create mode 100644 runtime/apu/ea_cpu_budget.h create mode 100644 runtime/game/cover_callers.cpp create mode 100644 runtime/game/cover_callers.h create mode 100644 runtime/game/hfr.cpp create mode 100644 runtime/game/hfr.h create mode 100644 runtime/game/hfr_blend.h create mode 100644 runtime/game/hfr_diag.cpp create mode 100644 runtime/game/hfr_grid.h create mode 100644 runtime/game/hfr_writeset.cpp create mode 100644 runtime/game/split_screen.cpp create mode 100644 runtime/game/split_screen.h create mode 100644 runtime/gpu/covers.h create mode 100644 runtime/gpu/split_views.h create mode 100644 runtime/hid/player_slots.h create mode 100644 runtime/hid/wheel.cpp create mode 100644 runtime/hid/wheel.h create mode 100644 runtime/hid/wheel_map.h create mode 100644 runtime/video/hfr_schedule.h create mode 100644 tests/covers_test.cpp create mode 100644 tests/ea_cpu_budget_test.cpp create mode 100644 tests/fade_layers_test.cpp create mode 100644 tests/hfr_blend_test.cpp create mode 100644 tests/hfr_grid_test.cpp create mode 100644 tests/hfr_schedule_test.cpp create mode 100644 tests/player_slots_test.cpp create mode 100644 tests/split_views_test.cpp create mode 100644 tests/vmem_host_pages_test.cpp create mode 100644 tests/wheel_map_test.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 74ccb6e..03b96b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,51 @@ What changed in each SpeedBreaker release, newest first. Each release's notes on its entry here, and the game shows the entry once, the first time a new version starts (offline: it's built into the game). +## v0.1.8 + +### What's new + +- **Two-player split screen** (Quick Race > Split Screen): with two controllers, each player gets + their own half of the screen. The second controller joins at "Player 2 press START". If either + player's controller disconnects, the game pauses and says so until it's back (issue #28). +- **Smooth Motion** (Settings > Display), on a Mac with a 120 Hz screen (ProMotion or a 120 Hz + monitor): up to 120 fps. The game still runs at 60 steps a second, as on the console, and draws + one more picture between each two. It's off by default and takes effect the next time the game + starts. When a scene is too heavy, it eases off, down to an even 60 for a few seconds. +- **USB steering wheels (experimental).** A Logitech G29 steers, the pedals are the throttle and + the brake, the paddles shift gears, and the menus work from the wheel's buttons. Settings > Wheel + (shown while a wheel is plugged in) has the steering range, deadzone, response, force feedback + and Calibrate for other wheels. Tested with a G29 on a Mac; the steering feel is still being + tuned, so feedback from wheel owners is very welcome. Thanks to byteofmydream, who wrote it + (pull request #29). + +### Fixed + +- Now and then in a race, especially on a busy Mac, the engine (or another sound) dropped to a + murmur until the next gear change. The game's own sound code took a moment where it didn't get to + run for a console overload and cut sounds; it no longer does. Thanks to Omega3komma3 for the + report and the video (issue #35). +- The fade to black before some cutscenes and loads (such as the career prologue's last race) + now covers the whole screen, top and bottom, on screens taller than 16:9 (a MacBook, a Steam + Deck), instead of leaving the scene showing above and below it. +- A preventive memory fix for Apple-silicon Macs, iPhones and iPads: handing memory back could + clear a little more than it should. It wasn't seen to happen in play. + +### More about it + +- Split screen runs at 60 fps on a Mac and on a Steam Deck at its Auto resolution; at higher + Internal Resolutions it can drop below. +- Smooth Motion isn't on SteamOS, Linux or iPhone and iPad yet. Internal Resolution's Auto picks + for two pictures a step (1x on an M1 Pro); the controls answer a few milliseconds later. +- Wheels: other wheels than the G29 are used as best the game can work them out; Calibrate teaches + it yours. Force feedback works on a Mac through SDL's own Logitech driver (the G29 in its PS3 + position, G27, G25, Driving Force GT and Pro; not a G29 in its PS4 position, a G920 or a G923). + On SteamOS and Linux the wheel should steer as on a Mac; force feedback there isn't tested yet. +- The log now says when the game's sound code would have dropped sounds, at most once a minute. +- Updating keeps your saves, settings and the installed game, and needs no disc image: on a Mac, + drag the new app into Applications and choose Replace, then Open Anyway once more; on SteamOS, + unpack the new download over the old folder. + ## v0.1.7 ### What's new diff --git a/CMakeLists.txt b/CMakeLists.txt index 92b5c0c..8ba9e84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ endif() # apps' versions, the SteamOS bundles' VERSION file and the release tag # (v). CHANGELOG.md has an entry for each version (the in-game # "What's new" note is built from it). -project(SpeedBreaker VERSION 0.1.7 LANGUAGES C CXX) +project(SpeedBreaker VERSION 0.1.8 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/README.md b/README.md index 11a98f5..9b35a19 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,11 @@ and a settings menu you can open mid-race. HUD and the rear-view mirror stay in place. A 4:3 iPad, a 3:2 screen or the 16:10 screens of the Steam Deck and many Macs show more above and below instead, and fill the screen. - **Up to 60 fps,** locked to your 60 Hz display. You can also pick a steady 30 at full game - speed, or *Auto*, which drops to 30 only while a device is hot or can't hold 60. + speed, or *Auto*, which drops to 30 only while a device is hot or can't hold 60. On a Mac with + a 120 Hz screen, *Smooth Motion* draws up to 120 fps (off by default). +- **Two-player split screen** (Quick Race > Split Screen), with two controllers. +- **USB steering wheels (experimental).** Tested with a Logitech G29 on a Mac, force feedback + included; the steering feel is still being tuned. - **The sun glare is back.** The low sun glows in open sky and fades behind buildings, as it did on the console. - **The original look:** sunlit roads and shadows as on the console, the picture a real Xbox 360 @@ -130,6 +134,13 @@ should say OK. What changed in each release is in [CHANGELOG.md](CHANGELOG.md). - **Everyone:** a disc image of your own **USA (NTSC-U) Xbox 360 disc** (see [Quick start](#quick-start)), about **7.2 GB** of free space, and a display running at about **60 Hz** (or 120 Hz, 180 Hz or 240 Hz on SteamOS and Linux). +- **Split screen:** two controllers. +- **Smooth Motion** (up to 120 fps): a Mac with a 120 Hz screen (a ProMotion MacBook Pro or a + 120 Hz monitor). Not yet on SteamOS, Linux, iPhone or iPad. +- **Steering wheels (experimental):** a USB wheel on a Mac, SteamOS or Linux. The Logitech G29 + is the one tested (on a Mac). Force feedback works on a Mac with the G29 in its PS3 position, + the G27, G25, Driving Force GT and Pro; not yet a G29 in its PS4 position, a G920 or a G923, + and it isn't tested on SteamOS or Linux. - **Steam Deck, Steam Machine and Linux PCs** (the x86-64 SteamOS download): a 64-bit x86 CPU with AVX2 (x86-64-v3): Intel Haswell (2013) or newer, or AMD Excavator, Zen or newer. A Vulkan 1.2 graphics card. @@ -362,6 +373,13 @@ is B, Square is X and Triangle is Y. - One player, one controller: the first one connected is used, and you can plug one in at any time. The keyboard always works as well. +- **Split screen** (Quick Race > Split Screen): the second controller joins at "Player 2 press + START" and drives the second half of the screen. If a player's controller disconnects, the + game pauses and says so until it's back. +- **A steering wheel** (experimental) is used instead of a controller while both are plugged in: + the wheel steers, the pedals are the throttle and the brake, the paddles shift gears, and the + menus work from its D-pad, Cross (A) and Circle (B). On a G29, Share + Options opens the + settings. See **Wheel** under [Settings](#settings). - Because Back + Start opens the settings, the game sees Back a moment late: a tap arrives when you let go, a hold after a quarter of a second. - The game shifts gears with the right stick, so from the keyboard you shift with O and L. @@ -378,6 +396,7 @@ is B, Square is X and Triangle is Y. |---|---| | Keyboard | **F1** (on a Mac also **Cmd+,**) | | Xbox-style controller | **Back + Start** (View + Menu) together | +| Logitech G29 wheel | **Share + Options** together | | Steam Deck | Hold **View**, press **Menu** | | Steam Frame | **Menu + View** together | | iPhone and iPad touchscreen | **Three-finger tap** | @@ -401,6 +420,7 @@ switcher). | Fullscreen | On / Off | Off: a 1280x720 window you can resize. The game always starts as set here; on a Mac, the window's green button switches only until you quit, and the row then says NOW FULLSCREEN or NOW WINDOWED. Always on in SteamOS Game Mode. Not shown on iPhone and iPad, which are always full screen. | | V-Sync | On / Off | On. Off can tear, but shows frames sooner. | | Frame Rate | Auto / 60 fps / 30 fps | 60 fps on most devices. 30 fps keeps the game at full speed. Auto runs at 60, or at a steady 30 while the device is hot or can't hold 60. | +| Smooth Motion | On / Off | Off. On a Mac with a 120 Hz screen: up to 120 fps. The game still runs at 60 steps a second, as on the console, and draws one more picture between each two; the controls answer a few milliseconds later. Heavy scenes ease off, down to an even 60 for a while. Takes effect the next time the game starts. Shown only where it works. | | Screen Resolution | Full / 75% | Full. iPhone and iPad only: 75% is slightly softer and saves graphics work. | | Aspect Ratio | Fill Screen / 16:9 | Fill Screen: wider screens get a wider view; 4:3, 3:2 and 16:10 screens (the Steam Deck, many Macs) a taller one. 16:9 always shows the classic picture with bars. | | Brightness | -5 to +5 | 0, the picture as it is. Each step makes the shadows and mid-tones a little lighter or darker, like a TV's brightness; black and white stay put, and the menus never change. | @@ -427,6 +447,12 @@ game while its window isn't in front. **Input:** Stick Deadzone (8%; raise it if the car steers by itself), Trigger Deadzone (2%), and Vibration (On). +**Wheel** (experimental; shown while a steering wheel is plugged in): Steering Wheel (On; Off +lets a controller or the keyboard play while the wheel stays plugged in), Steering Range (360 +degrees lock to lock, of a G29's 900), Invert Steering, Steering Deadzone (0%), Steering Response +(1.00), Force Feedback (100%), Centering Force, and **Calibrate**, which teaches the game a wheel +other than the G29: both ends of its turn, each pedal, then a button for each control. + **Controls:** the keyboard keys for each Xbox 360 control, two per control, as in the table under [Controls](#controls). The keys are saved by name in `settings.toml`'s `[keys]` table (`w`, `left_shift`, `keypad_1`, or `none`; `runtime/user/key_names.h` lists them). @@ -450,7 +476,8 @@ online, and only when you press it). The page also shows which build you're runn - **MacBook Pro with a 120 Hz (ProMotion) screen:** since v0.1.4 SpeedBreaker asks for each frame to reach the screen 1/60 s after the last. Measured in fullscreen on an M1 Pro: 99.9% of frames in menus and about 94% while driving (fewer in the heaviest scenes). Other screens show frames - as before. + as before. Since v0.1.8, **Smooth Motion** (Settings > Display) draws up to 120 fps there; + Internal Resolution's Auto picks for it (1x on an M1 Pro). - **Start with Auto.** If busy scenes drop below 60, set Internal Resolution one step lower, or let Frame Rate *Auto* fall back to a steady 30. - **30 fps is a real option.** It's a steady 30 at full game speed, and the smooth choice in the @@ -567,7 +594,7 @@ SpeedBreaker folder instead: `data/`, `data/game` and `cache/`. 2. A notice says where the zip file went: your **Desktop** (on SteamOS, pick it up in Desktop Mode, or in the Desktop app on a Steam Frame), the **SpeedBreaker** folder in the Files app on iPhone and iPad, or the data folder above when there is no Desktop. Its name says which - version you were running, for example `speedbreaker-bug-report-v0.1.7-_