#####################################################################

MAME_VERSION = -DMAME_VERSION=58

# set this to mame, mess or the destination you want to build
TARGET = mame
ifeq ($(TARGET),)
TARGET = mame
endif

# select compiler
USE_GCC = 1
# USE_VC = 1

# build a version for debugging games
# DEBUG = 1

# uncomment next line to include the symbols for symify
# SYMBOLS = 1

# uncomment next line to generate a link map for exception handling in win32
# MAP = 1

# uncomment next line to use Assembler 68000 engine
X86_ASM_68000 = 1

# uncomment next line to use Assembler 68020 engine
# X86_ASM_68020 = 1

# uncomment next line to support 32bpp
SUPPORT_32BPP = -DSUPPORT_32BPP

# uncomment next line to support extra folder
EXTRA_FOLDER = -DEXTRA_FOLDER

# build MAME32JP
MAME32JP = -DMAME32JP

# language
JAPANESE = 1
# ENGLISH = 1

# build console version
# BUILD_CONSOLE = -DBUILD_CONSOLE

# use fast (register) calling convention (for VC).
# USE_FASTCALL = -DFASTCALL

# uncomment next line to generate help files
# HELP = 1

#####################################################################
# PLEASE DO NOT CHANGE THE FOLLOWING SETTINGS!

# if compiler is not selected, GCC is used as the default.
ifndef USE_VC
ifndef USE_GCC
USE_GCC = 1
endif
endif

# set this the operating system you're building for
OS = Win32

# extension for executables
EXE = .exe

# CPU core include paths
VPATH = src $(wildcard src/cpu/*)

ifdef USE_GCC
USE_FASTCALL =
USE_VC =
endif

# compiler, linker and assembler
ifdef IP4
INTEL = 1
endif

ifdef USE_GCC
  AR = @ar
  CC = @gcc
  LD = @gcc
  ifdef JAPANESE
    RC  = @brcc32
    RC2 = @windres
  else
    RC = @windres
  endif
else
  AR = @lib
  ifdef INTEL
    CC = @icl
  else
    CC = @cl
  endif
  LD = @link
  RC = @rc
endif

# assembler
ASM = @nasmw
ASMFLAGS = -f win32 $(SUPPORT_32BPP)


# utilities
RM = del
RMDIR = rd /S /Q
MD = -md


ifdef USE_GCC
WINDOWS_PROGRAM = -mwindows
CONSOLE_PROGRAM = -mconsole
else
WINDOWS_PROGRAM = -subsystem:windows
CONSOLE_PROGRAM = -subsystem:console
endif

ifdef BUILD_CONSOLE
PROGRAM_TYPE = $(CONSOLE_PROGRAM)
KAILLERA =
else
PROGRAM_TYPE = $(WINDOWS_PROGRAM)
endif

ifdef I686
P6OPT = ppro
else
P6OPT = notppro
endif

ifdef JAPANESE
LANGUAGE = -DJAPANESE
ENGLISH =
SUFFIX = jp
else
LANGUAGE = -DENGLISH
JAPANESE =
SUFFIX = e
endif

ifdef SYMBOLS
CPUTYPE = debug
COMPILETYPE = -DCOMPILETYPE=0
else
  ifdef USE_GCC
    ifdef K
      ARCH = -march=pentium
      ifdef BUILD_CONSOLE
        CPUTYPE = pentium
        COMPILETYPE = -DCOMPILETYPE=1
      else
        CPUTYPE = kaillera
        KAILLERA = -DKAILLERA
        COMPILETYPE = -DCOMPILETYPE=5
      endif
    else
      ifdef K6
        ARCH = -march=k6
        CPUTYPE = k6
        COMPILETYPE = -DCOMPILETYPE=4
      else
        ifdef I686
          ARCH = -march=pentiumpro
          CPUTYPE = ppro
          COMPILETYPE = -DCOMPILETYPE=2
        else
          ARCH = -march=pentium
          CPUTYPE = pentium
          COMPILETYPE = -DCOMPILETYPE=1
        endif
      endif
    endif
  else
    ifdef K
      ARCH = -march=pentium
      ifdef BUILD_CONSOLE
        CPUTYPE = vc_pentium
        COMPILETYPE = -DCOMPILETYPE=1
      else
        CPUTYPE = vc_kaillera
        KAILLERA = -DKAILLERA
        COMPILETYPE = -DCOMPILETYPE=5
      endif
    else
      ifdef I686
        ARCH = -G6
        ifdef INTEL
          ARCH += -QxiM -QaxK
        endif
        CPUTYPE = vc_ppro
        COMPILETYPE = -DCOMPILETYPE=12
      else
        ifdef IP4
          ARCH = -G7 -QaxW
          CPUTYPE = pentium4
          COMPILETYPE = -DCOMPILETYPE=3
        else
          ARCH = -G5
          ifdef INTEL
            ARCH += -QaxM
          endif
          CPUTYPE = vc_pentium
          COMPILETYPE = -DCOMPILETYPE=1
        endif
      endif
    endif
  endif
endif

NAME = $(TARGET)32$(SUFFIX)

# build the targets in different object dirs, since mess changes
# some structures and thus they can't be linked against each other.
# cleantiny isn't needed anymore, because the tiny build has its
# own object directory too.
OBJ = obj/$(CPUTYPE)

EMULATOR = exe/$(CPUTYPE)/$(NAME)$(EXE)

#####################################################################
# check enviroment

ifndef DX_INCPATH
nodxincpath:
	@echo Path for DirectX include headers (DX_INCPATH) not defined.
endif

ifndef DX_LIBPATH
nodxlibpath:
	@echo Path for DirectX Libraries (DX_LIBPATH) not defined.
endif

ifdef KAILLERA
  ifndef KAILLERA_INCPATH
nokailleraincpath:
	@echo Path for Kaillera Client include header (KAILLERA_INCPATH) not defined.
  endif

  ifndef MAME32JP
    ifndef KAILLERA_LIBPATH
nokailleralibpath:
	@echo Path for Kaillera Library (KAILLERA_LIBPATH) not defined.
    endif
  endif
endif

#####################################################################
# compiler

#--------------------------------------------------------------------
# Preprocessor Definitions
#--------------------------------------------------------------------

DEFS = \
	-D_WIN32_IE=0x0400 \
	-DWINVER=0x0400 \
	-D_WIN32_WINNT=0x0400 \
	-DDIRECTSOUND_VERSION=0x0300 \
	-DDIRECTDRAW_VERSION=0x0300 \
	-DDIRECTINPUT_VERSION=0x0500 \
	-DWIN32 \
	-D_WINDOWS \
	-DM_PI=3.1415926534 \
	-DPI=3.1415926534 \
	-DCLIB_DECL=__cdecl \
	-DDECL_SPEC=__cdecl \
	-DPNG_SAVE_SUPPORT \
	-DHAS_CPUS \
	-DHAS_SOUND \
	-DLSB_FIRST=1 \
	-DZLIB_DLL \
	$(MAME_VERSION) \
	$(USE_FASTCALL) \
	-DMAME_FIX \
	-DMAME32_FIX \
	$(MAME32JP) \
	$(LANGUAGE) \
	$(BUILD_CONSOLE) \
	$(SUPPORT_32BPP) \
	$(EXTRA_FOLDER) \
	$(KAILLERA)

ifdef USE_GCC
DEFS += \
	-DNONAMELESSUNION \
	-DHMONITOR_DECLARED \
	-D_LPCWAVEFORMATEX_DEFINED \
	-UWINNT \
	-D__int64='long long' \
	-DINLINE='static __inline__' \
	-Dasm=__asm__ \
	-DX86_ASM
else
DEFS += \
	-DINLINE='static __inline' \
	-Dinline=__inline \
	-D__inline__=__inline
endif


ifndef SYMBOLS
DEFS += -DNDEBUG
endif

#--------------------------------------------------------------------
# Include path
#--------------------------------------------------------------------

INCLUDES = \
	-I. \
	-Isrc \
	-Isrc/includes \
	-Isrc/Win32 \
	-Isrc/Win32/Mame32UI \
	-Isrc/cpu/m68000 \
	-Isrc/zlib \
	-I$(OBJ)/cpu/m68000 \
	-I$(DX_INCPATH) \

ifdef KAILLERA
INCLUDES += -I$(KAILLERA_INCPATH)
endif

#--------------------------------------------------------------------
# C Compiler flags
#--------------------------------------------------------------------

ifdef USE_GCC

CFLAGS = $(INCLUDES) -mno-cygwin

# multi threaded
CFLAGS +=

ifdef SYMBOLS
CFLAGS += -d
endif

ifdef SYMBOLS
CFLAGS += -O0 -Wall -Werror -Wno-unused -g
else
CFLAGS += $(ARCH) -O3 -s -static -malign-double \
	-fomit-frame-pointer -fstrict-aliasing -ffast-math \
	-Werror -Wall -Wno-sign-compare -Wunused \
	-Wpointer-arith -Wbad-function-cast -Wcast-align \
	-Waggregate-return -Wshadow -Wstrict-prototypes -Wundef
#	try with gcc 3.0 -Wpadded -Wunreachable-code -Wdisabled-optimization
#	-W had to remove because of the "missing initializer" warning
#	-Wlarger-than-262144 \
#	-Wcast-qual \
#	-Wwrite-strings \
#	-Wconversion \
#	-Wmissing-prototypes \
#	-Wmissing-declarations \
#	-Wredundant-decls

endif

CFLAGSPEDANTIC = $(CFLAGS) -pedantic

else

CFLAGS = -W3 -nologo $(INCLUDES)

# multi threaded
CFLAGS += -MT

ifdef USE_FASTCALL
CFLAGS += -Gr
endif

ifdef SYMBOLS
CFLAGS += -Zi -Od
else

CFLAGS += -Ox $(ARCH) -Ob2
endif

endif

#####################################################################
# Resources

RCDEFS = $(COMPILETYPE) $(KAILLERA) $(BUILD_CONSOLE) -DNDEBUG $(MAME_VERSION) -D_WIN32

ifdef USE_GCC
  ifdef JAPANESE
  RCFLAGS = -r -I./Win32 -I$(INCLUDE)
  else
  RCDEFS += -D_WIN32_IE=0x0400
  RCFLAGS = -O coff --include-dir src/Win32
  endif
else
  ifdef JAPANESE
  RCFLAGS = -l 0x411 -I./Win32
  else
  RCFLAGS = -l 0x409 -I./Win32
  endif
endif

#####################################################################
# Linker

ifdef USE_GCC
LIBS = \
	-lkernel32 \
	-luser32 \
	-lgdi32 \
	-lshell32 \
	-lcomctl32 \
	-lcomdlg32 \
	-ladvapi32 \
	-lwinmm \
	-ldxguid \
	-ldinput \
	-lhtmlhelp

ifdef KAILLERA
ifndef MAME32JP
LIBS += -lkailleraclient -lws2_32
endif
LIBS += -limm32
endif

LDFLAGS = -L$(DX_LIBPATH)

ifdef KAILLERA
LDFLAGS += -L$(KAILLERA_LIBPATH)
endif

ifndef SYMBOLS
#LDFLAGS = -s -Wl,--warn-common
LDFLAGS += -s
endif

ifdef MAP
MAPFLAGS = -Wl,-M >$(NAME).map
else
MAPFLAGS =
endif

else

LIBS = \
	kernel32.lib \
	user32.lib \
	gdi32.lib \
	shell32.lib \
	comctl32.lib \
	comdlg32.lib \
	advapi32.lib \
	winmm.lib \
	dxguid.lib \
	dinput.lib \
	htmlhelp.lib

LDFLAGS = -libpath:$(DX_LIBPATH)

LDFLAGS += -machine:x86 -nologo

ifdef SYMBOLS
LDFLAGS += -debug:full
else
LDFLAGS += -release -incremental:no
endif

ifdef MAP
LDFLAGS += -map
endif

endif

#####################################################################

OBJDIRS = \
	$(OBJ) \
	$(OBJ)/cpu \
	$(OBJ)/sound \
	$(OBJ)/drivers \
	$(OBJ)/machine \
	$(OBJ)/vidhrdw \
	$(OBJ)/sndhrdw \
	$(OBJ)/patch \
	$(OBJ)/zlib \
	$(OBJ)/Win32 \
	$(OBJ)/Win32/Mame32UI \
	$(OBJ)/Win32/hlp

#####################################################################

all: maketree $(EMULATOR) extra
#all: update maketree $(EMULATOR) extra

# include the various .mak files
include src/core.mak
include src/$(TARGET).mak
include src/rules.mak
include src/zlib/zlib.mak
include src/$(OS)/$(OS).mak

ifdef USE_GCC
OSOBJS += $(OBJ)/Win32/portio.o
endif

ifdef DEBUG
DBGDEFS = -DMAME_DEBUG
else
DBGDEFS =
DBGOBJS =
endif

#extra:	$(TOOLS) $(HELPFILES)
extra:	$(HELPFILES)

# combine the various definitions to one
CDEFS = $(DEFS) $(COREDEFS) $(CPUDEFS) $(SOUNDDEFS) $(ASMDEFS) $(DBGDEFS)

$(EMULATOR): $(OBJS) $(COREOBJS) $(OSOBJS) $(DRVLIBS) $(RES) 
# always recompile the version string
ifdef USE_GCC
	$(CC) $(CDEFS) $(CFLAGS) -o $(OBJ)/version.o -c src/version.c
else
	$(CC) $(CDEFS) $(CFLAGS) -Fo$(OBJ)/version.o -c src/version.c
endif
	@echo Linking $@...
ifdef USE_GCC
	$(LD) $(LDFLAGS) $(PROGRAM_TYPE) $(OBJS) $(COREOBJS) $(OSOBJS) $(LIBS) $(DRVLIBS) $(RES) -o $@
else
	$(LD) $(LDFLAGS) $(PROGRAM_TYPE) -out:$(EMULATOR) $(LIBS) $(COREOBJS) $(OBJS) $(OSOBJS) $(DRVLIBS) $(RES)
endif
ifndef SYMBOLS
#	upx $(EMULATOR)
endif

romcmp$(EXE): $(OBJ)/romcmp.o $(OBJ)/unzip.o 
	@echo Linking $@...
ifdef USE_GCC
	$(LD) $(LDFLAGS) $(CONSOLE_PROGRAM) $^ $(LIBS) -o $@
else
	$(LD) $(LDFLAGS) $(CONSOLE_PROGRAM) $(LIBS) $(OBJ)/Win32/dirent.o -out:$@ $^
endif

#--------------------------------------------------------------------
# make list

ifdef PERL
$(OBJ)/cpuintrf.o: src/cpuintrf.c rules.mak
	$(PERL) src/makelist.pl
	@echo Compiling $<...
	$(CC) $(CDEFS) $(CFLAGSPEDANTIC) -c $< -o $@
endif

#--------------------------------------------------------------------
# ASM source

$(OBJ)/%.o: src/%.asm
	@echo Assembling $<...
	$(ASM) -o $@ $(ASMFLAGS) $(ASMDEFS) $<

#--------------------------------------------------------------------
# C source

$(OBJ)/%.o: src/%.c
	@echo Compiling $<...
ifdef USE_GCC
ifdef JAPANESE
	@sjisfix $< check
endif
	$(CC) $(CDEFS) $(CFLAGSPEDANTIC) -c $< -o $@
ifdef JAPANESE
	@sjisfix $< delete
endif
else
ifdef IP4
ifdef JAPANESE
	@sjisfix $< check
endif
endif
	$(CC) $(CDEFS) $(CFLAGS) -Fo$@ -c $<
ifdef IP4
ifdef JAPANESE
	@sjisfix $< delete
endif
endif
endif

#--------------------------------------------------------------------
# resource

ifdef USE_GCC
$(OBJ)/Win32/%.o: src/Win32/%.rc
	@echo Compiling resources $<...
ifdef JAPANESE
	$(RC) $(RCDEFS) $(RCFLAGS) -Fosrc/Win32/mame32$(SUFFIX).res $<
	$(RC2) -i src/Win32/mame32$(SUFFIX).res -o $@
else
	$(RC) $(RCDEFS) $(RCFLAGS) -o $@ -i $<
endif
else
$(OBJ)/Win32/%.o: src/Win32/%.rc
	@echo Compiling resources $<...
	$(RC) $(RCDEFS) $(RCFLAGS) -Fo$@ $<
endif

#--------------------------------------------------------------------
# 68000 C core

# compile generated C files for the 68000 emulator
$(M68000_GENERATED_OBJS): $(OBJ)/cpu/m68000/m68kmake$(EXE)
	@echo Compiling $(subst .o,.c,$@)...
ifdef USE_GCC
	$(CC) $(CDEFS) $(CFLAGSPEDANTIC) -c $*.c -o $@
else
	$(CC) $(CDEFS) $(CFLAGS) -Fo$@ -c $*.c
endif

# additional rule, because m68kcpu.c includes the generated m68kops.h :-/
$(OBJ)/cpu/m68000/m68kcpu.o: $(OBJ)/cpu/m68000/m68kmake$(EXE)

# generate C source files for the 68000 emulator
$(OBJ)/cpu/m68000/m68kmake$(EXE): src/cpu/m68000/m68kmake.c
	@echo M68K make $<...
ifdef USE_GCC
	$(CC) $(CDEFS) $(CFLAGSPEDANTIC) -DDOS -o $(OBJ)/cpu/m68000/m68kmake$(EXE) $<
else
	$(CC) $(CDEFS) $(CFLAGS) -Fe$@ -Fo$(OBJ)/cpu/m68000 $<
endif
	@echo Generating M68K source files...
	$(OBJ)/cpu/m68000/m68kmake$(EXE) $(OBJ)/cpu/m68000 src/cpu/m68000/m68k_in.c

#--------------------------------------------------------------------
# 68000 ASM core

# generate asm source files for the 68000 emulator
$(OBJ)/cpu/m68000/68000.asm:  src/cpu/m68000/make68k.c
	@echo Compiling $<...
ifdef USE_GCC
	$(CC) $(CDEFS) $(CFLAGSPEDANTIC) -O0 -DDOS -o $(OBJ)/cpu/m68000/make68k$(EXE) $<
else
	$(CC) $(CDEFS) $(CFLAGS) -Fe$(OBJ)/cpu/m68000/make68k$(EXE) -Fo$(OBJ)/cpu/m68000 $<
endif
	@echo Generating $@...
	$(OBJ)/cpu/m68000/make68k$(EXE) $@ $(OBJ)/cpu/m68000/68000tab.asm 00 $(P6OPT)

# generated asm files for the 68000 emulator
$(OBJ)/cpu/m68000/68000.o:  $(OBJ)/cpu/m68000/68000.asm
	@echo Assembling $<...
	$(ASM) -o $@ $(ASMFLAGS) $(subst -D,-d,$(ASMDEFS)) $<


#--------------------------------------------------------------------
# 68020 ASM core

# generate asm source files for the 68020 emulator
$(OBJ)/cpu/m68000/68020.asm:  src/cpu/m68000/make68k.c
	@echo Compiling $<...
ifdef USE_GCC
	$(CC) $(CDEFS) $(CFLAGSPEDANTIC) -O0 -DDOS -o $(OBJ)/cpu/m68000/make68k(EXE) $<
else
	$(CC) $(CDEFS) $(CFLAGS) -Fe$(OBJ)/cpu/m68000/make68k(EXE) -Fo$(OBJ)/cpu/m68000 $<
endif
	@echo Generating $@...
	$(OBJ)/cpu/m68000/make68k(EXE) $@ $(OBJ)/cpu/m68000/68020tab.asm 20 $(P6OPT)

# generated asm files for the 68020 emulator
$(OBJ)/cpu/m68000/68020.o:  $(OBJ)/cpu/m68000/68020.asm
	@echo Assembling $<...
	$(ASM) -o $@ $(ASMFLAGS) $(subst -D,-d,$(ASMDEFS)) $<

#--------------------------------------------------------------------
# archiving object files

$(OBJ)/%.a:
	@echo Archiving $@...
	@if exist $@ $(RM) $(subst /,\,$@)
ifdef USE_GCC
	$(AR) cr $@ $^
else
	$(AR) -nologo -out:$@ $^
endif


#####################################################################
# make rules

makedir:
	@echo make makedir is no longer necessary, just type make

$(sort $(OBJDIRS)):
	$(MD) $(subst /,\,$@)

maketree2:
	@echo Making object tree...

maketree: maketree2 $(sort $(OBJDIRS))

clean:
	@echo Deleting object tree $(OBJ)...
#	@if exist $(OBJ) $(RMDIR) $(subst /,\,$(OBJ))
#	@echo Deleting $(EMULATOR)...
#	@if exist $(EMULATOR) $(RM) $(EMULATOR)
	$(RM) -r $(OBJ)
	@echo Deleting $(EMULATOR)...
	$(RM) $(EMULATOR)

clean68k:
	@echo Deleting 68k files...
	$(RM) -r $(OBJ)/cpuintrf.o
	$(RM) -r $(OBJ)/drivers/cps2.o
	$(RM) -r $(OBJ)/cpu/m68000

update:
	@echo Deleting old object files...
#	@if exist $(OBJ)\vidhrdw\neogeo.o $(RM) $(OBJ)\vidhrdw\neogeo.o
