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.
640 lines
15 KiB
Plaintext
640 lines
15 KiB
Plaintext
# Makefile for FBNeo, headless core (derived from makefile.sdl2)
|
|
#
|
|
# The first pass makes sure all intermediary targets are present. The second pass updates
|
|
# any targets, if necessary. (Intermediary) targets which have their own unique rules
|
|
# are generated as required.
|
|
|
|
unexport
|
|
|
|
UNAME_S := $(shell uname -s)
|
|
ifeq ($(UNAME_S),Darwin)
|
|
DARWIN=1
|
|
endif
|
|
|
|
ifdef DARWIN
|
|
PLATFLAGS += -arch arm64 -mmacosx-version-min=11.0 -Wno-deprecated-declarations
|
|
endif
|
|
|
|
|
|
ifeq ($(OS),Windows_NT)
|
|
WINDOWS=1
|
|
endif
|
|
|
|
#
|
|
# Flags. Uncomment any of these declarations to enable their function.
|
|
#
|
|
|
|
# Check for changes in header files
|
|
ifndef SKIPDEPEND
|
|
DEPEND = 1
|
|
endif
|
|
|
|
# SANITIZE = 1
|
|
|
|
#
|
|
# Declare variables
|
|
#
|
|
|
|
# Specify the name of the executable file, without ".exe"
|
|
NAME = fbneo
|
|
|
|
PERL = 1
|
|
LSB_FIRST = 1
|
|
INCLUDE_7Z_SUPPORT = 1
|
|
|
|
BUILD_X86_ASM=
|
|
INCLUDE_AVI_RECORDING=
|
|
BUILD_A68K=
|
|
UNICODE=
|
|
|
|
|
|
#
|
|
# Specify paths/files
|
|
#
|
|
|
|
objdir = obj/
|
|
srcdir = src/
|
|
|
|
include makefile.burn_rules
|
|
|
|
# Platform stuff
|
|
alldir += burner burner/headless burner/sdl dep/libs/libspng dep/libs/lib7z dep/libs/zlib intf intf/video \
|
|
intf/video/scalers intf/video/headless intf/audio intf/audio/headless intf/input intf/input/headless intf/cd \
|
|
dep/generated
|
|
|
|
depobj += cdlist.o \
|
|
\
|
|
conc.o cong.o dat.o gamc.o gami.o image.o ioapi.o misc.o sshot.o state.o statec.o unzip.o zipfn.o \
|
|
\
|
|
adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o gzwrite.o infback.o inffast.o inflate.o inftrees.o \
|
|
trees.o uncompr.o zutil.o \
|
|
\
|
|
spng.o \
|
|
\
|
|
aud_dsp.o aud_interface.o cd_interface.o cd_chd.o inp_interface.o interface.o lowpass2.o vid_interface.o \
|
|
vid_support.o \
|
|
\
|
|
inp_headless.o aud_headless.o vid_headless.o support_paths.o ips_manager.o scrn.o localise_gamelist.o romdata.o \
|
|
cd_img.o stringset.o bzip.o media.o \
|
|
inpdipsw.o inputbuf.o replay.o stated.o headless_main.o headless_drv.o headless_misc.o headless_input.o headless_memory.o
|
|
|
|
ifdef FORCE_PULSE_AUDIO
|
|
alldir += intf/audio/linux
|
|
|
|
depobj += aud_pulse_simple.o
|
|
endif
|
|
|
|
ifdef INCLUDE_7Z_SUPPORT
|
|
depobj += un7z.o \
|
|
\
|
|
7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zFile.o 7zStream.o Alloc.o Bcj2.o Bra.o Bra86.o BraIA64.o CpuArch.o \
|
|
Delta.o LzFindOpt.o LzmaDec.o Lzma2Dec.o MtDec.o Ppmd7.o Ppmd7Dec.o Ppmd7aDec.o Sha256.o Sha1Opt.o Sha256Opt.o Threads.o Xxh64.o Xz.o XzCrc64.o XzCrc64Opt.o XzDec.o ZstdDec.o
|
|
endif
|
|
|
|
autobj += $(depobj)
|
|
|
|
ifdef BUILD_X86_ASM
|
|
autobj += eagle_fm.o 2xsaimmx.o hq2x32.o hq3x32.o hq4x32.o superscale.o
|
|
endif
|
|
|
|
# End, platform stuff
|
|
|
|
incdir = $(foreach dir,$(alldir),-I$(srcdir)$(dir)) -I$(objdir)dep/generated
|
|
|
|
lib = -lstdc++ -lm -lpthread
|
|
|
|
ifdef FORCE_PULSE_AUDIO
|
|
lib += -lpulse-simple
|
|
endif
|
|
|
|
|
|
ifdef INCLUDE_SWITCHRES
|
|
incdir += `pkg-config --cflags switchres`
|
|
lib += `pkg-config --libs switchres`
|
|
endif
|
|
|
|
autdep = $(depobj:.o=.d)
|
|
drvdep = $(drvsrc:.o=.d)
|
|
|
|
ifdef BUILD_A68K
|
|
a68k.o = $(objdir)cpu/a68k/a68k.o
|
|
endif
|
|
|
|
driverlist.h = $(srcdir)dep/generated/driverlist.h
|
|
ctv.h = $(srcdir)dep/generated/ctv.h
|
|
toa_gp9001_func.h = $(srcdir)dep/generated/toa_gp9001_func.h
|
|
neo_sprite_func.h = $(srcdir)dep/generated/neo_sprite_func.h
|
|
cave_tile_func.h = $(srcdir)dep/generated/cave_tile_func.h
|
|
cave_sprite_func.h = $(srcdir)dep/generated/cave_sprite_func.h
|
|
psikyo_tile_func.h = $(srcdir)dep/generated/psikyo_tile_func.h
|
|
pgm_sprite.h = $(srcdir)dep/generated/pgm_sprite.h
|
|
build_details.h = $(srcdir)dep/generated/build_details.h
|
|
|
|
allobj = $(objdir)cpu/m68k/m68kcpu.o $(objdir)cpu/m68k/m68kops.o \
|
|
$(foreach file,$(autobj:.o=.c), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .c,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
|
$(foreach file,$(autobj:.o=.cpp), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .cpp,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
|
$(foreach file,$(autobj:.o=.asm), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .asm,.o,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
|
$(foreach file,$(autobj:.o=.rc), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .rc,.o,$(wildcard $(srcdir)$(dir)/$(file)))))))
|
|
|
|
ifdef BUILD_A68K
|
|
allobj += $(a68k.o)
|
|
endif
|
|
|
|
alldep = $(foreach file,$(autobj:.o=.c), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .c,.d,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
|
$(foreach file,$(autobj:.o=.cpp), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .cpp,.d,$(wildcard $(srcdir)$(dir)/$(file))))))) \
|
|
$(foreach file,$(autobj:.o=.rc), \
|
|
$(foreach dir,$(alldir),$(subst $(srcdir),$(objdir), \
|
|
$(firstword $(subst .rc,.d,$(wildcard $(srcdir)$(dir)/$(file)))))))
|
|
|
|
autdrv := $(drvsrc:.cpp=.o)
|
|
|
|
#
|
|
#
|
|
# Specify compiler/linker/assembler
|
|
#
|
|
#
|
|
|
|
ifdef DARWIN
|
|
CC = gcc
|
|
else
|
|
CC = gcc
|
|
endif
|
|
|
|
CXX = $(CC)
|
|
LD = $(CC)
|
|
AS = nasm
|
|
|
|
# While cross-compiling, tools need to be compiled for host so that they can be executed by host.
|
|
# if HOST_CC is not set, then we aren't cross-compiling, so we'll use target compiler as host compiler
|
|
ifeq ($(HOST_CC),)
|
|
HOST_CC := $(CC)
|
|
HOST_CXX := $(CXX)
|
|
HOST_CFLAGS := $(CFLAGS)
|
|
HOST_CXXFLAGS := $(CXXFLAGS)
|
|
HOST_LDFLAGS := $(LDFLAGS)
|
|
endif
|
|
|
|
#LDFLAGS = -static
|
|
|
|
CFLAGS = -O2 -fomit-frame-pointer -Wno-write-strings \
|
|
-Wall -Wno-long-long -Wno-sign-compare -Wno-uninitialized -Wno-unused \
|
|
-Wno-conversion -Wno-attributes \
|
|
-Wno-unused-parameter -Wno-unused-value -std=c99 \
|
|
$(PLATFLAGS) $(DEF) $(incdir)
|
|
|
|
CXXFLAGS = -O2 -fomit-frame-pointer -Wno-write-strings \
|
|
-Wall -W -Wno-long-long -Wno-sign-compare \
|
|
-Wunknown-pragmas -Wundef -Wconversion -Wno-missing-braces \
|
|
-Wuninitialized -Wpointer-arith -Winline -Wno-multichar \
|
|
-Wno-conversion -Wno-attributes \
|
|
-Wno-unused-parameter -Wno-unused-value -Wno-narrowing \
|
|
$(PLATFLAGS) $(DEF) $(incdir)
|
|
|
|
ASFLAGS = -O1 -f coff -w-orphan-labels
|
|
|
|
# D3DUtils & D3DMath need these
|
|
# DEF = -Dsinf=\(float\)sin -Dcosf=\(float\)cos -Dasinf=\(float\)asin -Dacosf=\(float\)acos -Dsqrtf=\(float\)sqrt
|
|
|
|
# FIXME
|
|
DEF := -DBUILD_HEADLESS -DINCLUDE_FLACMP3_SUPPORT -DUSE_SPEEDHACKS -DFILENAME=$(NAME) -DUSE_FILE32API -DHAVE_UNISTD_H
|
|
|
|
ifdef FORCE_PULSE_AUDIO
|
|
DEF := $(DEF) -DFORCE_PULSE_AUDIO
|
|
endif
|
|
|
|
ifdef WINDOWS
|
|
DEF := $(DEF) -DSDL_WINDOWS
|
|
endif
|
|
|
|
ifdef UNICODE
|
|
DEF := $(DEF) -D_UNICODE
|
|
endif
|
|
|
|
ifdef SPECIALBUILD
|
|
DEF := $(DEF) -DSPECIALBUILD=$(SPECIALBUILD)
|
|
endif
|
|
|
|
ifdef FASTCALL
|
|
DEF := $(DEF) -DFASTCALL
|
|
endif
|
|
|
|
ifdef DEBUG
|
|
DEF := $(DEF) -DFBNEO_DEBUG
|
|
endif
|
|
|
|
ifdef ROM_VERIFY
|
|
DEF := $(DEF) -DROM_VERIFY
|
|
endif
|
|
|
|
ifdef INCLUDE_7Z_SUPPORT
|
|
DEF := $(DEF) -DINCLUDE_7Z_SUPPORT
|
|
endif
|
|
|
|
ifdef INCLUDE_AVI_RECORDING
|
|
DEF := $(DEF) -DINCLUDE_AVI_RECORDING
|
|
endif
|
|
|
|
ifdef LSB_FIRST
|
|
DEF := $(DEF) -DLSB_FIRST
|
|
endif
|
|
|
|
ifdef INCLUDE_LIB_PNGH
|
|
DEF := $(DEF) -DINCLUDE_LIB_PNGH
|
|
endif
|
|
|
|
ifdef BUILD_A68K
|
|
DEF := $(DEF) -DBUILD_A68K
|
|
endif
|
|
|
|
ifdef BUILD_X86_ASM
|
|
DEF := $(DEF) -DBUILD_X86_ASM
|
|
endif
|
|
|
|
ifdef BUILD_X64_EXE
|
|
DEF := $(DEF) -DBUILD_X64_EXE
|
|
endif
|
|
|
|
ifdef INCLUDE_SWITCHRES
|
|
DEF := $(DEF) -DINCLUDE_SWITCHRES
|
|
endif
|
|
|
|
ifdef SANITIZE
|
|
ifndef SYMBOL
|
|
SYMBOL =1
|
|
endif
|
|
CFLAGS += -fsanitize=address -fsanitize=undefined -fsanitize=bounds-strict
|
|
CXXFLAGS += -fsanitize=address -fsanitize=undefined -fsanitize=bounds-strict
|
|
endif
|
|
|
|
ifdef SYMBOL
|
|
CFLAGS += -ggdb3 -fno-omit-frame-pointer
|
|
CXXFLAGS += -ggdb3 -fno-omit-frame-pointer
|
|
ASFLAGS += -g
|
|
DEF := $(DEF) -D_DEBUG
|
|
else
|
|
LDFLAGS += -s
|
|
endif
|
|
|
|
ifdef PROFILE
|
|
CFLAGS += -pg
|
|
CXXFLAGS += -pg
|
|
endif
|
|
|
|
|
|
ifdef BUILD_NATIVE
|
|
CFLAGS += -march=native -mtune=native
|
|
CXXFLAGS += -march=native -mtune=native
|
|
endif
|
|
|
|
# For zlib
|
|
DEF := $(DEF) -DNO_VIZ -D_LARGEFILE64_SOURCE=0 -D_FILE_OFFSET_BITS=64
|
|
|
|
# For libchdr
|
|
DEF := $(DEF) -DCHDR_SYSTEM_ZLIB
|
|
|
|
# For lib7z
|
|
ifdef INCLUDE_7Z_SUPPORT
|
|
DEF := $(DEF) -D_7ZIP_PPMD_SUPPPORT -D_7ZIP_ST
|
|
endif
|
|
|
|
#
|
|
#
|
|
# Specify paths
|
|
#
|
|
#
|
|
|
|
vpath %.asm $(foreach dir,$(alldir),$(srcdir)$(dir)/ )
|
|
vpath %.cpp $(foreach dir,$(alldir),$(srcdir)$(dir)/ )
|
|
vpath %.c $(foreach dir,$(alldir),$(srcdir)$(dir)/ )
|
|
vpath %.h $(foreach dir,$(alldir),$(srcdir)$(dir)/ )
|
|
vpath %.rc $(foreach dir,$(alldir),$(srcdir)$(dir)/ )
|
|
|
|
vpath %.o $(foreach dir,$(alldir),$(objdir)$(dir)/ )
|
|
vpath %.d $(foreach dir,$(alldir),$(objdir)$(dir)/ )
|
|
|
|
#
|
|
#
|
|
# Rules
|
|
#
|
|
#
|
|
|
|
.PHONY: all init cleandep touch clean
|
|
|
|
ifeq ($(MAKELEVEL),1)
|
|
ifdef DEPEND
|
|
|
|
all: init $(drvdep) $(autdep) $(autobj) $(autdrv)
|
|
@$(MAKE) -f makefile.headless -s
|
|
|
|
else
|
|
|
|
all: init $(autobj) $(autdrv)
|
|
@$(MAKE) -f makefile.headless -s
|
|
|
|
endif
|
|
else
|
|
|
|
all: fbneo_headless.dylib
|
|
|
|
endif
|
|
|
|
#
|
|
#
|
|
# Rule for linking the executable
|
|
#
|
|
#
|
|
|
|
ifeq ($(MAKELEVEL),2)
|
|
|
|
$(objdir)drivers.o: $(autdrv)
|
|
@echo Linking drivers...
|
|
@$(LD) -r -nostdlib -o $@ $^
|
|
|
|
ifdef WINDOWS
|
|
|
|
$(NAME): $(allobj) $(objdir)drivers.o
|
|
@echo
|
|
@echo Linking executable... $(NAME)
|
|
@$(LD) -Wl,--image-base -Wl,0x10000000 -mconsole $(CFLAGS) $(LDFLAGS) -o $@ $^ $(lib)
|
|
|
|
else
|
|
|
|
fbneo_headless.dylib: $(allobj) $(objdir)drivers.o
|
|
@echo
|
|
@echo Linking dylib... $@
|
|
@$(LD) -dynamiclib -install_name @rpath/fbneo_headless.dylib $(CFLAGS) $(LDFLAGS) -o $@ $^ $(lib)
|
|
endif
|
|
|
|
|
|
ifdef DEBUG
|
|
|
|
# Don't compress when making a debug build
|
|
|
|
else
|
|
ifdef COMPRESS
|
|
@upx --best $@
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
ifeq ($(MAKELEVEL),1)
|
|
ifdef FORCE_UPDATE
|
|
$(build_details.h): FORCE
|
|
endif
|
|
endif
|
|
|
|
#
|
|
# Generate the gamelist
|
|
#
|
|
|
|
burn.o burn.d: $(driverlist.h)
|
|
|
|
$(driverlist.h): $(drvsrc) $(srcdir)dep/scripts/gamelist.pl
|
|
ifdef PERL
|
|
@$(srcdir)dep/scripts/gamelist.pl -o $@ -l gamelist.txt \
|
|
$(filter %.cpp,$(foreach file,$(drvsrc:.o=.cpp),$(foreach dir,$(alldir), \
|
|
$(firstword $(wildcard $(srcdir)$(dir)/$(file))))))
|
|
else
|
|
ifeq ($(MAKELEVEL),2)
|
|
@echo
|
|
@echo Warning: Perl is not available on this system.
|
|
@echo $@ cannot be updated or created!
|
|
@echo
|
|
endif
|
|
endif
|
|
|
|
#
|
|
# Verify if driverlist.h needs to be updated
|
|
#
|
|
|
|
#ifeq ($(MAKELEVEL),1)
|
|
#ifdef FORCE_UPDATE
|
|
#$(driverlist.h): FORCE
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#
|
|
# Compile 68000 cores
|
|
#
|
|
|
|
# A68K
|
|
|
|
ifdef BUILD_A68K
|
|
$(a68k.o): fba_make68k.c
|
|
@echo Compiling A68K MC68000 core...
|
|
@$(CC) -mconsole $(CFLAGS) $(LDFLAGS) -DWIN32 -Wno-unused -Wno-conversion -Wno-missing-prototypes \
|
|
-s $< -o $(subst $(srcdir),$(objdir),$(<D))/$(<F:.c=.exe)
|
|
@$(subst $(srcdir),$(objdir),$(<D))/$(<F:.c=.exe) $(@:.o=.asm) \
|
|
$(@D)/a68k_tab.asm 00 $(ppro)
|
|
@echo Assembling A68K MC68000 core...
|
|
@$(AS) $(ASFLAGS) $(@:.o=.asm) -o $@
|
|
endif
|
|
|
|
# Musashi
|
|
|
|
$(objdir)cpu/m68k/m68kcpu.o: $(srcdir)cpu/m68k/m68kcpu.c $(objdir)dep/generated/m68kops.h $(srcdir)cpu/m68k/m68k.h $(srcdir)cpu/m68k/m68kconf.h
|
|
@echo Compiling Musashi MC680x0 core \(m68kcpu.c\)...
|
|
@$(CC) $(CFLAGS) -c $(srcdir)cpu/m68k/m68kcpu.c -o $(objdir)cpu/m68k/m68kcpu.o
|
|
|
|
$(objdir)cpu/m68k/m68kops.o: $(objdir)cpu/m68k/m68kmake $(objdir)dep/generated/m68kops.h $(objdir)dep/generated/m68kops.c $(srcdir)cpu/m68k/m68k.h $(srcdir)cpu/m68k/m68kconf.h
|
|
@echo Compiling Musashi MC680x0 core \(m68kops.c\)...
|
|
@$(CC) $(CFLAGS) -c $(objdir)dep/generated/m68kops.c -o $(objdir)cpu/m68k/m68kops.o
|
|
|
|
$(objdir)dep/generated/m68kops.h $(objdir)dep/generated/m68kops.c: $(objdir)cpu/m68k/m68kmake $(srcdir)cpu/m68k/m68k_in.c
|
|
$(objdir)cpu/m68k/m68kmake $(objdir)dep/generated/ $(srcdir)cpu/m68k/m68k_in.c
|
|
|
|
$(objdir)cpu/m68k/m68kmake: $(srcdir)cpu/m68k/m68kmake.c
|
|
@echo Compiling Musashi MC680x0 core \(m68kmake.c\)...
|
|
@$(HOST_CC) $(HOST_CFLAGS) $(srcdir)cpu/m68k/m68kmake.c -o $(objdir)cpu/m68k/m68kmake -Dmain=main
|
|
|
|
|
|
#
|
|
# Extra rules for generated header file ctv.h, needed by ctv.cpp
|
|
#
|
|
|
|
ctv.d ctv.o: $(ctv.h)
|
|
|
|
$(ctv.h): ctv_make.cpp
|
|
@echo Generating $(srcdir)dep/generated/$(@F)...
|
|
@$(HOST_CC) $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $< \
|
|
-o $(subst $(srcdir),$(objdir),$(<D))/$(<F:.cpp=.exe) -Dmain=main
|
|
@$(subst $(srcdir),$(objdir),$(<D))/$(<F:.cpp=.exe) >$@
|
|
|
|
#
|
|
# Extra rules for generated header file toa_gp9001_func.h, needed by toa_gp9001.cpp
|
|
#
|
|
|
|
toa_bcu2.d toa_bcu2.o toa_gp9001.d toa_gp9001.o: $(toa_gp9001_func.h)
|
|
|
|
$(toa_gp9001_func.h): $(srcdir)dep/scripts/toa_gp9001_func.pl
|
|
@$(srcdir)dep/scripts/toa_gp9001_func.pl -o $(toa_gp9001_func.h)
|
|
|
|
#
|
|
# Extra rules for generated header file neo_sprite_func.h, needed by neo_sprite.cpp
|
|
#
|
|
|
|
neo_sprite.d neo_sprite.o: $(neo_sprite_func.h)
|
|
|
|
$(neo_sprite_func.h): $(srcdir)dep/scripts/neo_sprite_func.pl
|
|
@$(srcdir)dep/scripts/neo_sprite_func.pl -o $(neo_sprite_func.h)
|
|
|
|
#
|
|
# Extra rules for generated header file cave_tile_func.h, needed by cave_tile.cpp
|
|
#
|
|
|
|
cave_tile.d cave_tile.o: $(cave_tile_func.h)
|
|
|
|
$(cave_tile_func.h): $(srcdir)dep/scripts/cave_tile_func.pl
|
|
@$(srcdir)dep/scripts/cave_tile_func.pl -o $(cave_tile_func.h)
|
|
|
|
#
|
|
# Extra rules for generated header file cave_sprite_func.h, needed by cave_sprite.cpp
|
|
#
|
|
|
|
cave_sprite.d cave_sprite.o: $(cave_sprite_func.h)
|
|
|
|
$(cave_sprite_func.h): $(srcdir)dep/scripts/cave_sprite_func.pl
|
|
@$(srcdir)dep/scripts/cave_sprite_func.pl -o $(cave_sprite_func.h)
|
|
|
|
#
|
|
# Extra rules for generated header file psikyo_tile_func.h / psikyo_sprite_func.h, needed by psikyo_tile.cpp / psikyo_sprite.cpp
|
|
#
|
|
|
|
psikyo_tile.d psikyo_tile.o psikyosprite.d psikyo_sprite.o: $(psikyo_tile_func.h)
|
|
|
|
$(psikyo_tile_func.h): $(srcdir)dep/scripts/psikyo_tile_func.pl
|
|
$(srcdir)dep/scripts/psikyo_tile_func.pl -o $(psikyo_tile_func.h)
|
|
|
|
#
|
|
# Extra rules for generated header file pgm_sprite.h, needed by pgm_draw.cpp
|
|
#
|
|
|
|
pgm_draw.d pgm_draw.o: $(pgm_sprite.h)
|
|
|
|
$(pgm_sprite.h): pgm_sprite_create.cpp
|
|
@echo Generating $(srcdir)dep/generated/$(@F)...
|
|
@$(HOST_CC) $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $< \
|
|
-o $(subst $(srcdir),$(objdir),$(<D))/$(<F:.cpp=.exe) -Dmain=main
|
|
@$(subst $(srcdir),$(objdir),$(<D))/$(<F:.cpp=.exe) >$@
|
|
|
|
|
|
ifeq ($(MAKELEVEL),2)
|
|
ifdef DEPEND
|
|
|
|
include $(alldep)
|
|
|
|
endif
|
|
endif
|
|
|
|
|
|
#
|
|
# Generic rules for C/C++ files
|
|
#
|
|
# Note: require init to complete before assembling anything (see "| init" below)
|
|
# to avoid parallization issues on fresh builds.
|
|
#
|
|
|
|
ifeq ($(MAKELEVEL),1)
|
|
|
|
%.o: %.cpp
|
|
@echo Compiling $<...
|
|
@$(CC) $(CXXFLAGS) -c $< -o $(subst $(srcdir),$(objdir),$(<D))/$(@F)
|
|
|
|
%.o: %.c
|
|
@echo Compiling $<...
|
|
@$(CC) $(CFLAGS) -c $< -o $(subst $(srcdir),$(objdir),$(<D))/$(@F)
|
|
|
|
%.o: %.asm | init
|
|
@echo Assembling $<...
|
|
@$(AS) $(ASFLAGS) $< -o $(subst $(srcdir),$(objdir),$(<D))/$(@F)
|
|
|
|
else
|
|
|
|
%.o: %.c
|
|
@echo Compiling $<...
|
|
@$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
%.o: %.asm | init
|
|
@echo Assembling $<...
|
|
@$(AS) $(ASFLAGS) $< -o $@
|
|
|
|
%.o:
|
|
@echo Compiling $<...
|
|
@$(CC) $(CXXFLAGS) -c $< -o $@
|
|
|
|
endif
|
|
|
|
#
|
|
# Generate dependencies for C/C++ files
|
|
#
|
|
|
|
ifdef DEPEND
|
|
|
|
%.d: %.c
|
|
@echo Generating depend file for $<...
|
|
@$(CC) -MM -MT "$(subst $(srcdir),$(objdir),$(<D))/$(*F).o $(subst $(srcdir),$(objdir),$(<D))/$(@F)" -x c++ $(CXXFLAGS) $< >$(subst $(srcdir),$(objdir),$(<D))/$(@F)
|
|
|
|
%.d: %.cpp
|
|
@echo Generating depend file for $<...
|
|
@$(CC) -MM -MT "$(subst $(srcdir),$(objdir),$(<D))/$(*F).o $(subst $(srcdir),$(objdir),$(<D))/$(@F)" -x c++ $(CXXFLAGS) $< >$(subst $(srcdir),$(objdir),$(<D))/$(@F)
|
|
|
|
%.d: %.rc
|
|
@echo Generating depend file for $<...
|
|
@$(CC) -MM -MT "$(subst $(srcdir),$(objdir),$(<D))/$(*F).o $(subst $(srcdir),$(objdir),$(<D))/$(@F)" -x c++ $(CXXFLAGS) $< >$(subst $(srcdir),$(objdir),$(<D))/$(@F)
|
|
|
|
endif
|
|
|
|
#
|
|
# Phony targets
|
|
#
|
|
|
|
init:
|
|
|
|
ifdef DEBUG
|
|
@echo Making debug build...
|
|
else
|
|
@echo Making normal build...
|
|
endif
|
|
@echo
|
|
@mkdir -p $(foreach dir, $(alldir),$(objdir)$(dir))
|
|
@mkdir -p $(srcdir)dep/generated
|
|
|
|
cleandep:
|
|
@echo Removing depend files from $(objdir)...
|
|
-@for dir in $(alldir); do rm -f $(objdir)$$dir/*.d; done
|
|
|
|
touch:
|
|
@echo Marking all targets for $(NAME) as uptodate...
|
|
-@touch $(NAME).exe
|
|
-@touch -c -r $(NAME).exe $(srcdir)/dep/generated/*
|
|
-@for dir in $(alldir); do touch -c -r $(NAME).exe $(objdir)$$dir/*; done
|
|
|
|
clean:
|
|
@echo Removing build files...
|
|
-@rm -fr $(objdir) $(ctv.h) $(dep)generated gamelist.txt $(NAME)
|
|
|
|
ifdef PERL
|
|
@echo Removing all files generated with perl scripts...
|
|
-@rm -f -r $(app_gnuc.rc) $(driverlist)
|
|
endif
|
|
|
|
|
|
#
|
|
# Rule to force recompilation of any target that depends on it
|
|
#
|
|
|
|
FORCE:
|