Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Repository files navigation

AnyBOR

An independent libretro core for OpenBOR games, offering selectable engine profiles:

v3.0 3020-dev v3.0 3057 v3.0 3062 v3.0 3073 v3.0 3081 v3.0 3109
v3.0 3117 v3.0 3143 v3.0 3160 v3.0 3173 v3.0 3192 v3.0 3208
v3.0 3273 v3.0 3288 v3.0 3303 v3.0 3307 v3.0 3310 v3.0 3311
v3.0 3316 v3.0 3317 v3.0 3318 v3.0 3327 v3.0 3328 v3.0 3330
v3.0 3332 v3.0 3335 v3.0 3337 v3.0 3340 v3.0 3341 v3.0 3342
v3.0 3350 v3.0 3351 v3.0 3352 v3.0 3353 v3.0 3354 v3.0 3355
v3.0 3356 v3.0 3357 v3.0 3360 v3.0 3361 v3.0 3362 v3.0 3365
v3.0 3366 v3.0 3367 v3.0 3371 v3.0 3372 v3.0 3373 v3.0 3375
v3.0 3379 v3.0 3380 v3.0 3381 v3.0 3383 v3.0 3385 v3.0 3388
v3.0 3391 v3.0 3394 v3.0 3397 v3.0 3400 v3.0 3406 v3.0 3411
v3.0 3415 v3.0 3416 v3.0 3420 v3.0 3422 v3.0 3427 v3.0 3428
v3.0 3431 v3.0 3434 v3.0 3436 v3.0 3441 v3.0 3445 v3.0 3446
v3.0 3449 v3.0 3454 v3.0 3458 v3.0 3461 v3.0 3463 v3.0 3465
v3.0 3467 v3.0 3469 v3.0 3472 v3.0 3477 v3.0 3482 v3.0 3500
v3.0 3509 v3.0 3511 v3.0 3515 v3.0 3517 v3.0 3520 v3.0 3526
v3.0 3549 v3.0 3550 v3.0 3551 v3.0 3552 v3.0 3553 v3.0 3554
v3.0 3557 v3.0 3559 v3.0 3562 v3.0 3565 v3.0 3567 v3.0 3568
v3.0 3581 v3.0 3583 v3.0 3585 v3.0 3586 v3.0 3587 v3.0 3591
v3.0 3594 v3.0 3596 v3.0 3597 v3.0 3602 v3.0 3604 v3.0 3605
v3.0 3608 v3.0 3609 v3.0 3611 v3.0 3614 v3.0 3618 v3.0 3619
v3.0 3623 v3.0 3624 v3.0 3626 v3.0 3629 v3.0 3631 v3.0 3633
v3.0 3635 v3.0 3638 v3.0 3639 v3.0 3640 v3.0 3644 v3.0 3646
v3.0 3647 v3.0 3649 v3.0 3650 v3.0 3651 v3.0 3655 v3.0 3656
v3.0 3657 v3.0 3660 v3.0 3661 v3.0 3663 v3.0 3664 v3.0 3665
v3.0 3666 v3.0 3667 v3.0 3669 v3.0 3670 v3.0 3671 v3.0 3672
v3.0 3673 v3.0 3674 v3.0 3675 v3.0 3677 v3.0 3678 v3.0 3679
v3.0 3680 v3.0 3682 v3.0 3685 v3.0 3686 v3.0 3689 v3.0 3690
v3.0 3691 v3.0 3692 v3.0 3693 v3.0 3694 v3.0 3697 v3.0 3699
v3.0 3701 v3.0 3703 v3.0 3704 v3.0 3707 v3.0 3708 v3.0 3709
v3.0 3710 v3.0 3711 v3.0 3713 v3.0 3714 v3.0 3715 v3.0 3716
v3.0 3722 v3.0 3725 v3.0 3726 v3.0 3727 v3.0 3728 v3.0 3729
v3.0 3730 v3.0 3732 v3.0 3738 v3.0 3740 v3.0 3741 v3.0 3742-dev
v3.0 3761-dev v3.0 3769 v3.0 3773 v3.0 3780 v3.0 3783 v3.0 3789
v3.0 3793 v3.0 3797 v3.0 3805 v3.0 3814 v3.0 3818 v3.0 3822
v3.0 3824 v3.0 3829 v3.0 3831 v3.0 3837 v3.0 3839 v3.0 3842
v3.0 3846 v3.0 3847-dev v3.0 3849 v3.0 3854 v3.0 4086 v3.0 4088-dev
v3.0 4107 v3.0 4111 v3.0 4129 v3.0 4153 v3.0 4432 v3.0 4453
v3.0 6330 v3.0 6391 v3.0 6391-mod v3.0 6392-dev v3.0 6412-dev v3.0 6510-dev
v3.0 7086-dev v3.0 7123-dev v4.0 7142-alpha v4.0 7533 v4.0 8023-dev

Core Options also provides Auto, which uses build tags and content clues to choose a profile. You can select one manually when a game needs it. See choosing a profile for details. Save states, rewind and four players are supported. OpenBOR, Senile Team and libretro credits identify upstream work; they do not imply endorsement of this port.

Original AnyBOR work by retrodiv is BSD-3-Clause-licensed. Bundled components and dependencies retain their own licenses. The combined core includes OpenBOR 3400, whose license requires prior written permission for sale of the combined sources or binaries. See licensing and redistribution for the full scope.

Build

This repository contains the complete core and dependency sources. Builds require no network access and no other project checkout. On a Linux build host, install GNU make, GCC/G++, binutils, Python 3.5 or later and NASM for x86-64. A current Python release is recommended; 3.5 compatibility supports older libretro build images. Configure scripts are included; autoreconf is not required.

Preparation artwork has one source PNG. Builds derive three native-size backgrounds with Lanczos3 on the host; install Pillow for that host's Python interpreter when changing the master image or its generator. Unchanged builds can use the included generated data after validating both input hashes, so Pillow is not a runtime dependency or required on older build images.

NUMPROC=4 make                   # native Linux x86-64, ARM64 or RISC-V64
make platform=win64              # MinGW-w64 x86-64 cross toolchain
make TARGET=linux-aarch64        # GNU ARM64 cross toolchain
make TARGET=linux-riscv64        # GNU RISC-V64 LP64D cross toolchain
make TARGET=linux-aarch64 GLIBC_MAX=2.38  # optional GNU/Linux ABI ceiling
ANDROID_NDK=/path/to/ndk make platform=android
make platform=osx                # native macOS, x86-64 or ARM64
make check
make release                    # ZIP and SHA-256 file under dist/
make source-release             # optional source tar.gz; also included in each release ZIP

The RISC-V target uses the GNU riscv64-linux-gnu toolchain and a portable VP8/VP9 decoder. Its fixed module and arena addresses fit the Sv39 userspace range. It is checked under user emulation; real hardware remains unverified. Protected-page tracking, hot-page handling and preparation use the same policies as the other Linux targets.

Video allocation follows the known content size or starts at 1920x1080 when the mode is not yet known. Larger modes expand it on demand; smaller modes and CRT option changes reuse the existing allocation. Bounds cover both the native raster and its CRT output. Restored frames reannounce their geometry. Growing the allocation requires frontend support for AV-info changes; geometry-only updates remain the fallback when that request is refused.

The libraries are named anybor_libretro.so, anybor_libretro.dll, anybor_libretro_android.so and anybor_libretro.dylib. CC, CXX, AR, LD, OBJCOPY, STRIP, CFLAGS, CXXFLAGS, LDFLAGS and NASM can select an installed toolchain. On macOS the build selects clang/clang++ and the system linker, and accepts the LIBRETRO_APPLE_PLATFORM and LIBRETRO_APPLE_ISYSROOT variables the libretro osx-arm64 recipe exports. Set NUMPROC or JOBS to limit parallel compilation, and OBOR_BUILD_ROOT to move build outputs outside this directory. With OBOR_BUILD_ROOT set, consume the library and its build.json receipt only from $OBOR_BUILD_ROOT/dist/<target>/; managed builds do not overwrite a library in the source root. Ordinary make without this variable retains the conventional root library for frontend/buildbot compatibility. Dependencies are built from src/deps/; there is no download or prebuilt-library fallback.

External toolchains can set CONFIGURE_HOST and CONFIGURE_BUILD to the Autoconf system triplets used by libpng, libogg and libvorbis. For a Buildroot package, pass CONFIGURE_HOST="$(GNU_TARGET_NAME)" and CONFIGURE_BUILD="$(GNU_HOST_NAME)" to Make alongside its toolchain environment. The host is where the resulting library runs; the build is where compilation takes place. These settings do not select a compiler or a new AnyBOR target.

CONFIGURE_HOST=auto queries the selected CC with -dumpmachine, including compiler launchers such as ccache. An explicit host also selects the build triplet using the bundled config.guess unless CONFIGURE_BUILD is supplied. CONFIGURE_BUILD=auto requests that same detection, honoring CC_FOR_BUILD or HOST_CC instead of the cross compiler. Both resolved values invalidate the dependency cache when changed. With neither setting, existing target defaults apply.

Direct Python calls accept --configure-host=TRIPLET|auto and --configure-build=TRIPLET|auto; command-line values override the environment. For example:

CC=x86_64-buildroot-linux-gnu-gcc make TARGET=linux-x86_64 CONFIGURE_HOST=auto

Normal builds allow local logs and editor files outside SOURCES.json; these files are not added to the build's source receipt. make check, make release and make source-release require the checked source inventory. Keep temporary files under .build/ or outside the checkout when running publication checks. For intentional source additions, see CONTRIBUTING.md.

Only 64-bit x86, ARM and RISC-V targets are supported. Android uses ARM64 and API 24 or later. macOS targets x86-64 (10.13 or newer) and ARM64 (11.0 or newer) and links only against libSystem. jni/Android.mk and jni/Application.mk provide the ndk-build entry point used by the libretro Android runner. .gitlab-ci.yml uses the libretro CI templates; GitHub Actions also compiles and packages the core, including native macOS x86-64 and ARM64 jobs. Availability through core download services is managed by their maintainers. The required submission files, target commands and external registration steps are listed in docs/PUBLISHING.md. The core's frontend requirements, controls and core options are in docs/ANYBOR.md.

Content

Load a .pak, an unpacked game's data/models.txt, or a ZIP containing one game. ZIP entries are checked before extraction. A unique recognizable game can share its ZIP with identifiable auxiliary files; multiple games or inconclusive candidates are rejected. Verified engine executable hashes select the corresponding build before filename and content detection. A manual profile choice takes priority. Executables are inspected as data, never executed. The .txt extension is for data/models.txt, not arbitrary text documents. Newer engine versions are supported on a best effort basis through the latest pinned engine.

No third-party game data, artwork, music, BIOS or game executables are included. Use content you are entitled to use. Engine compatibility does not grant rights to redistribute a game's assets. Saves use the directory supplied by the frontend, under AnyBOR/<game>/<engine build>/; ZIP extraction uses AnyBOR-cache/zipcache/. Save states require the same core build and content.

See installation and data directories for frontend setup, external INI configuration and backup guidance.

Save states and rewind

For rewind, we recommend Rewind Frames set to 10 and Rewind Buffer Size (MB) set to 256. We only recommend enabling rewind on a Raspberry Pi 5 (quad-core Cortex-A76 at 2.4 GHz) or a device with an equivalent or faster CPU.

The System category offers Save state content (Smart / Full) and Save state compression (On / Off). Smart reconstructs resources only when their bytes can be reproduced exactly; Full retains complete engine memory. Compression Off leaves changed blocks uncompressed and keeps the reuse of unchanged blocks. These options apply when content is loaded; changing them during a session, resetting or loading a state does not change that session's writer. Diagnostic environment overrides retain priority.

The default is Smart + On. Supported targets also enable dirty-page tracking, advance state preparation, bounded encoder-pool maintenance and the synchronous compression helper. Linux, Android and macOS use guarded page protection; Windows uses its native write-watch API. Full + Off may not fit the 256 MiB rewind buffer in large games. The available duration and capture cost depend on the game, machine and selected combination.

Smart, and Full with compression On, use complete, independently loadable states with a fixed 64 MiB libretro transport. This is the size of one serialized state, not additional rewind history. The frontend owns the history within its 256 MiB buffer. Its available duration depends on how much state changes: a large transition can shorten it substantially.

The engines identify source-backed sample bytes; engines 3842 and later also identify reconstructible sprite bodies. Engine 3400 retains its sprite bytes in the mutable state. The common state layer verifies resource contents before replacing them with reconstruction recipes. Script-modified or unrecognized data stays in the mutable state. Headers, palettes, internal references, allocator metadata, engine globals, the live coroutine stack and audio playback state are retained. This selection depends on resource structure and lifetime, never game names or fingerprints.

Every snapshot contains the information needed to rebuild its resources from the loaded content, including in a new session with an empty cache. The resource cache is bounded to 128 MiB and holds only source-derived data. Restoration staging is bounded to 256 MiB; resources beyond that budget remain ordinary state bytes. The block codec caches only its current image. None of these caches stores additional rewind history. A failed reconstruction or a complete state that exceeds its transport budget is rejected; data is never truncated to make a capture fit.

The compressed transport uses OBC1 with independently encoded blocks and a resource manifest. Each image is complete and can be decoded without an earlier snapshot. New blocks use a compact initial encoding; changed blocks use a fast lossless codec. Bounded slot maintenance limits fragmentation. State preparation follows the frontend's observed capture interval and stops when captures stop; the requested capture still validates the current bytes. Unused transport bytes are deterministically zero. Fixed frontend capacity remains unchanged across loading, gameplay and Reset.

On supported Windows, Linux, Android and macOS targets, captures with enough observed encoding work can use one auxiliary compression thread. It finishes before capture returns; the engine never advances while it is working. Scratch space stays below 2.1 MiB and stores no rewind history. Lighter updates, unavailable CPU measurements or threads, and single-CPU systems retain serial compression. Both paths produce the same serialized bytes and preserve the capture frequency.

On supported targets, classic movie decoders retain write tracking while their engine-owned workers run, including between frontend calls. This avoids rechecking untouched resources after playback. Captures remain unavailable while workers are active. The asynchronous movie adapter has additional worker ownership and conservatively invalidates those proofs before playback instead.

On supported page-protection tracking targets, bounded learning identifies frequently written pages and leaves those pages writable. Every such page remains dirty for state validation, including repeated writes between captures. It never supplies an immutable resource or block proof. Resource recipe metadata and allocation ordering are reused only while their validity checks hold; all allocation bounds and global nonoverlap checks are retained. These policies do not omit mutable state or change the frontend's fixed state capacity.

The Android core is one installable .so. It contains a small libretro loader and the engine ELF; Android's android_dlopen_ext loads the engine at a reserved, stable address. This preserves saved code/static-data pointers without scanning and modifying arbitrary game data after ASLR changes. An address collision fails safely. Incompatible states are rejected before restoring engine memory.

Full + Off uses the complete OBS writer with binary-identity and runtime-storage checks. It sizes its fixed capacity from packed content and measured heap peaks; content that outgrows its allowance requires a restart to use the learned peak. Save states should be made and loaded with the same core build and content.

The reader accepts states from all four combinations regardless of the current writer selection. The ordinary build, layout, content and resource checks still apply. Both Smart and Full require the module to be at its original address. If its address changes on any platform, loading is refused with a state module address differs log message before changing the live game. The core does not guess which memory words are pointers or silently change the selected writer. This limits cross-process save states on macOS, where ASLR can move the dylib. After closing and reopening the frontend on macOS, expect loads to be refused if the module address changed. Selecting Full does not bypass the address check. Same-session rewind and restoration do not require relocation and remain available.

Within a compatible core build, loading a Full state in a Smart session preserves the game, but resources without reconstruction recipes remain stored as bytes. Capture cost and rewind duration may differ from a game started in Smart. Saving again as Smart does not recover missing recipes; starting the game afresh in Smart rebuilds them as resources load.

Save states and rewind are temporarily unavailable while the engine preloads models. Some games also preload models briefly while the player is already on screen. A manual save or load can be refused during that interval, and rewind history can contain gaps. Normal operation resumes when preloading finishes.

Loading a state retains the current session's content and writable-directory paths. Engine random-number state is captured with the world so external frontend activity does not change the restored AI sequence. Saving, loading and rewind are unavailable during internally threaded movie playback; the frontend's separate threaded-video setting does not trigger this exclusion. Returning from gameplay to an earlier menu requires its state to remain within the finite history. Entering gameplay does not clear the history.

Licenses and redistribution

The combined core has multiple licenses. Engine 3400 prohibits sale of its source and binaries, including modified versions, without specific prior written permission from the OpenBOR Team. Free redistribution must retain its terms and all other applicable notices. The port's BSD-3-Clause license does not replace engine or dependency licenses. Read LICENSES.md.

make release packages the exact binary with its license dossier, build receipt and matching sources in a source.tar.gz. PACKAGE.json records the binary and source-archive hashes. The complete dossier is also embedded in every core library; when content is loaded, the core attempts to write it as anybor-license-notices.txt in the frontend's save directory. This preserves access to notices when an updater transports a bare DLL/SO. NOTICE.txt is the same dossier in readable form. Redistributors should include that file and LICENSES/ with their downloads.

The original diagnostic fixture generator and native smoke test are described in docs/TESTING.md.

See MODIFICATIONS.md for changes to the selectable profiles, with file inventories and source references, PROVENANCE.md for source origins, CONTRIBUTING.md for development, and SECURITY.md for content trust and private reporting.

Optional content preparation

An otherwise complete, unencoded PACK with a damaged four-byte signature is repaired automatically after its directory and plain image assets are validated. This does not require AnyBOR.ini.

Optional buffer transforms can extract an archive from a custom header or a specified byte range, or convert stored 32-bit words to the byte order expected by the reader. Select an adapter in the frontend system directory's AnyBOR.ini. See configuration and examples.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages