##
# MegaZeux Makefile fragment
##

include contrib/gdm2s3m/src/Makefile.in
include contrib/icons/Makefile.in
include contrib/libmodplug/src/Makefile.in
include contrib/libxmp/Makefile.megazeux

.PHONY: mzx_clean core_target_clean

LINK_CC := ${CC}

core_src = src
core_obj = src/.build

audio_src = src/audio
audio_obj = src/audio/.build

network_src = src/network
network_obj = src/network/.build

core_flags   += -ffast-math -funsigned-char
core_flags   += -Wmissing-format-attribute -Wpointer-arith
core_flags   += -Wwrite-strings
core_cflags  += ${CFLAGS} -Wmissing-prototypes
core_cxxflags = ${CXXFLAGS} -DHAVE_INTTYPES_H

core_flags   += -I${PREFIX}/include
core_ldflags := -lm ${core_ldflags}

ifeq (${PLATFORM},mingw)
core_spec := -DCORE_LIBSPEC="__declspec(dllexport)"
endif

${core_obj}/main.o: ${core_src}/main.c
	$(if ${V},,@echo "  CC      " $<)
	${CC} -MD ${core_cflags} ${core_flags} -c $< -o $@

${core_obj}/run_stubs.o: ${core_src}/run_stubs.c
	$(if ${V},,@echo "  CC      " $<)
	${CC} -MD ${core_cflags} ${core_flags} -c $< -o $@

${core_obj}/updater.o: ${core_src}/updater.c
	$(if ${V},,@echo "  CC      " $<)
	${CC} -MD ${core_cflags} ${core_flags} -c $< -o $@

${audio_obj}/%.o: ${audio_src}/%.c
	$(if ${V},,@echo "  CC      " $<)
	${CC} -MD ${core_cflags} ${core_flags} ${core_spec} -c $< -o $@

${audio_obj}/%.o: ${audio_src}/%.cpp
	$(if ${V},,@echo "  CXX     " $<)
	${CC} -MD ${core_cxxflags} ${core_flags} ${core_spec} -c $< -o $@

${network_obj}/%.o: ${network_src}/%.c
	$(if ${V},,@echo "  CC      " $<)
	${CC} -MD ${core_cflags} ${core_flags} ${core_spec} -c $< -o $@

${core_obj}/%.o: ${core_src}/%.c
	$(if ${V},,@echo "  CC      " $<)
	${CC} -MD ${core_cflags} ${core_flags} ${core_spec} -c $< -o $@

${core_obj}/%.o: ${core_src}/%.cpp
	$(if ${V},,@echo "  CXX     " $<)
	${CXX} -MD ${core_cxxflags} ${core_flags} ${core_spec} -c $< -o $@

#
# Lists mandatory C language sources (mangled to object names) required
# to build the main binary. Please keep this sorted alphabetically.
#
core_cobjs := \
  ${core_obj}/block.o             \
  ${core_obj}/board.o             \
  ${core_obj}/caption.o           \
  ${core_obj}/configure.o         \
  ${core_obj}/core.o              \
  ${core_obj}/counter.o           \
  ${core_obj}/data.o              \
  ${core_obj}/error.o             \
  ${core_obj}/event.o             \
  ${core_obj}/expr.o              \
  ${core_obj}/fsafeopen.o         \
  ${core_obj}/game.o              \
  ${core_obj}/game_menu.o         \
  ${core_obj}/game_ops.o          \
  ${core_obj}/game_player.o       \
  ${core_obj}/game_update.o       \
  ${core_obj}/game_update_board.o \
  ${core_obj}/graphics.o          \
  ${core_obj}/idarray.o           \
  ${core_obj}/idput.o             \
  ${core_obj}/intake.o            \
  ${core_obj}/intake_num.o        \
  ${core_obj}/legacy_rasm.o       \
  ${core_obj}/legacy_board.o      \
  ${core_obj}/legacy_robot.o      \
  ${core_obj}/legacy_world.o      \
  ${core_obj}/mzm.o               \
  ${core_obj}/render.o            \
  ${core_obj}/robot.o             \
  ${core_obj}/run_robot.o         \
  ${core_obj}/scrdisp.o           \
  ${core_obj}/settings.o          \
  ${core_obj}/sprite.o            \
  ${core_obj}/str.o               \
  ${core_obj}/util.o              \
  ${core_obj}/window.o            \
  ${core_obj}/world.o             \
  ${core_obj}/zip.o

#
# Lists mandatory C++ language sources (mangled to object names) required
# to build the main binary. Currently there are only optional sources.
#
core_cxxobjs :=

#
# Hack to avoid silly warnings from devkitPro headers
#
ifeq ($(or ${BUILD_WII},${BUILD_NDS},${BUILD_PSP}),)
core_cflags += -Wstrict-prototypes
endif

#
# Hack to avoid silly warnings from Android headers
#
ifeq (${PLATFORM},android)
core_cflags += -Wno-strict-prototypes
endif

#
# These are really just hacks and should be moved elsewhere
#
ifeq (${BUILD_NDS},1)
core_cobjs += arch/nds/ram.o arch/nds/exception.o
core_cobjs += arch/nds/dlmalloc.o
core_cobjs += arch/nds/platform.o arch/nds/event.o
core_cobjs += arch/nds/render.o arch/nds/evq.o
ifneq (${BUILD_DEBYTECODE},1)
core_cobjs += arch/nds/extmem.o
endif
endif

ifeq (${BUILD_3DS},1)
core_cobjs += arch/3ds/shader_2d.shbin.o arch/3ds/shader_playfield.shbin.o
core_cobjs += arch/3ds/platform.o arch/3ds/render.o
core_cobjs += arch/3ds/event.o arch/3ds/audio.o
core_cobjs += arch/3ds/keyboard.o
endif

ifeq (${BUILD_SWITCH},1)
# Switch libraries require C++
LINK_CC := ${CXX}
endif

ifeq (${PLATFORM},android)
core_cxxobjs += arch/android/sfwrapper.o
LINK_CC := ${CXX}
endif

ifeq (${BUILD_WII},1)
# SDL and platform_sdl.c takes care of all of this when enabled.
ifeq (${BUILD_SDL},)
core_cobjs += arch/wii/event.o arch/wii/platform.o
core_cobjs += arch/wii/render_xfb.o
ifeq (${BUILD_RENDER_GX},1)
core_cobjs += arch/wii/render_gx.o
endif
ifeq (${BUILD_AUDIO},1)
core_cobjs += arch/wii/audio.o
endif
endif
endif

ifeq (${BUILD_PSP},1)
core_cobjs += arch/psp/platform.o
endif

#
# Other modular stuff
#

ifeq (${BUILD_HELPSYS},1)
core_cobjs += ${core_obj}/helpsys.o
endif

render_layer_software = 0

ifeq (${BUILD_RENDER_SOFT},1)
core_cobjs += ${core_obj}/render_soft.o
render_layer_software = 1
endif

# Accelerated SDL2 software renderer
ifeq (${BUILD_RENDER_SOFTSCALE},1)
core_cobjs += ${core_obj}/render_softscale.o
render_layer_software = 1
endif

# GL shared
ifneq ($(or ${BUILD_RENDER_GL_FIXED},${BUILD_RENDER_GL_PROGRAM}),)
core_cobjs += ${core_obj}/render_gl.o
endif

# Fixed function renderers (OGL=1, OGLES=1)
ifeq (${BUILD_RENDER_GL_FIXED},1)
core_cobjs += ${core_obj}/render_gl1.o ${core_obj}/render_gl2.o
render_layer_software = 1
endif

# Shader renderers (OGL>=2, OGLES=2)
ifeq (${BUILD_RENDER_GL_PROGRAM},1)
core_cobjs += ${core_obj}/render_glsl.o
endif

#
# Currently only usable with GL, but could theoretically be used
# with OpenVG in the future.
#
ifeq (${BUILD_EGL},1)
core_cobjs += ${core_obj}/render_egl.o
core_ldflags := -lEGL ${core_ldflags}
ifneq (${X11DIR},)
core_flags += ${X11_CFLAGS}
core_ldflags := ${X11_LDFLAGS} ${core_ldflags}
endif
endif

# Overlay renderers
ifeq (${BUILD_RENDER_YUV},1)
core_cobjs += ${core_obj}/render_yuv.o
render_layer_software = 1
endif

# GP2X Half-resolution renderer
ifeq (${BUILD_RENDER_GP2X},1)
core_cobjs += ${core_obj}/render_gp2x.o
endif

# Screenshots require the software layer renderer.
ifeq (${BUILD_ENABLE_SCREENSHOTS},1)
render_layer_software = 1
endif

# Software layer renderer
# This one tends to take forever for many builds. Prefix it to
# the list so hopefully it starts sooner during parallel builds.
ifeq (${render_layer_software},1)
core_cobjs := ${core_obj}/render_layer.o ${core_cobjs}
endif

ifeq (${BUILD_MODPLUG},1)
core_cflags += -I${gdm2s3m_src}
core_cxxflags += -I${gdm2s3m_src}
core_cobjs += ${gdm2s3m_objs}
core_flags += -I${libmodplug_src} -I${libmodplug_src}/libmodplug
core_cxxobjs += ${audio_obj}/audio_modplug.o ${libmodplug_objs}
LINK_CC := ${CXX}
endif

ifeq (${BUILD_MIKMOD},1)
core_flags += ${MIKMOD_CFLAGS}
core_ldflags := ${MIKMOD_LDFLAGS} ${core_ldflags}
core_cobjs += ${audio_obj}/audio_mikmod.o
endif

ifeq (${BUILD_XMP},1)
core_cflags += ${XMP_CFLAGS}
core_ldflags := ${XMP_LDFLAGS} ${core_ldflags}
core_cobjs += ${audio_obj}/audio_xmp.o
core_flags += ${libxmp_include}
core_cobjs += ${libxmp_objs}
endif

ifeq (${BUILD_OPENMPT},1)
core_flags += ${OPENMPT_CFLAGS}
core_ldflags := ${OPENMPT_LDFLAGS} ${core_ldflags}
core_cobjs += ${audio_obj}/audio_openmpt.o
endif

ifeq (${LIBPNG},1)
core_flags += $(LIBPNG_CFLAGS) -DNEED_PNG_WRITE_SCREEN
core_ldflags := $(LIBPNG_LDFLAGS) ${core_ldflags}
core_cobjs += ${core_obj}/pngops.o
endif

ifeq (${BUILD_KHASH},1)
core_flags += -Icontrib/khash/
endif

ifeq (${BUILD_AUDIO},1)
audio_cobjs := \
 ${audio_obj}/audio.o          \
 ${audio_obj}/audio_pcs.o      \
 ${audio_obj}/audio_wav.o      \
 ${audio_obj}/ext.o            \
 ${audio_obj}/sampled_stream.o \
 ${audio_obj}/sfx.o

ifneq (${VORBIS},)
audio_cobjs += \
 ${audio_obj}/audio_vorbis.o
endif

core_cobjs += ${audio_cobjs}
core_flags += ${VORBIS_CFLAGS}
core_ldflags := ${VORBIS_LDFLAGS} ${core_ldflags}
else
# The editor needs this for sfx_strs...
ifeq (${BUILD_EDITOR},1)
core_cobjs += ${audio_obj}/sfx.o
endif
endif

ifeq (${BUILD_SDL},1)

core_cobjs += ${core_obj}/event_sdl.o ${core_obj}/platform_sdl.o
core_cobjs += ${core_obj}/render_sdl.o

ifeq (${BUILD_AUDIO},1)
core_cobjs += ${audio_obj}/audio_sdl.o
endif

core_flags   += $(SDL_CFLAGS)
core_ldflags += $(SDL_LDFLAGS)

ifeq (${BUILD_MODULAR},1)
mzx_ldflags    += $(SDL_LDFLAGS)
mzxrun_ldflags += $(SDL_LDFLAGS)
endif

else

ifeq ($(or ${BUILD_WII},${BUILD_NDS},${BUILD_3DS}),)

core_cobjs += ${core_obj}/platform_dummy.o

#
# Normally SDL would provide us with pthread, but in the case
# we're not using SDL or any other platform mutex implementation,
# we must link pthread ourselves.
#
ifeq (${PTHREAD},1)
core_ldflags := ${PTHREAD_LDFLAGS} ${core_ldflags}
endif

endif

endif

core_cflags := ${ZLIB_CFLAGS} ${core_cflags}
core_ldflags := ${ZLIB_LDFLAGS} ${core_ldflags}

ifeq (${BUILD_NETWORK},1)
core_cobjs += ${network_obj}/dns.o ${network_obj}/host.o
core_cobjs += ${network_obj}/manifest.o ${network_obj}/network.o
core_cobjs += ${network_obj}/sha256.o ${network_obj}/socksyms.o

ifeq (${BUILD_UPDATER},1)
mzx_objs += ${core_obj}/updater.o
endif

ifeq (${PLATFORM},amiga)
core_ldflags := ${core_ldflags} -lnet
endif

endif

ifeq (${BUILD_DEBYTECODE},1)
core_cobjs += ${core_obj}/rasm.o
endif

core_objs := ${core_cobjs} ${core_cxxobjs}

-include ${core_objs:.o=.d}

${core_objs}: | $(filter-out $(wildcard ${core_obj}), ${core_obj})
${core_objs}: | $(filter-out $(wildcard ${audio_obj}), ${audio_obj})
${core_objs}: | $(filter-out $(wildcard ${network_obj}), ${network_obj})

ifeq (${BUILD_MODULAR},1)

core_target := ${DSOPRE}core${DSOPOST}

${core_target}: ${core_objs}
	$(if ${V},,@echo "  LINK    " $@)
	${LINK_CC} ${DSOLDFLAGS} -o $@ ${core_objs} ${LDFLAGS} \
	  ${DSOSONAME}$@ ${core_ldflags}

core_target_clean:
	$(if ${V},,@echo "  RM      " ${core_target} ${core_target}.debug)
	${RM} ${core_target} ${core_target}.debug

else

core_target := ${core_objs}

core_target_clean:

endif

ifeq (${BUILD_EDITOR},1)

include src/editor/Makefile.in

mzx_objs := ${mzx_objs} ${core_obj}/main.o

-include ${mzx_objs:.o=.d}

ifeq (${EMBED_ICONS},1)
mzx_objs += ${icons}
endif

ifeq (${BUILD_MODULAR},1)
${mzx}.debug: ${core_target}.debug ${editor_target}.debug
endif

${mzx}: ${core_target} ${editor_target} ${mzx_objs}
	$(if ${V},,@echo "  LINK    " ${mzx})
ifeq (${BUILD_MODULAR},1)
	${CC} ${mzx_objs} -o ${mzx} ${ARCH_EXE_LDFLAGS} ${LDFLAGS} \
	  ${DSORPATH} -L. -lcore -leditor \
	  ${mzx_ldflags}
else
	${LINK_CC} ${mzx_objs} ${core_target} ${editor_target} \
	  -o ${mzx} ${ARCH_EXE_LDFLAGS} ${LDFLAGS} \
	  ${core_ldflags} ${editor_ldflags}
endif

mzx_clean: editor_clean

else

.PHONY: ${mzx}.debug
${mzx}:
${mzx}.debug:

endif

ifeq (${BUILD_MZXRUN},1)

mzxrun_objs := ${core_obj}/main.o ${core_obj}/run_stubs.o

-include ${mzxrun_objs:.o=.d}

ifeq (${EMBED_ICONS},1)
mzxrun_objs += ${icons}
endif

ifeq (${BUILD_MODULAR},1)
${mzxrun}.debug: ${core_target}.debug
endif

${mzxrun}: ${core_target} ${mzxrun_objs}
	$(if ${V},,@echo "  LINK    " ${mzxrun})
ifeq (${BUILD_MODULAR},1)
	${CC} ${mzxrun_objs} -o ${mzxrun} ${ARCH_EXE_LDFLAGS} ${LDFLAGS} \
	  ${DSORPATH} -L. -lcore ${mzxrun_ldflags}
else
	${LINK_CC} ${mzxrun_objs} ${core_target} \
	  -o ${mzxrun} ${ARCH_EXE_LDFLAGS} ${LDFLAGS} ${core_ldflags}
endif

else

.PHONY: ${mzxrun}.debug
${mzxrun}:
${mzxrun}.debug:

endif

mzx_clean: core_target_clean gdm2s3m_clean icons_clean libmodplug_clean libxmp_clean
	$(if ${V},,@echo "  RM      " ${core_obj} ${audio_obj} ${network_obj})
	${RM} -r ${core_obj} ${audio_obj} ${network_obj}
	$(if ${V},,@echo "  RM      " ${mzxrun} ${mzxrun}.debug)
	${RM} ${mzxrun} ${mzxrun}.debug
	$(if ${V},,@echo "  RM      " ${mzx} ${mzx}.debug)
	${RM} ${mzx} ${mzx}.debug
