mirror of
https://github.com/libretro/FBNeo.git
synced 2026-11-07 11:06:01 -10:00
* Add headless frontend for embedding FBNeo
A new "headless" port that builds libfbneo as a shared library (fbneo_headless.dylib) exposing a small C API, for embedding in native host frontends.
Built originally to support OpenEmu-Silicon.
* Add input mapping and timing/aspect/reset to the C API
Rounds out the headless frontend with the functions a host wrapper needs to
actually run and control a game, instead of only loading one.
Input mapping (headless_input.cpp): FBHeadlessSetInput(player, button, value)
turns a simple arcade control (Up/Down/Left/Right, buttons 1-6, Start, Coin,
Service) into the right input for whatever driver is loaded. It does this by
reading each input's canonical name from the driver ("p1 up", "p1 fire 1",
"p1 coin", "p1 start", and the "coin N"/"start N" variants) and rebinding that
input to a private switch code the headless input plugin reads back. Inputs
that don't match a control are parked on a dead code so they always read as
released.
Timing and geometry, needed for correct video/audio sync and aspect ratio:
- FBHeadlessGetFrameRate() - the game's refresh rate (fps x 100)
- FBHeadlessGetAspectX/Y() - the game's pixel aspect ratio
- FBHeadlessReset() - reset the running game
The FBHeadlessButton enum lists the supported controls in a fixed order so the
host can pass them straight through.
* Add save/load functions
* Add support for cheats and RetroAchievements
* Address comments from adversarial review
* Honor BDF_16BIT_ONLY (Cave, CPS3, Megadrive)
These drivers only blit RGB565. Rendering them at 32bpp produced garbled graphics. Render at 16bpp and convert to 32bpp on present (combined with the existing rotation pass so vertical games get both), fixing Cave, CPS3 and Megadrive-arcade video while keeping the 32bpp zero-copy fast path.
* Map the Service and Configure keys to the test and service switches
Most drivers name their cabinet switches "diag" (test switch, opens the
settings menu) and "service" with no player prefix, so the headless mapper
never bound them and the frontend's Service key did nothing.
Service now drives the test switch, or "service" when a driver has no test
switch. A new FBHeadlessButtonConfigure drives "service" in drivers that
have both (it usually adds a service credit).
* Map twin-stick games
Drivers name the second stick inconsistently: "pN <dir> 2", or another player's plain d-pad (Robotron's "Fire Up" is "p2 up", Smash TV's fire stick is p3/p4, Angel Kids' left stick is p3). The headless mapper dropped the first form and sent the second to the wrong player, so Robotron's fire stick only worked from a second controller.
When the display name names a stick (Left Stick, Right Stick, Fire, Shoot, Aim...), it now decides the stick and the player; otherwise "pN <dir> 2" is player N's right stick. Like the MAME core, the left stick goes on the d-pad and the right stick on buttons 1-4 (left, up, down, right), since OpenEmu's arcade controller has one stick.
* Report little-endian cheat memory for TMS34010 and V60 boards
GetMainMemoryBigEndian returned 1 for CPUs with MB_CHEAT_ENDI_SWAP, but those (TMS34010, V60) are little-endian; the flag only exists because FBNeo's own cheat engine stores values big-endian. The host then wrote multi-byte cheats in the wrong order: in Mortal Kombat "0000A260:00A1" stored bytes 00 A1, so P1 health read as 0xA100 (bar overfilled, dies in one hit).
Every board now reports little-endian, which is what the 68K boards already did by the RetroAchievements/libretro convention.
Headless check (mk, round 1, cheat 0000A260:00A1 at frame 3100):
before: A260=00 A261=A1 after the cheat (was A1 00)
after: A260=A1 A261=00, unchanged from what the game wrote
* Save battery-backed RAM in the headless burner
Drivers keep battery-backed RAM (ACB_NVRAM: Mortal Kombat's settings,
Robotron's high scores...) only as a scan area; the frontend has to save
it. The Windows burner does that with StatedAuto in DrvInit/DrvExit, but
the headless burner never did, so those games lost their settings every
session (unlike EEPROM games, which the device saves itself).
Like the Windows burner, DrvInit(bRestore) now loads
<szAppEEPROMPath><set>.fs and DrvExit saves it. Loading a game and Reset
both restore it. Drivers without NVRAM write no file.
Headless check (mk, three runs sharing the support folder, 600 frames):
before: only mk.ini saved
after: mk.fs saved; run 1 (blank NVRAM) sits on one screen, runs 2 and
3 boot normally and are identical. sfa still saves sfa.nv only.
136 lines
3.5 KiB
Makefile
136 lines
3.5 KiB
Makefile
# Main Makefile for FBNeo, execute an appropriate system-specific makefile
|
|
|
|
export
|
|
|
|
#
|
|
# Declare variables
|
|
#
|
|
|
|
# Make a special build, pass the quoted text as comment (use FORCE_UPDATE declaration below to force recompilation of resources)
|
|
# SPECIALBUILD = "This text will appear in the property sheet of the .exe file"
|
|
|
|
|
|
#
|
|
# Flags. Uncomment any of these declarations to enable their function.
|
|
#
|
|
|
|
# Include Unicode support
|
|
UNICODE = 1
|
|
|
|
# Build A68K ASM 68000 core
|
|
#BUILD_A68K = 1
|
|
|
|
# Include x86 Assembly routines
|
|
BUILD_X86_ASM = 1
|
|
|
|
# Include GCC optmisations for your CPU e.g use -march=native. WARNING: This might mean that the generated binaries will not run on other peoples (older) machines!
|
|
#BUILD_NATIVE = 1
|
|
|
|
# Build for x64 targets (MinGW64 and MSVC only, this will undefine BUILD_A68K and BUILD_X86_ASM)
|
|
#BUILD_X64_EXE = 1
|
|
|
|
# Build for Windows XP target (for use with Visual Studio 2012-15)
|
|
#BUILD_VS_XP_TARGET = 1
|
|
|
|
# Include 7-zip support
|
|
INCLUDE_7Z_SUPPORT = 1
|
|
|
|
# Include AVI recording support (uses Video For Windows)
|
|
INCLUDE_AVI_RECORDING = 1
|
|
|
|
# Include LUA support (on Windows Standalone, LUA is enabled regardless)
|
|
#INCLUDE_LUA_SUPPORT = 1
|
|
|
|
# Include symbols and other debug information in the executable
|
|
#SYMBOL = 1
|
|
|
|
# Include features for debugging drivers unless we are doing a release build
|
|
ifndef RELEASEBUILD
|
|
DEBUG = 1
|
|
endif
|
|
|
|
# Include rom set verifying features (comment this for release builds)
|
|
#ROM_VERIFY = 1
|
|
|
|
# Force recompilation of files that need it (i.e. use __TIME__, __DATE__, SPECIALBUILD).
|
|
FORCE_UPDATE = 1
|
|
|
|
# Use the __fastcall calling convention when interfacing with A68K/Musashi/Doze
|
|
FASTCALL = 1
|
|
|
|
# Compress executable with upx (the DEBUG option ignores this)
|
|
# COMPRESS = 1
|
|
|
|
# Perl is available
|
|
PERL = 1
|
|
|
|
# Endianness
|
|
LSB_FIRST = 1
|
|
|
|
# Include png.h from burner.h
|
|
INCLUDE_LIB_PNGH = 1
|
|
|
|
# Enable CRT resolution switching
|
|
# INCLUDE_SWITCHRES = 1
|
|
|
|
#
|
|
# execute an appropriate system-specific makefile
|
|
#
|
|
|
|
mingw345: FORCE
|
|
@$(MAKE) -s -f makefile.mingw GCC345=1
|
|
|
|
mingw452: FORCE
|
|
@$(MAKE) -s -f makefile.mingw GCC452=1
|
|
|
|
mingw471: FORCE
|
|
@$(MAKE) -s -f makefile.mingw GCC471=1
|
|
|
|
mingw510: FORCE
|
|
@$(MAKE) -s -f makefile.mingw GCC510=1
|
|
|
|
# MinGW w/gcc 5.1.x to gcc 11.x (present)
|
|
# note: BORKYCRT fixes swprintf() which MSYS2 broke some time 2021
|
|
mingw: FORCE
|
|
@$(MAKE) -s -f makefile.mingw GCC510=1 BORKYCRT=1
|
|
|
|
# Cross compile a 32 bits windows binary from linux
|
|
mingwcc: FORCE
|
|
@$(MAKE) -s -f makefile.mingw GCC510=1 BORKYCRT=1 HOST_CC=gcc HOST_CXX=g++ CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ WINDRES=i686-w64-mingw32-windres
|
|
|
|
# Cross compile a 64 bits windows binary from linux
|
|
mingwcc64: FORCE
|
|
@$(MAKE) -s -f makefile.mingw BUILD_X64_EXE=1 GCC510=1 BORKYCRT=1 HOST_CC=gcc HOST_CXX=g++ CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ WINDRES=x86_64-w64-mingw32-windres
|
|
|
|
# Native Windows ARM64 build with MSYS2 (CLANGARM64 environment)
|
|
# note: MSYS2 can't produce binaries for ARMv8.0
|
|
mingwarm64: FORCE
|
|
@$(MAKE) -s -f makefile.mingw BUILD_ARM64_EXE=1 GCC510=1 BORKYCRT=1
|
|
|
|
# Cross compile a windows ARM64 binary from linux (llvm-mingw)
|
|
mingwccarm64: FORCE
|
|
@$(MAKE) -s -f makefile.mingw BUILD_ARM64_EXE=1 GCC510=1 BORKYCRT=1 HOST_CC=gcc HOST_CXX=g++ CC=aarch64-w64-mingw32-clang CXX=aarch64-w64-mingw32-clang++ WINDRES=aarch64-w64-mingw32-windres
|
|
|
|
mamemingw: FORCE
|
|
@$(MAKE) -s -f makefile.mamemingw
|
|
|
|
sdl: FORCE
|
|
@$(MAKE) -s -f makefile.sdl
|
|
|
|
sdl2: FORCE
|
|
@$(MAKE) -s -f makefile.sdl2
|
|
|
|
headless: FORCE
|
|
@$(MAKE) -s -f makefile.headless
|
|
|
|
vc: FORCE
|
|
@$(MAKE) -s -f makefile.vc
|
|
|
|
vc18: FORCE
|
|
@$(MAKE) -s -f makefile.vc18
|
|
|
|
pi: FORCE
|
|
@$(MAKE) -s -f makefile.pi
|
|
|
|
FORCE:
|