281 Commits
Author SHA1 Message Date
ayozetr 6796fbbd13 Window: ask for fullscreen again when Wayland drops it at start
On Wayland a program cannot place its window. With several monitors
KWin could map the game on the one SDL reports as primary, move it to
the monitor chosen in the launcher and leave it there as a plain
window (#39); asked again, fullscreen holds, as KDE's own shortcut
showed. During the first 10 seconds the port now asks again, at most
three times and a second apart, and logs each try. After that the
desktop decides, so its own shortcuts keep working.

TROUBLESHOOTING.md: choosing the monitor, the retry and
SDL_VIDEO_DRIVER=x11 as the fallback.
2026-11-07 12:57:45 +00:00
ayozetr badd460277 Texture cache: name the images when an overlap resolve fails
The warning said only "Image overlap resolve failed". It now gives the
image the game asked for and the one dropped for it (address, size,
dimensions, format, levels and layers), and whether the dropped image
held what the GPU drew: then its contents are lost and the new image is
read from guest memory. Issue #25 had two of these warnings around a
garbled texture that went away after a reload.
2026-11-07 11:56:21 +00:00
ayozetr 1d0bbec978 Launcher: version 0.70-linux.2 0.70-linux.2 2026-11-04 11:11:38 +00:00
ayozetrandMark Hall 843424de13 Guest memory: allow device-local host types on single-pool GPUs
On integrated Intel Arc/Xe with Mesa's ANV driver every memory type is
device-local and host-pointer imports are allowed only into those, so no
type was found and the game stopped at startup with exit code 23. A second
pass now accepts a device-local host-visible type when no system-memory
type is allowed; the search is unchanged on other GPUs.

From deadinside28/bloodborne_pc#429.

Co-Authored-By: Mark Hall <[email protected]>
2026-11-04 11:11:26 +00:00
ayozetr 21e1ce4224 Game menu: Exit to desktop saves first in the world
Exit to desktop closed the window at once, so whatever the game had not
saved yet was lost (#25). In the world the System menu's entry now runs the
game's own Quit Game: its question becomes "Quit the game and return to the
desktop?", the game saves and goes back to the title, and the runtime closes
it there (the intro logos or the title menu, once no save data is mounted).

Answering No leaves the quit armed for two minutes at most; the game's own
Quit Game disarms it. On the title screen the entry still closes the game
at once, as there is nothing to save there.
2026-11-04 11:11:26 +00:00
ayozetr 498a37d24b Runtime: run the game's movbe on processors without MOVBE
The game's code was built for the PS4's CPU and has 987 movbe. AMD's FX
processors of the Piledriver generation have every other instruction the
game uses but not this one, so the game stopped with SIGILL (exit code 132)
at the first one, while reading a file header (#39).

The SIGILL handler now decodes the movbe at the faulting address, does the
load or store with its bytes swapped and resumes after it. On a processor
with MOVBE this never runs. The CPU check no longer refuses to start
without MOVBE and says in the log that the port runs them; the log also
counts them every 10 s (a few thousand a second while loading, about ten a
second while playing).

BB_MOVBE_TRAP=file turns the movbe listed by tools/movbe_sites.py into ud2,
so the emulation can be tested on any processor. tests/test_movbe.c checks
the forms the game uses.
2026-11-04 11:11:26 +00:00
ayozetr e8c7eaaf9c Players' guide: brought up to 0.70
The guide still described 0.51 in a few places:

- FAQ: The Hunter's Dream has no seamless co-op in 0.70 (summons are the
  normal game's), and no bridge relays there; the ports answer now says
  what UPnP, BBSC's relay and Tailscale each cover. New answers on the
  in-game map (preparing it, opening it with the quick menu, M or R3)
  and on FSR 4.1.2 (AMD's installer or amdxcffx64.dll, plus the FSR 4.1.x
  DLL, and the model in the port's menu).
- Troubleshooting: DLSS failures as 0.70 logs them ("DLSS: unavailable
  (...)"), Frame Generation on RTX 40 and newer, without the 0.4-linux.1
  note and a log line that no longer exists.
- Getting a log: the first line as 0.70 writes it.
- Online: the BBSC switch is "Turn on BBSC", as the launcher says.
2026-11-03 21:54:23 +00:00
ayozetr 74b1a30870 README: what the unlocked frame rate allows
The features list said the unlocked frame rate went "up to 120 FPS". In
0.7 it goes up to 480 FPS, the most the game's loading screens take, and
120 is the most the game's movement is sure to keep up with (the
launcher warns above it). The line now says so, and that the in-game
menu changes the frame rate while playing.
0.70-linux.1
2026-11-03 21:38:26 +00:00
ayozetr 62dbeefa6b AppImage build: the new image is renamed into dist/
packaging/appimage-in-arch.sh copied the new AppImage over
dist/Bloodborne-bbport-x86_64.AppImage. When the previous build was still
open (its launcher, or the game), that changed the file under its mount
and the running program could crash. The new image is now copied next to
it and renamed over it: the open one keeps running from the old file,
and the next start uses the new one.
2026-11-03 21:20:06 +00:00
7c6b25a560 Keyboard: the Linux fork's movement keys by default
bbport 0.7 turns the movement keys into a stick that ramps up over 70 ms,
turns at 1100 degrees a second and keeps a diagonal within a round gate,
and opposite keys held together cancel out. In the game that stops a
sprint when A and D (or W and S) overlap for a moment, and a diagonal
gives 90 of 127 on each axis while the game picks walk or run by the
larger one.

The movement keys now work as in 0.51-linux: the one of two opposite
keys pressed last wins, a diagonal stays on the square, the direction
turns toward the keys' at 900 degrees a second and at most 30 degrees a
read (a half turn going through forward), and a released key holds its
direction for 60 ms, so the game never sees a turn of 45 degrees or a
neutral read that would end a sprint (cassioKenji's measurements in
Supermedo/bloodborne_pc#74). bbport.ini keyboard_movement=0.7 gives back
0.7's stick; stick_socd=neutral and stick_circular=1 work as before. The
walk key and the camera keys are unchanged. The pad tests cover the keys'
direction, the turn, the release hold and the settings; the README says
it, and Jhony-Jhansen and cassioKenji are back in the credits and the
About page's thanks (in the seven languages).

Co-Authored-By: João Pedro Valadares <[email protected]>
Co-Authored-By: Supermedo <[email protected]>
2026-11-03 21:19:29 +00:00
ayozetr 43ffa68201 Launcher: About page layout
The About page lists this project, the players' guide, support, the
licence and the thanks first, and the related projects' links in one
expandable row after them, with its title in the seven languages.
2026-11-03 21:17:15 +00:00
ayozetr 0f90125d4a Discord: the repository fits in the art's hover text
Discord shows the large image's text in a narrow box that wraps at spaces
only. "github.com/ayozetr/bloodborne_linux" was one word wider than the
box and came out cut ("github.com/ayozetr/bloodbor"). The text is now
"Bloodborne on Linux · ayozetr/bloodborne_linux on GitHub": the
repository has a line of its own and the "Get the Linux port" button
still opens it. The test checks that no word is longer than the box.
2026-11-03 21:12:17 +00:00
ayozetr 02dc648c96 Build release AppImages in a plain Arch Linux container
packaging/appimage-sharun.sh bundles the system libraries of the PC it
runs on. Built on CachyOS, those come from its x86-64-v3 repositories:
libpython, GLib and GTK then carry AVX2/BMI2 instructions outside any
CPU check, and the AppImage died with SIGILL before showing anything on
processors without them (AMD FX and Phenom, Intel before Haswell; issue
#39).

packaging/appimage-in-arch.sh clones the current commit with its
submodules into out/arch-build/, builds the image from
packaging/appimage-arch.Dockerfile (archlinux:base-devel plus the build
and packaging dependencies, VulkanMemoryAllocator 3.5.0 and xbyak 7.43
headers from git), and runs build.sh, tools/build_dlss.sh and
packaging/appimage-sharun.sh inside it as the calling user. The DLSS SDK
cache and fsr4_shaders/ already on the PC are reused. The image keeps the translations Arch's Docker image leaves
out (GTK's and libadwaita's, X11's compose tables) and has the ALSA plugins for
PipeWire and PulseAudio, as a desktop does. Host networking is
used for both the image build and the run.

Checked on the result: libpython, GLib and libstdc++ have no BMI2
instructions; the ones left in glibc, GTK (CRoaring), FFmpeg, OpenSSL,
GMP and the codecs sit behind runtime CPU dispatch, as in Arch itself.
The README names the script as the way releases are built.
2026-11-03 02:01:38 +00:00
ayozetr c16b6d3d58 Discord Rich Presence: the repository in the image's tooltip and a button to it
Whoever sees the status in Discord can find the port: the large image's tooltip
names github.com/ayozetr/bloodborne_linux, and a "Get the Linux port" button
opens it. Discord shows the button to the others looking at the profile, not to
the player. Tested against Discord's length limits.
2026-11-01 23:44:35 +00:00
ayozetr b4f75ec15c Credits: what this build actually takes from each one
The credits and the launcher's thanks listed work that did not come over to 0.7:
features 0.7 replaces (the direct mouse camera, ultrawide and the HUD position,
Quit to Desktop, bbbridge, DLSS's groundwork - 0.7's DLSS is its own), the
earlier online module's shadNet fixes, keyboard movement and sprint, cloth, plants
and effects at high frame rates (pending a test against 0.7's), and renderer
fixes 0.7 does differently. Each entry now names what is in this tree; entries
with nothing left go (MaskZeus, Jhony-Jhansen, mcrib884, HatsyRei, pmwork-personal,
cassioKenji, jpramosjp, devilismyfriend, Obrikash, Vorshim92, AwesomeObserver,
gibs2193, zFenrys, and Abken's mod 537), in the credits and the launcher's thanks
in every language. Work that comes back later brings its credit back with it.
2026-11-01 23:38:23 +00:00
ayozetr c8373033ad Icon: a hunter before the crimson moon
A new icon for the launcher, the AppImage's desktop entry and the Steam shortcut:
the hunter's silhouette before a blood moon over Yharnam's spires, in a red rounded
frame. 256 px with its corners transparent (it was 128 px), stripped of metadata;
it reads at 24 px too. The old one (launcher/bloodborne.svg and its PNG) goes, and
so does it from Supermedo's credit, in the credits and the launcher's thanks in
every language. A Steam shortcut takes the new icon the next time Add to Steam is
used.
2026-11-01 23:33:10 +00:00
ayozetr 42e8b4c606 Gestures menu without the motion-control icons, as an option again
The Linux fork offered Dommo's stripped-down gestures menu (Nexus Mods,
Bloodborne mod 30) as a switch on the Controls page; it went with the fork's
prompt layer when 0.7's live prompts took over. It is back:
scripts/gestures_menu.py applies assets/menu_prompts/gesturetop.json to the
player's own menu/gesturetop.gfx (only to the file the edits were made for) as a
layer under the mods, when BB_GESTURES_NO_MOTION=1, the launcher's switch, keeps
the same setting it had. Checked against a retail 1.09 dump: the edits apply.
2026-11-01 23:31:27 +00:00
ayozetr afac1a4f39 Launcher: an own server at Seamless Hunt's address keeps its address
0.7's default shadNet address is Seamless Hunt's, and the Online page left the
own-server field empty when it held the default. The Linux fork's guide had
players enter Seamless Hunt as their own server, so for them the field showed
empty, and saving the page would have lost the server. With an own server
chosen the field now always shows its address.
2026-11-01 23:23:52 +00:00
ayozetr 4c1e2e3061 Launcher: BBSC's settings again, folded under its switch
The Linux fork's launcher had a page of BBSC's options; on 0.7 only the switch
was left, and the options could be changed through extra variables only. They
are back as an expander, "BBSC settings", under the switch: what the guest
shares with the host, five hunters, enemy scaling and its percentages per guest,
shared progress and the rest, 28 options from BBSC 0.0.2's list
(scripts/bbsc_options.json) with their names in the launcher's seven
languages. Only the options changed from BBSC's defaults are kept and passed to
the game (scripts/bbsc.py, through online.environment). Left out: BBSC's two
master switches (the BBSC switch is the one), its own Discord status and its P2P
channel, which 0.7's BBSC does not read.
2026-11-01 23:23:52 +00:00
ayozetr ab3088469a Docs: online and environment pages match 0.7's online module
- ONLINE.md quoted log lines of the earlier online module and said the co-op port
  is random by default. 0.7 uses UDP 3658, the PS4's own, unless another is set (the
  launcher's 0 keeps it), and logs its own lines for the router, the port, a sign-in
  and a server that refuses the build; the page quotes those now. The launcher's
  comment on the setting says the same.
- ENVIRONMENT.md: its list regenerated (BB_STEAM_INPUT_X11, BB_MOTION_LARGE and the
  others added since), and its header says which part is generated.
- The design notes (memory module, translator, parallel GPU commands) say they
  predate 0.7 and name switches that no longer exist.
2026-11-01 17:02:04 +00:00
ayozetr dbc374fcec run.sh: an explicit render size above 1080p gets the direct memory it needs
0.7 gives a scene above 1080p more direct memory on its scaled path only. A render
size set by hand (BB_RENDER_RES) skips that path while patches.py still grows the
graphics heaps for it, and the game stopped at start (exit 139); the Linux fork's
run.sh handled it. It does again, through the same large_scene_memory.
2026-11-01 17:00:38 +00:00
ayozetr 8e9dbc20e1 Game menu: 0.7's new rows in every language, and the test that checks them
The rows 0.7 adds to the game's own menu (the Display page with aspect ratio,
resolution and texture quality, FSR 4 through AMD's DLL, Exit to desktop, Bloom
among the effects) showed in English in Spanish, Italian, French, German,
Portuguese and Chinese. The Linux fork's test of the menu's translations, which
caught them, comes back with them.
2026-11-01 17:00:19 +00:00
ayozetr 027e834a79 Steam overlay in the sharun AppImage: found above the launcher, and passed on
0.7 loads Steam's overlay when its packaged entry (the Nix AppImage) names it in
BB_STEAM_OVERLAY. The Linux fork's AppImage is built with sharun, which has no such
entry and clears LD_PRELOAD in every program of the package, so the overlay never
loaded although the launcher's switch is on by default (#28). When Steam started the
game and nothing named it, run.sh reads Steam's 64-bit gameoverlayrenderer.so from
the nearest process above that still preloads it, as the fork's run.sh did; with
the overlay it asks sharun to pass LD_PRELOAD on (SHARUN_ALLOW_LD_PRELOAD=1) and, on
a Wayland desktop, opens the window through Xwayland, where Steam can draw it.
Tested with a simulated process tree; BB_STEAM_OVERLAY=0 still turns it off.
2026-11-01 16:59:04 +00:00
ayozetr 0219c34163 AppImage: the assets folder again, with the Xbox and Switch button art
scripts/prompt_art.py makes the live button prompts' Xbox and Switch icons from
assets/menu_prompts, but the AppImage no longer carried that folder: the prompts fell
back to letters without a word. It is copied again, as the Linux fork's AppImage did.
2026-11-01 16:58:17 +00:00
ayozetr f0306a62a1 Content: a dump without a region gets Europe (#9)
A dump whose param.sfo has no region (USER_DEFINED_PARAM_1 = 0) gave the game no
address for its server, and Log In failed with "Unable to obtain Bloodborne server
information". The Linux fork gave such a dump Europe; that went out with its Region
row, which 0.7's text and voice languages replace. It is back, without the row, and
tested.
2026-11-01 16:58:17 +00:00
ayozetr 5fd9e2ccb5 Repository: BBSC's text tables count as C++ in GitHub's language bar
The Linux fork marked BBSC's table of game texts as C++, since its <?name?>
placeholders made GitHub take it for PHP. The table moved to gpu/bbnet20/bbsc in
0.7; the attribute follows it, and covers its translations too.
2026-11-01 16:50:34 +00:00
ayozetr 311aeb36ff DLSS: tools/build_dlss.sh back, with Frame Generation, and the AppImage carries both
The Linux fork's releases ship DLSS ready to use: tools/build_dlss.sh fetches the
files of NVIDIA's DLSS SDK 310.9.1 once into ~/.cache/bbport, builds the bridge
and puts it with NVIDIA's library next to bb-probe, and the AppImage takes them.
The script had not come over to 0.7, so a build without it asked the player for
the library. It is back, and it also fetches the DLSS Frame Generation library,
which 0.7 uses on GeForce RTX 40 and newer; the AppImage now copies that one too.
2026-11-01 16:50:28 +00:00
ayozetr 3963108624 Steam Input: the window through Xwayland when Steam made a virtual controller (#12)
Steam sends its virtual controller's input only while it sees the game's window
focused, and on a Wayland desktop it only sees X11 windows: started from Steam
with Steam Input on, the controller did nothing. The Linux fork's run.sh opened
the window through Xwayland then, and that block did not come over to 0.7; it is
back (BB_STEAM_INPUT_X11=0 keeps Wayland). docs/TROUBLESHOOTING.md already
describes it.
2026-11-01 16:49:48 +00:00
ayozetr afef07c90f Version 0.70-linux.1, first in every log with bbport's
The launcher's version (launcher/bbport_update.py) moves to 0.70-linux.1, the
first release on bbport 0.7. run.sh prints it first in every log, with the build
and the bbport version it is built on: "bbport Linux 0.70-linux.1, build ...
(bbport 0.7)"; without the launcher's file, as before.
2026-11-01 15:31:37 +00:00
ayozetr aae3f0566f Credits: bbport 0.7's contributors, and the projects as 0.7 uses them
The projects table follows what this tree takes from each one now: the online
module is shadPS4 0.20's network libraries put together by Awaken, with
droogie's bbhost behind The Hunter's Dream backend, and BBSC lives in
gpu/bbnet20/bbsc with its game server in scripts/bbsc_gameserver; shadp2p and
bbbridge are no longer part of it (MaskZeus keeps the credit for bbbridge in
earlier releases). A new section names everyone bbport 0.7 took work from, with
a link to bbport's own list.
2026-11-01 15:30:55 +00:00
ayozetr dff4079ef6 Docs: BBPORT.md is bbport 0.7's README
BBPORT.md kept the original project's README from bbport 0.3. It is now 0.7's,
still marked as the original project's, with its links to documents this
repository does not carry pointing at deadinside28/bloodborne_pc.
2026-11-01 15:30:22 +00:00
ayozetr e0543751fb Docs: the environment variables from the port's own registry
docs/ENVIRONMENT.md described the 0.51 tree by hand, with file and line
references that no longer exist. Its list is now the one gpu/shim/bb_env_vars.def
gives (scripts/env_vars.py --doc), which tests/test_env_vars.py keeps complete;
how to set them and their precedence stay written by hand, brought up to date.
2026-11-01 15:30:22 +00:00
ayozetrandMikeTat1988 76ebf406f3 Hunter's Atlas: its map generator, running on Linux
The launcher's Map page (launcher/bbport_atlas_maps.py) prepares the
maps with Atlas's generator in tools/hunters-atlas, which this branch did
not have: Prepare had nothing to run. It is the Linux fork's copy of the
scripts of Atlas's source/generator/src at 4ee4a0ed (Atlas 1.3) by
MikeTat1988, with:

- art/: Atlas's source/art, its PNGs recompressed without loss (the same
  pixels, checked against their hashes by the launcher), and the fallback
  font with its licence;
- requirements.lock: exact versions with their hashes, installed by the
  launcher with uv into atlas-tools/ in the data folder;
- localize_names.py: the names of areas, lamps and pickups in the game's
  language;
- the Linux fix for parameter tables looked up by name (soulstruct gives
  Windows paths, which Path.name does not split on Linux).

The AppImage carries it next to the launcher, as in the Linux fork.
tests/test_atlas_maps.py covers the launcher's side (the maps' state,
the tools' reuse, the downloads' checks, the shipped art and lock) and
passes. scripts/env_vars.py skips BB_PATH, Soulstruct's game folder
setting in the generator, not an environment variable.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:27:21 +00:00
ayozetrandMikeTat1988 c27d8fb36b Hunter's Atlas: the map keeps what it covers when the window size changes
The map's zoom is in pixels of the drawn map, so a window made larger or
smaller (a resize, fullscreen, a new resolution) showed more or less of
the area than before. The zoom now remembers the UI scale it was set for
and follows that scale in Draw; Fit's limits scale with it too. From
Hunter's Atlas 3.0, as the Linux fork has it.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:25:56 +00:00
ayozetrandMikeTat1988 2719bce35f Hunter's Atlas: travel dialog selection and Alt+Tab
As in the Linux fork:
- The travel dialog marks its selected button and Left/Right choose
  between Travel and Cancel; the confirm button does what is selected.
  Only the button under the mouse was marked, so with a controller
  neither looked chosen.
- Losing the window's focus (Alt+Tab, local co-op) no longer closes the
  map; only what is held (sticks, zoom) is let go.
- After a travel the quick-menu tile stays hidden until the game's menu
  has closed, instead of showing on the loading screen.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:24:19 +00:00
ayozetrandMikeTat1988 8cfcdc1f76 Hunter's Atlas: the Map tile follows the game's quick menu
Measured frame by frame against recordings of the game's own menu, as in
the Linux fork:
- the tile fades in and slides with the menu as it opens, instead of
  appearing 180 ms late and still;
- it stays until the menu leaves the screen, fades out with it when the
  menu is closed with Back, and is gone before a lamp travel's loading
  screen;
- losing the window's focus (Alt+Tab, local co-op) no longer hides it or
  drops its selection;
- back from the System page the game's menu manager reports 0 instead of
  2 while the menu is shown; 0 with the quick menu's list alive counts as
  shown (src/runtime_map.c already reads it so), so the tile no longer
  stays hidden until the menu is reopened;
- its "Map" label has the game's size, colour and weight, and the cover
  over the game's own label is only as wide as that label, opaque and
  faded at its edges, without hiding the divider line;
- Up from below the Map tile focuses it and Down from it reaches the tile
  below it, as for a native tile: the game knows of no tile above the
  fourth column, so Up landed on System and Down went below System (the
  game is moved to the tile below System and Right is pulsed until it
  gets there). tests/test_bbport_atlas_menu_state.cpp covers both ways.

BB_ATLAS_DEBUG=1 (docs/ENVIRONMENT.md) logs what the tile reads from the
quick menu whenever it changes, which is how the System case was found.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:22:35 +00:00
ayozetrandMikeTat1988 a68b6a75c8 Hunter's Atlas: the map and its tile in the game's language
Atlas had its texts in English, with a Russian label on the tile only.
They now follow the port's other texts in the game, as in the Linux fork:

- the map and the quick-menu tile follow the game's language, like the
  port's pages in the game's System menu (BbGameMenu::Language, now
  exported: the game's own once its menu has looked up a text, else the
  port's menu language);
- the map's section of the port's menu (Insert) follows that menu's
  language;
- gpu/shim/bbport_atlas_i18n.h holds them in Russian, Spanish, Italian,
  French, German, Brazilian Portuguese and Simplified Chinese, with the
  game's own names where it has them (Farol, Fiole de sang, Озарение);
- the map's titles use the game's own map font in Russian too (it has
  Cyrillic); only Chinese takes the port's font, the map font having no
  CJK glyphs.

Identifiers stay in English (the travel popup's id); the text the footer
compares is translated on both sides. The names of areas and lamps come
from the generator. tests/test_atlas_i18n.cpp checks the columns and the
English fallback and runs in build.sh --test.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:20:17 +00:00
ayozetrandMikeTat1988 2bdee3185a Hunter's Atlas: the map screen, its quick-menu tile and input
Second part of Hunter's Atlas by MikeTat1988 (GPL-2.0-or-later,
github.com/MikeTat1988/HuntersAtlas): the fullscreen map, drawn with the
overlay's ImGui, and the "Map" tile next to the game's quick menu, as the
Linux fork has them.

- gpu/shim/bbport_map*.cpp, bbport_atlas_*: the map screen (layers,
  floors, walls, lamps, markers, travel dialog), its art, features, tile
  and controller shortcut. Their BB_* variables are read through bb_env()
  and listed in bb_env_vars.def (BB_MAP_SOUND_GAIN and the map's test
  hooks are new there). The map packs are read with nlohmann/json, the
  system package the online module already builds with.
- The overlay draws and ticks them, routes events and the pad to them,
  loads the map's title font and has the map's section in its menu.
  MenuOpen() is also true while the map or the tile uses the pointer, so
  the window lets the mouse go and shows the system cursor over them, as
  for the menu; CapturesInput() also covers the open map. The L3+R3 hold
  that opens the menu is unchanged.
- runtime_pad/sample.c: with the map on, the pad is read even while the
  map holds it, Atlas takes what it uses (bbgpu_atlas_route_pad), the game
  gets neutral input meanwhile, and buttons still held afterwards stay
  hidden until released (sample_atlas). Scripted input, the injected
  mouse and the game modules' pad filter stay on that path.
- runtime_audio.c and runtime_menu_sound.c: the tile's cursor sound,
  decoded on first use from the player's own sound/sprj_main.fsb with
  LibAtrac9 and mixed into the main port at the level of the game's own
  quick-menu cursor (CURSOL_SELECT, BB_MAP_SOUND_GAIN), silent in the
  background like the game.

Everything is behind BB_ATLAS_ENABLED=1: off, the overlay calls none of
it and the pad keeps its current path. build.sh --test runs the pad with
the map on (test_pad_atlas.c), the tile's state machine, map styles,
floor interiors, the controller shortcut and the features on a synthetic
features.json; test_menu_sound.c needs the player's own sound bank and
stays a manual test.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:17:04 +00:00
ayozetrandMikeTat1988 6621a1f0a7 Hunter's Atlas: the game-state readers and lamp travel
First part of Hunter's Atlas by MikeTat1988, a fullscreen in-game map
(GPL-2.0-or-later, github.com/MikeTat1988/HuntersAtlas), as the Linux fork
has it: the runtime pieces that read the game's state.

- src/runtime_map.c: the player's position, facing and area, the quick
  menu's state and which button confirms. Reads only; every guarded site
  is checked byte for byte first.
- src/runtime_atlas_state.c: event flags (read only) and the opt-in lamp
  travel (BB_MAP_TRAVEL_ENABLED=1), which hooks the game's frame pacer
  entry (0x2034770, not a site 0.7's frame rate hooks touch) and calls the
  game's own return-point and warp functions on the game thread.
- bb-probe binds them right after bbgpu_patch_image, and only with
  BB_ATLAS_ENABLED=1: with the map off, nothing of the game is touched.

Both test programs run in build.sh --test and pass. The map screen comes
next.

Co-Authored-By: MikeTat1988 <[email protected]>
2026-11-01 15:04:28 +00:00
ayozetr e2ac43b725 Local co-op: each player's window in its part of the screen, without the keyboard
The launcher's Local co-op page starts one game per player through X11
with BB_WINDOW_RECT, BB_KEYBOARD=0 for the controller players and
BB_PAD_BACKGROUND=1; 0.7 already took the chosen controller strictly
(BB_GAMEPAD_STRICT), kept it in the background and chose the monitor
(BB_DISPLAY). Now:

- BB_WINDOW_RECT=x,y,w,h (fractions of the display, read with a point
  whatever the locale) places a borderless window in that part of the
  screen, never fullscreen.
- BB_KEYBOARD=0: the game ignores the keyboard and the mouse, which reach
  whichever window has the focus; its player has a gamepad. The window
  drops their events as it does for Steam's gamepad-only mode.
- BB_PAD_BACKGROUND=1: an unfocused player's window keeps its sound
  (players 2-4 are silenced by BB_AUDIO=none instead).

From the Linux fork.
2026-11-01 15:02:38 +00:00
ayozetrandAwaken 614602cf36 Faults: a read or write fault stays within its page
A write or read fault on the last bytes of a mapping invalidated or read 8
bytes past its end: IsMapped failed and the fault went unhandled (the game
ended). Both now stay within the faulting page. From Awaken's
BloodBorneButPc engine (0.9.24), as the Linux fork has it; that change's
other half (a page whose tracking keeps faulting gets the guest's access
back) is not ported yet.

Co-Authored-By: Awaken <[email protected]>
2026-11-01 14:59:43 +00:00
ayozetrandAwaken f0068ecb34 VideoOut: a full flip queue no longer refuses an end-of-pipe flip
A full flip queue refused an end-of-pipe flip, which nobody can take back:
its caller asserted (exit 23). It is queued anyway and reported a few
times; a flip the game submits itself is still refused, as on the console.
The out-of-order flip IRQ half of this change was already in 0.7 (it waits
for the label and flips anyway). From Awaken's BloodBorneButPc engine
(0.9.24), as the Linux fork has it.

Co-Authored-By: Awaken <[email protected]>
2026-11-01 14:58:07 +00:00
ayozetrandAwaken 1f98a632b5 GPU: a garbage descriptor is reported and read as a known one, not exit 23
Several lookups ended the game (an assertion, exit 23) on a value outside
their tables, as a stale or garbage sharp brings: unknown tile, macro tile
and array modes and pipe configs, sample counts and bits per element out
of range, a mode that is not macro tiled (tiling.cpp), a data format with
no size (formats.cpp), a data/number format combination the surface table
lacks and an invalid sample count (gcn_to_vk.cpp). Each is now reported a
few times and replaced by a known value; at worst that surface renders
wrong. From Awaken's BloodBorneButPc engine (0.9.24), as the Linux fork
has it.

Co-Authored-By: Awaken <[email protected]>
2026-11-01 14:56:49 +00:00
ayozetr 4e0aa911d2 Runtime: large copy lists are recorded in slices
Loading an area on NVIDIA, a download of the buffer cache carried 178563
buffer copies (4.3 MB) into one deferred command. A command's data shares a
128 KiB recording chunk with it, so ReserveRecordData's check stopped the
game (exit 23). Buffer copies, guest chunk copies, buffer-to-image uploads
and image-to-buffer downloads are now recorded as one command per 64 KiB
of regions; UpdateBuffer already split its data. From the Linux fork.
2026-11-01 14:54:33 +00:00
ayozetrandSupermedo 312d119b5a VRAM full: allocate past the budget instead of stopping
On 6 GB cards the game went over the driver's VRAM budget and the next
image or buffer allocation stopped it ("image allocation" / "buffer
allocation", exit 23). An allocation the budget refuses is now made past
it, where the driver may keep it in system memory: slower, but the game
goes on, and the texture collector turns aggressive for a while. Logged
once per kind. Buffers that must be in VRAM or nothing (the mirrors) still
do without, as before.

From Supermedo/bloodborne_pc 44e7644, as the Linux fork has it; its other
half (dropping old GPU-written tiled images unwritten) is left out: the
Linux fork later had to write them back instead (#13, #14).

Co-Authored-By: Supermedo <[email protected]>
2026-11-01 14:53:03 +00:00
ayozetr 0d34da1577 Pipelines: skip the draws of a pipeline the driver cannot create
"Failed to create graphics pipeline: ErrorUnknown" (some AMD and older
drivers) stopped the game with code 23. The pipeline now stays empty and
is logged; its draws and dispatches are skipped, on the GPU thread and when
a background compile finishes, and it is not saved to the cache, so the
next start tries it again. A cached one the driver rejects still rebuilds
the cache, as before. After Supermedo/bloodborne_pc 188c1f6, as the Linux
fork has it.
2026-11-01 14:50:37 +00:00
ayozetrand0xCydral 28eac08195 Pipeline: skip a draw whose shader program address is not readable
A malformed command buffer can leave a shader program address that is not
mapped (0x4c0012d0000 during an area load), and reading the program there
ended the game. LooksLikeProgram, which every stage of every draw and
dispatch goes through, first checks that the program is readable and skips
the draw or dispatch otherwise; the last readable mapping is cached per
thread against the mapping table's generation. From 0xCydral's change in
the Linux fork (b99535b, after yumlevi/bloodborne_pc ce385b6 and
GoncaloLobo0/bloodborne_pc_win ef70ed2).

Co-Authored-By: 0xCydral <[email protected]>
2026-11-01 14:47:55 +00:00
ayozetrand0xCydral f0aa0fa2ae Draw preparation: a failed check or an exception ends the attempt, not the game
Draw-preparation workers specialize shaders ahead of the GPU thread from
descriptors the game may still be rewriting. A fault there already returned
to a recovery point and left the draw to the GPU thread, but a failed check
on such a torn descriptor stopped the port with exit 23, and a C++ exception
from the same data (a container over its capacity, an empty optional)
escaped the worker and ended the process through std::terminate.

A failed check while this thread's recovery point is armed now jumps there
like a fault (common/assert.cpp calls the pipeline cache's hook; anywhere
else the check still stops), and an exception is caught and treated the
same. From 0xCydral's changes in the Linux fork (917d2c0, df619c7).

Co-Authored-By: 0xCydral <[email protected]>
2026-11-01 14:45:22 +00:00
ayozetrandAwaken 983c89fa9a Shaders: the phi pass queues duplicate groups in a fixed order
The phi simplification pass queued its duplicate SCC groups in the hash
table's order, which is not the same from one run to the next, so the same
shader could compile to different SPIR-V each time. They are queued in the
SCCs' own order now (upstream shadPS4 #5364). From Awaken's Lantern Engine
(0.9.37 beta 5), as the Linux fork has it.

Co-Authored-By: Awaken <[email protected]>
2026-11-01 14:42:17 +00:00
ayozetr da3ff0ecb0 Shaders: per-mip image bindings counted the same everywhere a stage's bindings start
An image with a binding per mip level (DynamicIndex, on GPUs without
VK_AMD_shader_image_load_store_lod, such as NVIDIA's) takes one binding
number per level in the pipeline layout and in the SPIR-V, but
Info::AddBindings and the rasterizer counted one: a stage after it found
its resources at numbers the layout does not have. Both now count as the
layout does (Info::ImageBindingCount; the T# is read only for such
images). A stage whose start moves gets a new permutation, since
StageSpecialization compares the start, so saved pipelines stay valid.
From the Linux fork.
2026-11-01 14:41:16 +00:00