#
#  Rules for building the Allegro library with MSVC. This file is included
#  by the primary makefile, and should not be used directly.
#
#  To path MSVC so it can be used from the commandline, run the
#  vcvars32.bat file which can be found in your MSVC bin directory.
#
#  To use MSVC7 specific options, the variable COMPILER_MSVC7 must be set. The
#  fix.bat script should do this automatically if run as `fix msvc7'
#
#  To use the Intel commandline compiler instead of the MSVC compiler,
#  COMPILER_ICL must be set. Again, `fix icl' should take care of this.
#
#  This platform uses GCC for building the assembler sources and calculating
#  source dependencies, so you'll need to have that installed in the form of
#  DJGPP, MinGW or Cygwin.
#
#  The "depend" target uses sed.
#
#  See makefile.all for a list of the available targets.



# -------- define some variables that the primary makefile will use --------

PLATFORM = MSVC
RUNNER = obj/msvc/runner.exe
GCC = gcc
EXE = .exe
OBJ = .obj
HTML = html

PLATFORM_DIR = obj/msvc

ifeq ($(TERM), cygwin)
   ALLEGRO_USE_CYGWIN=1
   UNIX_TOOLS = 1
endif

ifneq (,$(findstring /sh.exe,$(SHELL)))
   UNIX_TOOLS = 1
endif

ifdef STATICRUNTIME

# ======== USING A STATIC RUNTIME (/MT) ========

ifdef STATICLINK

# -------- link as a static library --------

OBJ_DIR = obj/msvc/$(VERSION)_s_crt
IMPLIB_BASENAME = $(VERSION)_s_crt.lib
IMPLIB_NAME = lib/msvc/$(IMPLIB_BASENAME)
LIB_NAME = $(IMPLIB_NAME)

else

# -------- link as a DLL --------

OBJ_DIR = obj/msvc/$(VERSION)_crt
DLL_BASENAME = $(VERSION)$(LIBRARY_VERSION)_crt.dll
DLL_NAME = lib/msvc/$(DLL_BASENAME)
IMPLIB_BASENAME = $(VERSION)_crt.lib
IMPLIB_NAME = lib/msvc/$(IMPLIB_BASENAME)
LIB_NAME = $(DLL_NAME) $(IMPLIB_NAME)

endif

else

# ======== USING DYNAMIC RUNTIME (/MD) ========

ifdef COMPILER_MSVC8
   EMBED_MANIFEST = 1
endif

ifdef STATICLINK

# -------- link as a static library --------

OBJ_DIR = obj/msvc/$(VERSION)_s
IMPLIB_BASENAME = $(VERSION)_s.lib
IMPLIB_NAME = lib/msvc/$(IMPLIB_BASENAME)
LIB_NAME = $(IMPLIB_NAME)

else

# -------- link as a DLL --------

OBJ_DIR = obj/msvc/$(VERSION)
DLL_BASENAME = $(VERSION)$(LIBRARY_VERSION).dll
DLL_NAME = lib/msvc/$(DLL_BASENAME)
IMPLIB_BASENAME = $(VERSION).lib
IMPLIB_NAME = lib/msvc/$(IMPLIB_BASENAME)
LIB_NAME = $(DLL_NAME) $(IMPLIB_NAME)

endif

endif

# -------- check that environment path variables are set --------

.PHONY: badwin badmsvc badspaces

ifdef ALLEGRO_USE_CYGWIN

WINDIR_S := $(shell cygpath -S)
WINDIR_U = $(subst \,/,$(WINDIR_S))
WINDIR_D = $(subst /,\,$(WINDIR_S))

else

ifeq ($(OS),Windows_NT)
   WINSYSDIR = $(SYSTEMROOT)
   ifeq ($(WINSYSDIR),)
      WINSYSDIR = $(SystemRoot)
   endif
   WINSUBDIR = system32
else
   WINSYSDIR = $(WINDIR)
   ifeq ($(WINSYSDIR),)
      WINSYSDIR = $(windir)
   endif
   WINSUBDIR = system
endif

ifneq ($(WINSYSDIR),)
   WINDIR_U = $(subst \,/,$(WINSYSDIR)/$(WINSUBDIR))
   WINDIR_D = $(subst /,\,$(WINSYSDIR)/$(WINSUBDIR))
else
badwin:
	@echo Your SYSTEMROOT or windir environment variable is not set!
endif

endif # ALLEGRO_USE_CYGWIN


ifndef MSVCDir
badmsvc:
	@echo Your MSVCDir environment variable is not set!
	@echo See the docs/build/msvc.txt file!
endif

ifdef ALLEGRO_USE_CYGWIN
   MSVCDIR_S := $(shell cygpath "$(MSVCDir)")
   MSVCDIR_U = $(subst \,/,$(MSVCDIR_S))
   MSVCDIR_D = $(subst /,\,$(MSVCDIR_S))
else
   MSVCDIR_U = $(subst \,/,$(MSVCDir))
   MSVCDIR_D = $(subst /,\,$(MSVCDir))
endif  # ALLEGRO_USE_CYGWIN


NULLSTRING :=
SPACE := $(NULLSTRING) # special magic to get an isolated space character

ifneq ($(findstring $(SPACE),$(MSVCDir)),)
badspaces:
	@echo There are spaces in your MSVCDir environment variable:
	@echo please change it to the 8.3 short filename version,
	@echo or move your compiler to a different directory.
endif



# -------- Work out the absolute pathnames for some MSVC tools to avoid confusion --------

ifdef COMPILER_ICL
   MSVC_CL = icl
else
   MSVC_CL = $(MSVCDIR_U)/bin/cl
endif
MSVC_LINK = $(MSVCDIR_U)/bin/link
MSVC_LIB = $(MSVCDIR_U)/bin/link -lib
MSVC_RC = rc



# -------- give a sensible default target for make without any args --------

.PHONY: _default

_default: default



# -------- decide what compiler options to use --------

ifdef WARNMODE
   WFLAGS = -W3 -WX
else
   WFLAGS = -W1
endif

ifdef STATICRUNTIME
   RUNTIME_FLAGS = -MT
else
   RUNTIME_FLAGS = -MD
endif

ifdef DEBUGMODE

# -------- debugging build --------

CFLAGS = -DDEBUGMODE=$(DEBUGMODE) $(WFLAGS) -Gd -Zi $(RUNTIME_FLAGS)d
SFLAGS = -DDEBUGMODE=$(DEBUGMODE) -Wall
LFLAGS = -debug -debugtype:cv

else
ifdef PROFILEMODE

# -------- profiling build --------

CFLAGS = $(WFLAGS) -Gd -Ox $(RUNTIME_FLAGS)
SFLAGS = -Wall
LFLAGS = -profile

else

# -------- optimised build --------

CFLAGS = $(WFLAGS) -Gd $(RUNTIME_FLAGS)
SFLAGS = -Wall
LFLAGS = -release
LIBPARMS = 

ifdef COMPILER_ICL
   CFLAGS += -Os -G7 -QaxPN
else
   ifdef TARGET_ARCH_EXCL
      CFLAGS += -O2 -G$(TARGET_ARCH_EXCL)
   else
      CFLAGS += -O2 
   endif
endif

ifdef COMPILER_MSVC7
   CFLAGS += -GL
   LFLAGS += -LTCG
   LIBPARMS += -LTCG
endif

ifdef COMPILER_MSVC8
   CFLAGS += -GL
   LFLAGS += -LTCG
   LIBPARMS += -LTCG
endif

endif
endif

# -------- on all MSVC 8 targets, remove deprecation warnings --------
ifdef COMPILER_MSVC8
   CFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
endif


# -------- list platform specific objects and programs --------

VPATH = src/win src/misc src/compat tests/win tools/win

ifdef ALLEGRO_USE_C

# ------ build a C-only version ------

VPATH += src/c
MY_OBJECTS = $(C_OBJECTS)
CFLAGS += -DALLEGRO_NO_ASM
SFLAGS += -DALLEGRO_NO_ASM

else

# ------ build the normal asm version ------

VPATH += src/i386
MY_OBJECTS = $(I386_OBJECTS)

endif # ALLEGRO_USE_C

OBJECT_LIST = $(COMMON_OBJECTS) $(MY_OBJECTS) $(basename $(notdir $(ALLEGRO_SRC_WIN_FILES)))

LIBRARIES = kernel32.lib user32.lib gdi32.lib comdlg32.lib ole32.lib \
		dinput.lib ddraw.lib dxguid.lib winmm.lib dsound.lib

PROGRAMS = dibgrab dibhello dibsound dxwindow scrsave wfixicon

dibgrab: tests/win/dibgrab.exe
dibhello: tests/win/dibhello.exe
dibsound: tests/win/dibsound.exe
dxwindow: tests/win/dxwindow.exe
scrsave: tests/win/scrsave.scr
wfixicon: tools/win/wfixicon.exe



# -------- rules for installing and removing the library files --------

INSTALLDIR = $(MSVCDIR_U)
LIBDIR = lib
INCDIR = include


ifdef UNIX_TOOLS

$(WINDIR_U)/$(DLL_BASENAME): $(DLL_NAME)
	cp lib/msvc/$(DLL_BASENAME) $(WINDIR_U)

$(MSVCDIR_U)/lib/$(IMPLIB_BASENAME): $(IMPLIB_NAME) $(MSVCDIR_U)/lib
	cp lib/msvc/$(IMPLIB_BASENAME) $(MSVCDIR_U)/lib

else

$(WINDIR_U)/$(DLL_BASENAME): $(DLL_NAME)
	copy lib\msvc\$(DLL_BASENAME) $(WINDIR_D)

$(MSVCDIR_U)/lib/$(IMPLIB_BASENAME): $(IMPLIB_NAME) $(MSVCDIR_U)/lib
	copy lib\msvc\$(IMPLIB_BASENAME) $(MSVCDIR_D)\lib

endif


HEADERS = $(MSVCDIR_U)/include/winalleg.h                 \
          $(MSVCDIR_U)/include/allegro/platform/aintwin.h \
          $(MSVCDIR_U)/include/allegro/platform/al386vc.h \
          $(MSVCDIR_U)/include/allegro/platform/almsvc.h  \
          $(MSVCDIR_U)/include/allegro/platform/alplatf.h \
          $(MSVCDIR_U)/include/allegro/platform/astdint.h \
          $(MSVCDIR_U)/include/allegro/platform/alwin.h

INSTALL_FILES = $(MSVCDIR_U)/lib/$(IMPLIB_BASENAME)

ifndef STATICLINK
   INSTALL_FILES += $(WINDIR_U)/$(DLL_BASENAME)
endif

INSTALL_FILES += $(HEADERS)

install: generic-install
	@echo The $(DESCRIPTION) $(PLATFORM) library has been installed.

UNINSTALL_FILES = $(MSVCDIR_U)/lib/alleg.lib              \
                  $(MSVCDIR_U)/lib/alld.lib               \
                  $(MSVCDIR_U)/lib/allp.lib               \
                  $(MSVCDIR_U)/lib/alleg_s.lib            \
                  $(MSVCDIR_U)/lib/alld_s.lib             \
                  $(MSVCDIR_U)/lib/allp_s.lib             \
                  $(WINDIR_U)/alleg$(LIBRARY_VERSION).dll \
                  $(WINDIR_U)/alld$(LIBRARY_VERSION).dll  \
                  $(WINDIR_U)/allp$(LIBRARY_VERSION).dll  \
                  $(HEADERS)

uninstall: generic-uninstall
	@echo All gone!



# -------- helper function for compressing the executables --------

.PHONY: compress

compress:
ifdef UPX_BIN
	$(UPX_BIN) demo/*.exe examples/*.exe setup/*.exe tests/*.exe tools/*.exe lib/msvc/all*.dll
else
	@echo No executable compressor specified! You must set the environment variable
	@echo UPX_BIN to point to upx.exe.
endif



# -------- test capabilities --------

TEST_CPP = @echo ...integrated

include makefile.tst



# -------- finally, we get to the fun part... --------

ifdef STATICLINK

# -------- link as a static library --------

define MAKE_LIB
   $(RUNNER) $(MSVC_LIB) @ -nologo $(LIBPARMS) -out:$(LIB_NAME) $(OBJECTS)
endef

COMPILE_FLAGS = -DALLEGRO_STATICLINK 

else

# -------- link as a DLL --------

ifdef EMBED_MANIFEST
ifdef ALLEGRO_USE_CYGWIN
   EMBEDMAN_BAT = misc/embedman.bat
else
   EMBEDMAN_BAT = misc\embedman.bat
endif
define MAKE_LIB
   $(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -dll -def:lib/msvc/allegro.def -out:$(DLL_NAME) -implib:$(IMPLIB_NAME) $(OBJECTS) $(LIBRARIES)
   $(EMBEDMAN_BAT) "$(subst /,\,$(DLL_NAME))" 2
endef
else
define MAKE_LIB
   $(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -dll -def:lib/msvc/allegro.def -out:$(DLL_NAME) -implib:$(IMPLIB_NAME) $(OBJECTS) $(LIBRARIES)
endef
endif

endif

COMPILE_FLAGS += $(subst src/,-DALLEGRO_SRC ,$(findstring src/, $<))$(CFLAGS)

$(OBJ_DIR)/%.obj: %.c $(RUNNER)
	$(RUNNER) $(MSVC_CL) @ -nologo $(COMPILE_FLAGS) -I. -I./include -Fo$@ -c $<

$(OBJ_DIR)/%.obj: %.cpp $(RUNNER)
	$(RUNNER) $(MSVC_CL) @ -nologo $(COMPILE_FLAGS) -I. -I./include -Fo$@ -c $<

$(OBJ_DIR)/%.obj: %.s
	$(GCC) $(SFLAGS) -I. -I./include -x assembler-with-cpp -o $@ -c $<

$(OBJ_DIR)/%.obj: %.rc
	$(MSVC_RC) -i"include" -fo$@ $<

obj/msvc/%.res: %.rc
	$(MSVC_RC) -fo$@ $<

tests/win/dibsound.exe: $(OBJ_DIR)/dibsound.obj obj/msvc/dibsound.res $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:tests/win/dibsound.exe $(OBJ_DIR)/dibsound.obj obj/msvc/dibsound.res $(IMPLIB_NAME) $(LIBRARIES)

tests/win/dxwindow.exe: $(OBJ_DIR)/dxwindow.obj obj/msvc/dxwindow.res $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:tests/win/dxwindow.exe $(OBJ_DIR)/dxwindow.obj obj/msvc/dxwindow.res $(IMPLIB_NAME) $(LIBRARIES)

tests/win/%.exe: $(OBJ_DIR)/%.obj $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:$@ $< $(IMPLIB_NAME) $(LIBRARIES)

tests/win/scrsave.scr: $(OBJ_DIR)/scrsave.obj obj/msvc/scrsave.res $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:tests/win/scrsave.scr $(OBJ_DIR)/scrsave.obj obj/msvc/scrsave.res $(IMPLIB_NAME) $(LIBRARIES)

tools/win/%.exe: $(OBJ_DIR)/%.obj $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:console -out:$@ $< $(IMPLIB_NAME) $(LIBRARIES)

obj/msvc/demo.res: demo/demo.dat tools/win/wfixicon.exe
ifdef STATICLINK
	tools/win/wfixicon.exe obj/msvc/demo.ico -ro -d demo/demo.dat SHIP3 GAME_PAL
else
   ifdef UNIX_TOOLS
	cp tools/win/wfixicon.exe lib/msvc/wfixicon.exe
      ifdef EMBED_MANIFEST
		cp tools/win/wfixicon.exe.manifest lib/msvc/wfixicon.exe.manifest
      endif
   else
	copy tools\win\wfixicon.exe lib\msvc\wfixicon.exe
      ifdef EMBED_MANIFEST
		copy tools\win\wfixicon.exe.manifest lib\msvc\wfixicon.exe.manifest
      endif
   endif
	lib/msvc/wfixicon.exe obj/msvc/demo.ico -ro -d demo/demo.dat SHIP3 GAME_PAL
   ifdef UNIX_TOOLS
	rm lib/msvc/wfixicon.exe
      ifdef COMPILER_MSVC8
		rm lib/msvc/wfixicon.exe.manifest
      endif
   else
	del lib\msvc\wfixicon.exe
      ifdef COMPILER_MSVC8
		del lib\msvc\wfixicon.exe.manifest
      endif
   endif
endif

demo/demo.exe: obj/msvc/demo.res $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:demo/demo.exe $(OBJECTS_DEMO) obj/msvc/demo.res $(IMPLIB_NAME) $(LIBRARIES)

*/%.exe: $(OBJ_DIR)/%.obj $(IMPLIB_NAME) $(RUNNER)
	$(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:$@ $< $(IMPLIB_NAME) $(LIBRARIES)

LINK_CONSOLE_DEPS = $(IMPLIB_NAME) $(RUNNER)

define LINK_CONSOLE
   $(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:console -out:$@ $< $(IMPLIB_NAME) $(LIBRARIES)
endef

obj/msvc/asmdef.inc: obj/msvc/asmdef.exe
	obj/msvc/asmdef.exe obj/msvc/asmdef.inc

obj/msvc/asmdef.exe: src/i386/asmdef.c include/*.h include/allegro/*.h obj/msvc/asmcapa.h $(RUNNER)
	$(RUNNER) $(MSVC_CL) @ -nologo $(WFLAGS) $(CFLAGS) -I. -I./include -Foobj/msvc/asmdef.obj -Feobj/msvc/asmdef.exe src/i386/asmdef.c

obj/msvc/runner.exe: src/misc/runner.c
	$(GCC) -O -Wall -Werror -o obj/msvc/runner.exe src/misc/runner.c

define LINK_WITHOUT_LIB
   $(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:console -out:$@ $^
endef

PLUGIN_LIB = lib/msvc/$(VERY_SHORT_VERSION)dat.lib
PLUGIN_DEPS = $(IMPLIB_NAME) $(PLUGIN_LIB) $(RUNNER)
PLUGINS_H = obj/msvc/plugins.h
PLUGIN_SCR = scv

ifdef UNIX_TOOLS
   define GENERATE_PLUGINS_H
      cat tools/plugins/*.inc > obj/msvc/plugins.h
   endef
else
   define GENERATE_PLUGINS_H
      copy /B tools\plugins\*.inc obj\msvc\plugins.h
   endef
endif

define MAKE_PLUGIN_LIB
   $(RUNNER) $(MSVC_LIB) @ -nologo $(LIBPARMS) -out:$(PLUGIN_LIB) $(PLUGIN_OBJS)
endef

define LINK_WITH_PLUGINS
   $(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:windows -out:$@ $< $(strip $(PLUGIN_LIB) $(addprefix @,$(PLUGIN_SCRIPTS)) $(IMPLIB_NAME) $(LIBRARIES))
endef

define LINK_CONSOLE_WITH_PLUGINS
   $(RUNNER) $(MSVC_LINK) @ -nologo $(LFLAGS) -subsystem:console -out:$@ $< $(strip $(PLUGIN_LIB) $(addprefix @,$(PLUGIN_SCRIPTS)) $(IMPLIB_NAME) $(LIBRARIES))
endef



# -------- generate automatic dependencies --------

DEPEND_PARAMS = -MM -MG -I. -I./include -DSCAN_DEPEND -DALLEGRO_MSVC

depend:
	$(GCC) $(DEPEND_PARAMS) src/*.c src/c/*.c src/i386/*.c src/misc/*.c src/win/*.c demo/*.c > _depend.tmp
	$(GCC) $(DEPEND_PARAMS) docs/src/makedoc/*.c examples/*.c setup/*.c tests/*.c tests/win/*.c >> _depend.tmp
	$(GCC) $(DEPEND_PARAMS) tools/*.c tools/win/*.c tools/plugins/*.c >> _depend.tmp
	$(GCC) $(DEPEND_PARAMS) -x c tests/*.cpp >> _depend.tmp
	$(GCC) $(DEPEND_PARAMS) -x assembler-with-cpp src/c/*.s src/i386/*.s src/misc/*.s src/win/*.s >> _depend.tmp
	sed -e "s/^[a-zA-Z0-9_\/]*\///" _depend.tmp > _depend2.tmp
ifdef UNIX_TOOLS
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alleg\/\1\.obj:/" _depend2.tmp > obj/msvc/alleg/makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alld\/\1\.obj:/" _depend2.tmp > obj/msvc/alld/makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/allp\/\1\.obj:/" _depend2.tmp > obj/msvc/allp/makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alleg_s\/\1\.obj:/" _depend2.tmp > obj/msvc/alleg_s/makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alld_s\/\1\.obj:/" _depend2.tmp > obj/msvc/alld_s/makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/allp_s\/\1\.obj:/" _depend2.tmp > obj/msvc/allp_s/makefile.dep
	rm _depend.tmp _depend2.tmp
else
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alleg\/\1\.obj:/" _depend2.tmp > obj\msvc\alleg\makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alld\/\1\.obj:/" _depend2.tmp > obj\msvc\alld\makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/allp\/\1\.obj:/" _depend2.tmp > obj\msvc\allp\makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alleg_s\/\1\.obj:/" _depend2.tmp > obj\msvc\alleg_s\makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/alld_s\/\1\.obj:/" _depend2.tmp > obj\msvc\alld_s\makefile.dep
	sed -e "s/^\([a-zA-Z0-9_]*\)\.o:/obj\/msvc\/allp_s\/\1\.obj:/" _depend2.tmp > obj\msvc\allp_s\makefile.dep
	del _depend.tmp
	del _depend2.tmp
endif
