Index: dists/msvc9/scummvm-tfmx.sln
===================================================================
--- dists/msvc9/scummvm-tfmx.sln	(Revision 0)
+++ dists/msvc9/scummvm-tfmx.sln	(Revision 0)
@@ -0,0 +1,20 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scummvm", "scummvm-tfmx.vcproj", "{8434CB15-D08F-427D-9E6D-581AE5B28440}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8434CB15-D08F-427D-9E6D-581AE5B28440}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8434CB15-D08F-427D-9E6D-581AE5B28440}.Debug|Win32.Build.0 = Debug|Win32
+		{8434CB15-D08F-427D-9E6D-581AE5B28440}.Release|Win32.ActiveCfg = Release|Win32
+		{8434CB15-D08F-427D-9E6D-581AE5B28440}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: dists/msvc9/scummvm-tfmx.vcproj
===================================================================
--- dists/msvc9/scummvm-tfmx.vcproj	(Revision 0)
+++ dists/msvc9/scummvm-tfmx.vcproj	(Revision 0)
@@ -0,0 +1,1784 @@
+<?xml version="1.0" encoding="windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="scummvm"
+	ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}"
+	RootNamespace="scummvm"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(SolutionName)-$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)$(SolutionName)-$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				InlineFunctionExpansion="0"
+				AdditionalIncludeDirectories="../../;../../engines"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				ExceptionHandling="1"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="true"
+				DisableLanguageExtensions="false"
+				ForceConformanceInForLoopScope="true"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				SuppressStartupBanner="false"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+				DisableSpecificWarnings="4512"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib sdl.lib"
+				OutputFile="$(OutDir)\$(ProjectName)-tfmx.exe"
+				LinkIncremental="2"
+				IgnoreDefaultLibraryNames="libc.lib;libcmt.lib;msvcrt.lib"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/scummvm.pdb"
+				SubSystem="1"
+				EntryPointSymbol="WinMainCRTStartup"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(SolutionName)-$(ConfigurationName)"
+			IntermediateDirectory="$(SolutionDir)$(SolutionName)-$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702 /wd4996"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="../../;../../engines"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				MinimalRebuild="false"
+				ExceptionHandling="1"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="false"
+				DisableLanguageExtensions="false"
+				ForceConformanceInForLoopScope="true"
+				RuntimeTypeInfo="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib sdl.lib"
+				OutputFile="$(OutDir)\$(ProjectName)-tfmx.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="libc.lib"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				EntryPointSymbol="WinMainCRTStartup"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="base"
+			>
+			<File
+				RelativePath="..\..\base\commandLine.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\commandLine.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\internal_version.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\main.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\main.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\plugins.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\plugins.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\version.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\base\version.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="common"
+			>
+			<File
+				RelativePath="..\..\common\algorithm.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\archive.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\archive.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\array.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\backends\base-backend.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\config-file.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\config-file.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\config-manager.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\config-manager.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\debug.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\debug.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\endian.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\error.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\events.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\file.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\file.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\frac.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\fs.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\fs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\func.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\hash-str.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\hashmap.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\hashmap.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\iff_container.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\keyboard.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\list.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\list_intern.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\md5.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\md5.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\memorypool.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\memorypool.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\mutex.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\mutex.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\noncopyable.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\pack-end.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\pack-start.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\ptr.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\queue.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\rect.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\savefile.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\scummsys.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\serializer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\singleton.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\stack.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\str.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\str.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\stream.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\stream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\system.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\system.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\timer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\unarj.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\unarj.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\unzip.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\unzip.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\util.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\xmlparser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\xmlparser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\zlib.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\common\zlib.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="sound"
+			>
+			<File
+				RelativePath="..\..\sound\adpcm.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\adpcm.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\aiff.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\aiff.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\audiocd.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\audiocd.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\audiostream.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\audiostream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\flac.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\flac.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\fmopl.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\fmopl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\iff.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)\$(InputName)1.obj"
+						XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ObjectFile="$(IntDir)\$(InputName)1.obj"
+						XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\sound\iff.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mididrv.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mididrv.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\midiparser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\midiparser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\midiparser_smf.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\midiparser_xmidi.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mixer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mixer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mixer_intern.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mp3.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mp3.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mpu401.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\mpu401.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\musicplugin.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\musicplugin.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\null.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\rate.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\rate.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\shorten.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\shorten.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\timestamp.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\timestamp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\vag.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\vag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\voc.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\voc.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\vorbis.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\vorbis.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\wave.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\sound\wave.h"
+				>
+			</File>
+			<Filter
+				Name="softhsynth"
+				>
+				<File
+					RelativePath="..\..\sound\softsynth\adlib.cpp"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)/$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)/$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\emumidi.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\fluidsynth.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\mt32.cpp"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)/$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)/$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\pcspk.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\pcspk.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\ym2612.cpp"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)/$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)/$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\..\sound\softsynth\ym2612.h"
+					>
+				</File>
+				<Filter
+					Name="mt32"
+					>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\freeverb.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\freeverb.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\i386.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\i386.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\mt32_file.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\mt32_file.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\mt32emu.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\part.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\part.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\partial.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\partial.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\partialManager.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\partialManager.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\structures.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\synth.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\synth.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\tables.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\mt32\tables.h"
+						>
+					</File>
+				</Filter>
+				<Filter
+					Name="opl"
+					>
+					<File
+						RelativePath="..\..\sound\softsynth\opl\dosbox.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\opl\dosbox.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\opl\mame.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\opl\mame.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\opl\opl_impl.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\sound\softsynth\opl\opl_inc.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="mods"
+				>
+				<File
+					RelativePath="..\..\sound\mods\infogrames.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\infogrames.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\module.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\module.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\paula.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\paula.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\protracker.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\protracker.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\rjp1.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\rjp1.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\soundfx.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\soundfx.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\tfmx.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\sound\mods\tfmx.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="txt"
+			>
+			<File
+				RelativePath="..\..\COPYING"
+				>
+			</File>
+			<File
+				RelativePath="..\..\NEWS"
+				>
+			</File>
+			<File
+				RelativePath="..\..\README"
+				>
+			</File>
+			<File
+				RelativePath="..\..\TODO"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="rsc"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+			<File
+				RelativePath="..\..\icons\scummvm.ico"
+				>
+			</File>
+			<File
+				RelativePath="..\..\dists\scummvm.rc"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="backends"
+			>
+			<File
+				RelativePath="..\..\backends\base-backend.cpp"
+				>
+			</File>
+			<Filter
+				Name="sdl"
+				>
+				<File
+					RelativePath="..\..\backends\platform\sdl\events.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\platform\sdl\graphics.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\platform\sdl\hardwarekeys.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\platform\sdl\main.cpp"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)\$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							ObjectFile="$(IntDir)\$(InputName)1.obj"
+							XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\..\backends\platform\sdl\sdl.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\platform\sdl\sdl.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="fs"
+				>
+				<File
+					RelativePath="..\..\backends\fs\abstract-fs.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\fs\abstract-fs.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\fs\fs-factory.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\fs\stdiostream.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\fs\stdiostream.h"
+					>
+				</File>
+				<Filter
+					Name="windows"
+					>
+					<File
+						RelativePath="..\..\backends\fs\windows\windows-fs-factory.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\backends\fs\windows\windows-fs-factory.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="midi"
+				>
+				<File
+					RelativePath="..\..\backends\midi\windows.cpp"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="timer"
+				>
+				<File
+					RelativePath="..\..\backends\timer\default\default-timer.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\timer\default\default-timer.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="saves"
+				>
+				<File
+					RelativePath="..\..\backends\saves\default\default-saves.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\saves\default\default-saves.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\saves\savefile.cpp"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="events"
+				>
+				<Filter
+					Name="default"
+					>
+					<File
+						RelativePath="..\..\backends\events\default\default-events.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\backends\events\default\default-events.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+			<Filter
+				Name="keymapper"
+				>
+				<File
+					RelativePath="..\..\backends\keymapper\action.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\action.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\hardware-key.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\keymap.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\keymap.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\keymapper.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\keymapper.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\remap-dialog.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\remap-dialog.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\keymapper\types.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="vkeybd"
+				>
+				<File
+					RelativePath="..\..\backends\vkeybd\image-map.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\image-map.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\keycode-descriptions.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\polygon.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\polygon.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\virtual-keyboard.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\backends\vkeybd\virtual-keyboard.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="gui"
+			>
+			<File
+				RelativePath="..\..\gui\about.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\about.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\browser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\browser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\chooser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\chooser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\console.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\console.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\credits.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\debugger.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\debugger.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\dialog.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\dialog.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\editable.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\editable.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\EditTextWidget.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\EditTextWidget.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\GuiManager.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\GuiManager.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\Key.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\Key.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\launcher.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\launcher.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ListWidget.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ListWidget.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\massadd.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\massadd.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\message.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\message.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\object.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\object.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\options.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\options.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\PopUpWidget.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\PopUpWidget.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\saveload.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\saveload.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ScrollBarWidget.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ScrollBarWidget.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\TabWidget.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\TabWidget.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\themebrowser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\themebrowser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeEngine.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeEngine.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeEval.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeLayout.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeLayout.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeParser.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeParser.h"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\gui\widget.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\widget.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="graphics"
+			>
+			<File
+				RelativePath="..\..\graphics\colormasks.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\cursorman.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\cursorman.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\dither.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\dither.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\font.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\font.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\fontman.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\fontman.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\iff.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\iff.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\imagedec.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\imagedec.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\primitives.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\primitives.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\scaler.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\scaler.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\surface.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\surface.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\thumbnail.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\thumbnail.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\VectorRenderer.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\VectorRenderer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\VectorRendererSpec.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\VectorRendererSpec.h"
+				>
+			</File>
+			<Filter
+				Name="scaler"
+				>
+				<File
+					RelativePath="..\..\graphics\scaler\2xsai.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\aspect.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\hq2x.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\hq2x.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\hq2x_i386.asm"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						>
+						<Tool
+							Name="VCCustomBuildTool"
+							CommandLine="nasm.exe -f win32 -g -o &quot;$(OutDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+							Outputs="$(OutDir)\$(InputName).obj"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						>
+						<Tool
+							Name="VCCustomBuildTool"
+							CommandLine="nasm.exe  -f win32 -o &quot;$(OutDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+							Outputs="$(OutDir)\$(InputName).obj"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\hq3x.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\hq3x.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\hq3x_i386.asm"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						>
+						<Tool
+							Name="VCCustomBuildTool"
+							CommandLine="nasm.exe -f win32 -g -o &quot;$(OutDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+							Outputs="$(OutDir)\$(InputName).obj"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						>
+						<Tool
+							Name="VCCustomBuildTool"
+							CommandLine="nasm.exe -f win32 -o &quot;$(OutDir)\$(InputName).obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+							Outputs="$(OutDir)\$(InputName).obj"
+						/>
+					</FileConfiguration>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\intern.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\scale2x.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\scale2x.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\scale3x.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\scale3x.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\scalebit.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\scalebit.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\scaler\thumbnail_intern.cpp"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="fonts"
+				>
+				<File
+					RelativePath="..\..\graphics\fonts\consolefont.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\fonts\newfont.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\fonts\newfont_big.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\fonts\scummfont.cpp"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="video"
+				>
+				<File
+					RelativePath="..\..\graphics\video\dxa_decoder.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\dxa_decoder.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\flic_decoder.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\flic_decoder.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\mpeg_player.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\mpeg_player.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\smk_decoder.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\smk_decoder.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\video_player.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\graphics\video\video_player.h"
+					>
+				</File>
+				<Filter
+					Name="coktelvideo"
+					>
+					<File
+						RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\graphics\video\coktelvideo\coktelvideo.h"
+						>
+					</File>
+					<File
+						RelativePath="..\..\graphics\video\coktelvideo\indeo3.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\graphics\video\coktelvideo\indeo3.h"
+						>
+					</File>
+				</Filter>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="engines"
+			>
+			<File
+				RelativePath="..\..\engines\advancedDetector.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\advancedDetector.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\dialogs.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\dialogs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\engine.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\engine.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\game.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\game.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\engines\metaengine.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="TFMX"
+			>
+			<File
+				RelativePath="..\..\TFMX\README.txt"
+				>
+			</File>
+			<File
+				RelativePath="..\..\tfmx\tfmxdebug.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\tfmx\tfmxdebug.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\TFMX\tfmxplayer.cpp"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: sound/module.mk
===================================================================
--- sound/module.mk	(Revision 41318)
+++ sound/module.mk	(Arbeitskopie)
@@ -29,6 +29,7 @@
 	mods/paula.o \
 	mods/rjp1.o \
 	mods/soundfx.o \
+	mods/tfmx.o \
 	softsynth/adlib.o \
 	softsynth/opl/dosbox.o \
 	softsynth/opl/mame.o \
Index: sound/mods/tfmx.cpp
===================================================================
--- sound/mods/tfmx.cpp	(Revision 0)
+++ sound/mods/tfmx.cpp	(Revision 0)
@@ -0,0 +1,789 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/stream.h"
+#include "common/util.h"
+#include "common/debug.h"
+
+#include "sound/mods/tfmx.h"
+
+#include "tfmx/tfmxdebug.h"
+
+namespace Audio {
+
+const uint16 Tfmx::noteIntervalls[64] = {
+	1710, 1614, 1524, 1438, 1357, 1281, 1209, 1141, 1077, 1017,  960,  908,
+	 856,  810,  764,  720,  680,  642,  606,  571,  539,  509,  480,  454,
+	 428,  404,  381,  360,  340,  320,  303,  286,  270,  254,  240,  227,
+	 214,  202,  191,  180,  170,  160,  151,  143,  135,  127,  120,  113,
+	 214,  202,  191,  180,  170,  160,  151,  143,  135,  127,  120,  113,
+	 214,  202,  191,  180 };
+
+
+
+Tfmx::Tfmx(int rate, bool stereo)
+: Paula(stereo, rate), _resource()  {
+	_playerCtx.enabled = false;
+	_playerCtx.song = -1;
+
+	for (int i = 0; i < kNumVoices; ++i) 
+		_channelCtx[i].paulaChannel = i;
+}
+
+Tfmx::~Tfmx() {
+}
+
+void Tfmx::interrupt() {
+	assert(!_end);
+	for (int i = 0; i < kNumVoices; ++i) {
+		ChannelContext &channel = _channelCtx[i];
+
+		if (channel.countDmaInterrupts) {
+			// wait for DMA Interupts to happen
+			int doneDma = getChannelDmaCount(channel.paulaChannel);
+			if (doneDma > channel.dmaCount) {
+				debug("channel %d, DMA done", i);
+				channel.countDmaInterrupts = false;
+				channel.macroRun = true;
+			}
+		}
+
+		// TODO: Sometimes a macro will be executed here
+
+		// apply timebased effects on Parameters 
+		effects(channel);
+
+		// see if we have to run the macro-program
+		if (channel.macroRun) {
+			if (channel.macroWait == 0) {
+				// run macro
+				while (macroStep(channel))
+					;
+			} else
+				--channel.macroWait;
+		}
+		// FIXME handle Volume
+		Paula::setChannelVolume(channel.paulaChannel, 0x40);
+	}
+
+	// Patterns are only processed each _playerCtx.timerCount + 1 tick
+	if (_playerCtx.song >= 0 && !_playerCtx.patternCount--) {
+		_playerCtx.patternCount = _playerCtx.patternSkip;
+		advancePatterns();
+	}
+}
+
+void Tfmx::effects(ChannelContext &channel) {
+	if (channel.sfxLockTime >= 0)
+		--channel.sfxLockTime;
+	else
+		channel.sfxLocked = false;
+
+	// TODO: macroNote pending?
+	if (0) {
+		channel.sfxLocked = false;
+		// TODO: macronote
+	}
+
+	// vibratio
+
+	// porta
+
+	// envelope
+}
+
+FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) {
+	const byte *const macroPtr = (byte *)(_resource.getMacroPtr(channel.macroOffset) + channel.macroStep);
+	++channel.macroStep;
+	//int channelNo = ((byte*)&channel-(byte*)_channelCtx)/sizeof(ChannelContext);
+
+	displayMacroStep(macroPtr);
+
+	int32 temp = 0;
+
+	switch (macroPtr[0]) {
+	case 0x00:	// Reset + DMA Off. Parameters: deferWait, addset, vol
+		channel.envReset = 0;
+		channel.vibReset = 0;
+		channel.portaRate = 0;
+		// FT
+	case 0x13:	// DMA Off. Parameters:  deferWait, addset, vol
+		// TODO: implement PArameters
+		Paula::disableChannel(channel.paulaChannel);
+		channel.deferWait = macroPtr[1] >= 1;
+		if	(channel.deferWait) {
+			// if set, then we expect a DMA On in the same tick.
+			Paula::setChannelPeriod(channel.paulaChannel, 4);
+			Paula::setChannelSampleLen(channel.paulaChannel, 1);
+			// in this state we then need to allow some commands that normally
+			// would halt the macroprogamm to continue instead.
+			// those commands are: Wait, WaitDMA, AddPrevNote, AddNote, SetNote, <unknown Cmd>
+			// DMA On is affected aswell
+			// TODO remember time disabled?.
+		} else {
+			//TODO ?
+		}
+		return true;
+
+	case 0x01:	// DMA On
+		channel.countDmaInterrupts = false;
+		if (channel.deferWait) {
+			// TODO
+			// there is actually a small delay in the player, but I think that
+			// only allows to clear DMA-State on real Hardware
+		}
+		Paula::enableChannel(channel.paulaChannel);
+		channel.deferWait = false;
+		return true;
+
+	case 0x02:	// SetBeginn. Parameters: SampleOffset(L)
+		channel.sampleStart = READ_BE_UINT32(macroPtr) & 0xFFFFFF;
+		Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+		return true;
+
+	case 0x03:	// SetLength. Parameters: SampleLength(W)
+		channel.sampleLen = READ_BE_UINT16(&macroPtr[2]);
+		Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen);
+		return true;
+
+	case 0x04:	// Wait. Parameters: Ticks to wait(W).
+		// TODO: some unkown Parameter? (macroPtr[1] & 1)
+		channel.macroWait = READ_BE_UINT16(&macroPtr[2]);
+		return false;
+
+	case 0x10:	// Loop Key Up. Parameters: Loopcount, MacroStep(W)
+		if (!channel.keyUp)
+			return true;
+		// FT
+	case 0x05:	// Loop. Parameters: Loopcount, MacroStep(W)
+		// debug("Step %d, Loopcount: %02X", channel.macroStep, channel.macroLoopCount);
+		if (channel.macroLoopCount != 0) {
+			if (channel.macroLoopCount == 0xFF)
+				channel.macroLoopCount = macroPtr[1];
+			channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+		}
+		--channel.macroLoopCount;
+		return true;
+
+	case 0x06:	// Jump. Parameters: MacroIndex, MacroStep(W)
+		channel.macroOffset = _macroOffset[macroPtr[1] % kMaxMacroOffsets];
+		channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+		channel.macroLoopCount = 0xFF;
+		return true;
+
+	case 0x07:	// Stop Macro
+		channel.macroRun = false;
+		return false;
+
+	case 0x1F:	// AddPrevNote. Parameters: Note, Finetune(W)
+	case 0x08:	// AddNote. Parameters: Note, Finetune(W)
+		temp = (macroPtr[0] == 0x08) ? channel.note : channel.prevNote;
+		// Fallthrough to SetNote
+	case 0x09: {	// SetNote. Parameters: Note, Finetune(W)
+		const uint16 noteInt = noteIntervalls[(temp + macroPtr[1]) & 0x3F];
+		const uint16 finetune = READ_BE_UINT16(&macroPtr[2]) + channel.fineTune + 0x0100;
+		channel.portaDestPeriod = (uint16)((noteInt * finetune) >> 8);
+		if (!channel.portaRate) {
+			channel.period = channel.portaDestPeriod;
+			Paula::setChannelPeriod(channel.paulaChannel, channel.portaDestPeriod);
+		}
+		return channel.deferWait;
+	}
+
+	case 0x0A:	// Clear Effects
+		channel.envReset = 0;
+		channel.vibReset = 0;
+		channel.portaRate = 0;
+		return true;
+
+	case 0x0B:	// Portamento. Parameters: count, speed
+		macroPtr[1];
+		macroPtr[3];
+		return true;
+
+	case 0x0C:	// Vibrato. Parameters: Speed, intensity
+		macroPtr[1];
+		macroPtr[3];
+		return true;
+
+	case 0x0D:	// Add Volume. Parameters: unknown, volume
+		macroPtr[2];
+		macroPtr[3];
+		return true;
+
+	case 0x0E:	// Set Volume. Parameters: unknown, volume
+		macroPtr[2];
+		macroPtr[3];
+		return true;
+
+	case 0x0F:	// Envelope. Parameters: speed, count, endvol
+		macroPtr[1];
+		macroPtr[2];
+		macroPtr[3];
+		return true;
+
+	case 0x11:	// AddBegin. Parameters: times, Offset(W)
+		// TODO: implement Parameter
+		macroPtr[1];
+//		debug("prev: %06X, after: %06X", channel.sampleStart, channel.sampleStart + (int16)READ_BE_UINT16(&macroPtr[2]));
+		channel.sampleStart += (int16)READ_BE_UINT16(&macroPtr[2]);
+		Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+		return true;
+
+	case 0x12:	// AddLen. Parameters: added Length(W)
+		channel.sampleLen += READ_BE_UINT16(&macroPtr[2]);
+		Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen);
+		return true;
+
+	case 0x14:	// Wait key up. Parameters: wait cycles(W)
+		if (!channel.keyUp || channel.macroLoopCount == 0) {
+			channel.macroLoopCount = 0xFF;
+			return true;
+		} else if (channel.macroLoopCount == 0xFF)
+			channel.macroLoopCount = macroPtr[3];
+		--channel.macroLoopCount;
+		return false;
+
+	case 0x15:	// Subroutine. Parameters: MacroIndex, Macrostep(W)
+		channel.macroReturnOffset = channel.macroOffset;
+		channel.macroReturnStep = channel.macroStep;
+
+		channel.macroOffset = _macroOffset[macroPtr[1] % kMaxMacroOffsets];
+		channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+		// TODO: MI does some weird stuff there. Figure out which varioables need to be set
+		return true;
+
+	case 0x16:	// Return from Sub.
+		channel.macroOffset = channel.macroReturnOffset;
+		channel.macroStep = channel.macroReturnStep;
+		return true;
+
+	case 0x17:	// set Period. Parameters: Period(W)
+		channel.portaDestPeriod = READ_BE_UINT16(&macroPtr[2]);
+		if (!channel.portaRate) {
+			channel.period = channel.portaDestPeriod;
+			Paula::setChannelPeriod( channel.paulaChannel, channel.portaDestPeriod);
+		}
+		return true;
+
+	case 0x18:	// Sampleloop. Parameters: Offset from Samplestart(W)
+		// TODO: MI loads 24 bit, but thats useless?
+		temp = READ_BE_UINT16(&macroPtr[2]);
+		assert(!(temp & 1));
+		channel.sampleStart += temp & 0xFFFE;
+		channel.sampleLen -= (temp / 2);
+		Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+		Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen);
+		return true;
+
+	case 0x19:	// set one-shot Sample
+		channel.sampleStart = 0;
+		channel.sampleLen = 1;
+		Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(0));
+		Paula::setChannelSampleLen(channel.paulaChannel, 1);
+		return true;
+
+	case 0x1A:	// Wait on DMA. Parameters: Cycles-1(W) to wait
+		channel.dmaCount = READ_BE_UINT16(&macroPtr[2]);
+		channel.countDmaInterrupts = true;
+		channel.macroRun = false;
+		Paula::setChannelDmaCount(channel.paulaChannel);
+		return channel.deferWait;
+
+	case 0x1B:	// Random play. Parameters: macro/speed/mode
+		macroPtr[1];
+		macroPtr[2];
+		macroPtr[3];
+		return true;
+
+	case 0x1C:	// Splitkey. Parameters: key/macrostep(W)
+		macroPtr[1];
+		READ_BE_UINT16(&macroPtr[2]);
+		return true;
+
+	case 0x1D:	// Splitvolume. Parameters: volume/macrostep
+		macroPtr[1];
+		READ_BE_UINT16(&macroPtr[2]);
+		return true;
+
+	case 0x1E:	// Addvol+note. Parameters: note/CONST./volume
+		return true;
+
+	case 0x20:	// Signal. Parameters: signalnumber/value
+		return true;
+
+	case 0x21:	// Play macro. Parameters: macro/chan/detune
+		return true;
+#if defined(TFMX_NOT_IMPLEMENTED)
+	// used by Gem`X according to the docs
+	case 0x22:	// SID setbeg. Parameters: sample-startadress
+		return true;
+	case 0x23:	// SID setlen. Parameters: buflen/sourcelen 
+		return true;
+	case 0x24:	// SID op3 ofs. Parameters: offset
+		return true;
+	case 0x25:	// SID op3 frq. Parameters: speed/amplitude
+		return true;
+	case 0x26:	// SID op2 ofs. Parameters: offset
+		return true;
+	case 0x27:	// SID op2 frq. Parameters: speed/amplitude
+		return true;
+	case 0x28:	// ID op1. Parameters: speed/amplitude/TC
+		return true;
+	case 0x29:	// SID stop. Parameters: flag (1=clear all)
+		return true;
+	// 30-34 used by Carribean Disaster
+#endif
+	default:
+		return channel.deferWait;
+	}
+}
+
+void Tfmx::advancePatterns() {
+doTrackstep:
+	if (_playerCtx.pendingTrackstep) {
+		while (trackStep())
+			;
+		_playerCtx.pendingTrackstep = false;
+	}
+
+	for (int i = 0; i < kNumChannels; ++i) {
+		assert(!_playerCtx.pendingTrackstep);
+
+		const uint8 pattCmd = _patternCtx[i].command;
+		if (pattCmd < 0x90) {	// execute Patternstep
+			// FIXME: 0x90 is very likely a bug, 0x80 would make more sense
+			assert(pattCmd < 0x80);
+
+			if (_patternCtx[i].wait == 0) {
+				// issue all Steps for this tick
+				while (patternStep(_patternCtx[i]))
+					;
+			} else 
+				--_patternCtx[i].wait;
+
+		} else if (pattCmd == 0xFE) {	// Stop voice in pattern.expose
+			_patternCtx[i].command = 0xFF;
+			clearChannel(_channelCtx[_patternCtx[i].expose % kNumVoices]);
+		} // else this pattern-Channel is stopped
+
+		if (_playerCtx.pendingTrackstep) {
+			// we load the next Trackstep Command and then process all Channels again
+			// TODO Optionally disable looping
+			if (_trackCtx.startInd == _trackCtx.stopInd)
+				_trackCtx.posInd = _trackCtx.startInd;
+			else
+				++_trackCtx.posInd;
+			goto doTrackstep;
+		}
+	}
+}
+
+FORCEINLINE bool Tfmx::patternStep(PatternContext &pattern) {
+	const byte *const patternPtr = (byte *)(_resource.getPatternPtr(pattern.offset) + pattern.step);
+	++pattern.step;
+
+	debug("Pattern %04X +%d", pattern.offset, pattern.step-1);
+	displayPatternstep(patternPtr);
+
+	const byte pattCmd = patternPtr[0];
+
+	if (pattCmd < 0xF0) { // Playnote
+		const byte flags = pattCmd >> 6; // 0-1 means note, 2 means wait, 3 means portamento
+		byte noteCmd = pattCmd + pattern.expose;
+		byte param3  = patternPtr[3];
+		if (flags == 2) {
+			// Store wait-value in context and delete it the (note)command
+			pattern.wait = param3;
+			param3 = 0;
+		}
+		if (flags != 3)
+			noteCmd &= 0x3F;
+		noteCommand(noteCmd, patternPtr[1], patternPtr[2], param3);
+		return (flags != 2);
+
+	} else {	// Patterncommand
+		switch (pattCmd & 0xF) {
+		case 0: 	// End Pattern + Next Trackstep
+			pattern.command = 0xFF;
+			_playerCtx.pendingTrackstep = true;
+			return false;
+
+		case 1: 	// Loop Pattern. Parameters: Loopcount, PatternStep(W)
+			if (pattern.loopCount != 0) {
+				if (pattern.loopCount == 0xFF)
+					pattern.loopCount = patternPtr[1];
+				pattern.step = READ_BE_UINT16(&patternPtr[2]);
+			}
+			--pattern.loopCount;
+			return true;
+
+		case 2: 	// Jump. Parameters: PatternIndex, PatternStep(W)
+			pattern.offset = _patternOffset[patternPtr[1]];
+			pattern.step = READ_BE_UINT16(&patternPtr[2]);
+			return true;
+
+		case 3: 	// Wait. Paramters: ticks to wait
+			pattern.wait = patternPtr[1];
+			// TODO check for 0?
+			return false;
+
+		case 14: 	// Stop custompattern
+			// TODO ?
+			// FT
+		case 4: 	// Stop this pattern
+			pattern.command = 0xFF;
+			// TODO: try figuring out if this was the last Channel?
+			return false;
+
+		case 5: 	// Kup^-Set key up
+		case 6: 	// Vibrato
+		case 7: 	// Envelope
+		case 12: 	// Lock
+			noteCommand(pattCmd, patternPtr[1], patternPtr[2], patternPtr[3]);
+			return true;
+
+		case 8: 	// Subroutine
+			return true;
+		case 9: 	// Return from Subroutine
+			return true;
+		case 10:	// fade master volume
+			return true;
+
+		case 11: {	// play pattern. Parameters: patternCmd, channel, expose
+			PatternContext &target = _patternCtx[patternPtr[2] % kNumChannels];
+
+			target.command = patternPtr[1];
+			target.offset = _patternOffset[patternPtr[1] % kMaxPatternOffsets];
+			target.expose = patternPtr[3];
+			target.step = 0;
+			target.wait = 0;
+			target.loopCount = 0xFF;
+			}
+			return true;
+		case 13: 	// Cue
+			return true;
+		case 15: 	// NOP
+			return true;
+		}
+	}
+
+	return true;
+}
+
+bool Tfmx::trackStep() {
+	const uint16 *const trackData = _resource.getTrackPtr(_trackCtx.posInd);
+
+	debug( "TStep %04X", _trackCtx.posInd);
+	displayTrackstep(trackData);
+
+	if (trackData[0] != FROM_BE_16(0xEFFE)) {
+		// 8 commands for Patterns
+		for (int i = 0; i < 8; ++i) {
+			const uint patCmd = READ_BE_UINT16(&trackData[i]);
+
+			// First byte is pattern number
+			const uint patNum = (patCmd >> 8);
+			
+			// if highest bit is set then keep previous pattern
+			if (patNum < 0x80) {
+				_patternCtx[i].command = (uint8)patNum;
+				_patternCtx[i].step = 0;
+				_patternCtx[i].wait = 0;
+				_patternCtx[i].loopCount = 0xFF;
+				_patternCtx[i].offset = _patternOffset[patNum];
+			}
+
+			// second byte expose is always set
+			_patternCtx[i].expose = patCmd & 0xFF;
+		}
+		return false;
+
+	} else {
+		// 16 byte Trackstep Command
+		int temp;
+		switch (READ_BE_UINT16(&trackData[1])) {
+		case 0:	// Stop Player. No Parameters
+			_playerCtx.enabled = 0;
+			stopPaula();
+			return false;
+
+		case 1:	// Branch/Loop section of tracksteps. Parameters: branch target, loopcount
+			// this depends on the current loopCounter
+			temp = _trackCtx.loopCount;
+			if (temp > 0) {
+				// if trackloop is positive, we decrease one loop and continue at start of loop
+				--_trackCtx.loopCount;
+				_trackCtx.posInd = READ_BE_UINT16(&trackData[2]);
+			} else if (temp == 0) {
+				// if trackloop is 0, we reached last iteration and continue with next trackstep
+				_trackCtx.loopCount = (uint16)-1;
+			} else /*if (_context.TrackLoop < 0)*/ {
+				// if TrackLoop is negative then we reached the loop instruction the first time
+				// and we setup the Loop
+				_trackCtx.posInd    = READ_BE_UINT16(&trackData[2]);
+				_trackCtx.loopCount = READ_BE_UINT16(&trackData[3]);
+			}
+			break;
+
+		case 2:	// Set Tempo. Parameters: tempo, divisor
+			_playerCtx.patternCount = _playerCtx.patternSkip = READ_BE_UINT16(&trackData[2]); // tempo
+			temp = READ_BE_UINT16(&trackData[3]); // divisor
+
+			if (!(temp & 0x8000) && (temp & 0x1FF))
+				setInterruptFreqUnscaled(temp & 0x1FF);
+			break;
+
+		case 3:	// Unknown, stops player aswell
+		case 4:	// Fade
+		default:
+			debug("Unknown Command: %02X", READ_BE_UINT16(&trackData[1]));
+			// MI-Player handles this by stopping the player, we just continue
+		}
+		++_trackCtx.posInd;
+		return true;
+	}
+}
+
+void Tfmx::noteCommand(const uint8 note, const uint8 param1, const uint8 param2, const uint8 param3) {
+	ChannelContext &channel = _channelCtx[param2 % kNumVoices];
+
+	if (note == 0xFC) { // Lock
+		channel.sfxLocked = (param1 != 0);
+		channel.sfxLockTime = param3; // only 1 byte read! 
+		return;
+	}
+	if (channel.sfxLocked)
+		return;
+
+	if (note < 0xC0) {	// Play Note
+		channel.prevNote = channel.note;
+		channel.note = note;
+		channel.macroOffset = _macroOffset[param1 % kMaxMacroOffsets];
+		channel.relVol = (param2 >> 4) & 0xF;
+		channel.fineTune = (int16)param3;
+
+		initMacroProgramm(channel);
+		channel.keyUp = true;
+		
+	} else if (note < 0xF0) {	// do that porta stuff
+		channel.portaReset = param1;
+		channel.portaTime = 1;
+		if (!channel.portaRate)
+			channel.portaPeriod = channel.portaDestPeriod;
+		channel.portaRate = param3;
+
+		channel.note = note & 0x3F;
+		channel.portaDestPeriod = noteIntervalls[channel.note];
+	} else switch (note & 0xF) {	// Command
+		case 5:	// Key Up Release
+			channel.keyUp = false;
+			break;
+		case 6:	// Vibratio
+			channel.vibReset = param1 & 0xFE;
+			channel.vibTime = param1 / 2;
+			channel.vibFlag = 1;
+			channel.vibOffset = 0;
+			break;
+		case 7:	// Envelope
+			channel.envRate = param1;
+			channel.envReset = channel.envTime = (param2 >> 4) + 1;
+			channel.envEndVolume = param3;
+			break;
+	}
+}
+
+bool Tfmx::load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData) {
+	bool res;
+
+	assert(0 == _resource._mdatData);
+	assert(0 == _resource._sampleData);
+
+	// TODO: Sanity checks if we have a valid TFMX-Module
+	// TODO: check for Stream-Errors (other than using asserts)
+
+	// 0x0000: 10 Bytes Header "TFMX-SONG "
+	// 0x000A: int16 ?
+	// 0x000C: int32 ?
+	musicData.read(_resource.header, 10);
+	_resource.headerFlags = musicData.readUint16BE();
+	_resource.headerUnknown = musicData.readUint32BE();
+
+	// This might affect timing
+	// bool isPalModule = (_resource.headerFlags & 2) != 0;
+
+	// 0x0010: 6*40 Textfield
+	musicData.read(_resource.textField, 6 * 40);
+
+	/* 0x0100: Songstart x 32*/
+	for (int i = 0; i < kNumSubsongs; ++i)
+		_subsong[i].songstart = musicData.readUint16BE();
+
+	/* 0x0140: Songend x 32*/
+	for (int i = 0; i < kNumSubsongs; ++i)
+		_subsong[i].songend = musicData.readUint16BE();
+
+	/* 0x0180: Tempo x 32*/
+	for (int i = 0; i < kNumSubsongs; ++i)
+		_subsong[i].tempo  = musicData.readUint16BE();
+
+	/* 0x01c0: unused ? */
+	musicData.skip(16);
+
+	/* 0x01d0: trackstep, pattern data p, macro data p */
+	uint32 offTrackstep = musicData.readUint32BE();
+	uint32 offPatternP = musicData.readUint32BE();
+	uint32 offMacroP = musicData.readUint32BE();
+
+	// This is how MI`s TFMX-Player tests for unpacked Modules.
+	if (offTrackstep == 0) {
+		offTrackstep	= 0x600 + 0x200;
+		offPatternP		= 0x200 + 0x200;
+		offMacroP		= 0x400 + 0x200;
+	}
+
+	_resource._trackstepOffset = offTrackstep;
+
+	// Read in pattern starting offsets
+	musicData.seek(offPatternP);
+	for (int i = 0; i < kMaxPatternOffsets; ++i)
+		_patternOffset[i] = musicData.readUint32BE();
+
+	res = musicData.err();
+	assert(!res);
+
+	// Read in macro starting offsets
+	musicData.seek(offMacroP);
+	for (int i = 0; i < kMaxMacroOffsets; ++i)
+		_macroOffset[i] = musicData.readUint32BE();
+
+	res = musicData.err();
+	assert(!res);
+
+	// Read in whole mdat-file
+	int32 size = musicData.size();
+	assert(size != -1);
+	// TODO: special routine if size = -1?
+
+	_resource._mdatData = new byte[size];
+	assert(_resource._mdatData);
+	_resource._mdatLen = size;
+	musicData.seek(0);
+	musicData.read(_resource._mdatData, size);
+	
+	res = musicData.err();
+	assert(!res);
+	musicData.readByte();
+	res = musicData.eos();
+	assert(res);
+
+
+	// TODO: It would be possible to analyze the pointers and be able to
+	// seperate the file in trackstep, patterns and macro blocks
+	// Modules could do weird stuff like having those blocks mixed though.
+	// TODO: Analyze pointers if they are correct offsets,
+	// so that accesses can be unchecked later
+
+	// Read in whole sample-file
+	size = sampleData.size();
+	assert(size >= 4);
+	assert(size != -1);
+	// TODO: special routine if size = -1?
+
+	_resource._sampleData = new byte[size];
+	assert(_resource._sampleData);
+	_resource._sampleLen = size;
+	sampleData.seek(0);
+	sampleData.read(_resource._sampleData, size);
+	for (int i = 0; i < 4; ++i)
+		_resource._sampleData[i] = 0;
+	
+	res = sampleData.err();
+	assert(!res);
+	sampleData.readByte();
+	res = sampleData.eos();
+	assert(res);
+
+	return true;
+}
+
+
+void Tfmx::doMacro(int macro, int note) {
+	assert(0 <= macro && macro < kMaxMacroOffsets);
+	assert(0 <= note && note < 0xC0);
+
+	_playerCtx.song = -1;
+	_playerCtx.volume = 0x40;
+
+	const int channel = 0;
+	_channelCtx[channel].sfxLocked = false;
+	_channelCtx[channel].note = 0;
+	clearChannel(_channelCtx[channel]);
+
+	noteCommand(note, macro, channel, 0);
+
+	setTimerBaseValue(kPalCiaClock);
+	setInterruptFreqUnscaled(kPalDefaultCiaVal);
+	startPaula();
+}
+
+void Tfmx::doSong(int songPos) {
+	assert(0 <= songPos && songPos < kNumSubsongs);
+
+	_playerCtx.song = (int8)songPos;
+	_playerCtx.volume = 0x40;
+
+	_trackCtx.loopCount = -1;
+	_trackCtx.startInd = _trackCtx.posInd = _subsong[songPos].songstart;
+	_trackCtx.stopInd = _subsong[songPos].songend;
+
+	const uint16 tempo = _subsong[songPos].tempo;
+	uint16 ciaIntervall;
+	
+	if (tempo >= 0x10) {
+		ciaIntervall = (uint16)(kCiaBaseInterval / tempo);
+		_playerCtx.patternSkip = 0;
+	} else {
+		ciaIntervall = kPalDefaultCiaVal;
+		_playerCtx.patternSkip = tempo;
+	}
+
+	_playerCtx.patternCount = 0;
+
+	_playerCtx.pendingTrackstep = true;
+
+	for (int i = 0; i < kNumChannels; ++i) {
+		_patternCtx[i].command = 0xFF;
+		_patternCtx[i].expose = 0;
+	}
+
+	setTimerBaseValue(kPalCiaClock);
+	setInterruptFreqUnscaled(ciaIntervall);
+	startPaula();
+}
+
+}
Index: sound/mods/paula.cpp
===================================================================
--- sound/mods/paula.cpp	(Revision 41318)
+++ sound/mods/paula.cpp	(Arbeitskopie)
@@ -27,7 +27,7 @@
 
 namespace Audio {
 
-Paula::Paula(bool stereo, int rate, int interruptFreq) :
+Paula::Paula(bool stereo, int rate, uint interruptFreq) :
 		_stereo(stereo), _rate(rate), _intFreq(interruptFreq) {
 
 	clearVoices();
@@ -36,10 +36,11 @@
 	_voice[2].panning = 191;
 	_voice[3].panning = 63;
 
-	if (_intFreq <= 0)
+	if (_intFreq == 0)
 		_intFreq = _rate;
 
-	_curInt = _intFreq;
+	_curInt = 0;
+	_timerBase = 1;
 	_playing = false;
 	_end = true;
 }
@@ -55,8 +56,10 @@
 	_voice[voice].length = 0;
 	_voice[voice].lengthRepeat = 0;
 	_voice[voice].period = 0;
+	_voice[voice].periodRepeat = 0;
 	_voice[voice].volume = 0;
 	_voice[voice].offset = 0;
+	_voice[voice].dmaCount = 0;
 }
 
 int Paula::readBuffer(int16 *buffer, const int numSamples) {
@@ -95,14 +98,14 @@
 
 		// Handle 'interrupts'. This gives subclasses the chance to adjust the channel data
 		// (e.g. insert new samples, do pitch bending, whatever).
-		if (_curInt == _intFreq) {
+		if (_curInt == 0) {
+			_curInt = _intFreq;
 			interrupt();
-			_curInt = 0;
 		}
 
 		// Compute how many samples to generate: at most the requested number of samples,
 		// of course, but we may stop earlier when an 'interrupt' is expected.
-		const int nSamples = MIN(samples, _intFreq - _curInt);
+		const uint nSamples = MIN((uint)samples, _curInt);
 
 		// Loop over the four channels of the emulated Paula chip
 		for (int voice = 0; voice < NUM_VOICES; voice++) {
@@ -115,7 +118,7 @@
 			// the requested output sampling rate (typicall 44.1 kHz or 22.05 kHz)
 			// as well as the "period" of the channel we are processing right now,
 			// to compute the correct output 'rate'.
-			const double frequency = (7093789.2 / 2.0) / _voice[voice].period;
+			const double frequency = (kPalSystemClock / 2.0) / _voice[voice].period;
 			frac_t rate = doubleToFrac(frequency / _rate);
 
 			// Cap the volume
@@ -139,14 +142,25 @@
 			mixBuffer<stereo>(p, data, offset, rate, end, _voice[voice].volume, _voice[voice].panning);
 			neededSamples -= end;
 
+			// TODO correctly handle setting registers after last 2 bytes red from channel
+
 			// If we have not yet generated enough samples, and looping is active: loop!
 			if (neededSamples > 0 && _voice[voice].lengthRepeat > 2) {
 
 				// At this point we know that we have used up all samples in the buffer, so reset it.
+				_voice[voice].dmaCount++;
 				_voice[voice].data = data = _voice[voice].dataRepeat;
 				_voice[voice].length = _voice[voice].lengthRepeat;
+				_voice[voice].period = _voice[voice].periodRepeat;
 				sLen = intToFrac(_voice[voice].length);
 
+				if (_voice[voice].period != _voice[voice].periodRepeat) {
+					_voice[voice].period = _voice[voice].periodRepeat;
+					const double frequency = (kPalSystemClock / 2.0) / _voice[voice].period;
+					rate = doubleToFrac(frequency / _rate);
+
+				}
+
 				// If the "rate" exceeds the sample rate, we would have to perform constant
 				// wrap arounds. So, apply the first step of the euclidean algorithm to
 				// achieve the same more efficiently: Take rate modulo sLen
@@ -169,7 +183,7 @@
 
 		}
 		buffer += _stereo ? nSamples * 2 : nSamples;
-		_curInt += nSamples;
+		_curInt -= nSamples;
 		samples -= nSamples;
 	}
 	return numSamples;
Index: sound/mods/tfmx.h
===================================================================
--- sound/mods/tfmx.h	(Revision 0)
+++ sound/mods/tfmx.h	(Revision 0)
@@ -0,0 +1,233 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SOUND_MODS_TFMX_H
+#define SOUND_MODS_TFMX_H
+
+#include "sound/mods/paula.h"
+
+namespace {
+#ifndef NDEBUG
+inline void boundaryCheck(const void *bufStart, size_t bufLen, const void *address, size_t accessLen = 1) {
+	assert(bufStart <= address && (const byte *)address + accessLen <= (const byte *)bufStart + bufLen);
+}
+#else
+inline void boundaryCheck(const void *, size_t, void *, size_t = 1) {}
+#endif
+}
+
+namespace Audio {
+
+class Tfmx : public Paula {
+public:
+	Tfmx(int rate, bool stereo);
+	virtual ~Tfmx();
+
+	void interrupt();
+	void doSong(int songPos);
+	void doMacro(int macro, int note);
+	bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData);
+
+// Note: everythings public so the debug-Routines work.
+// private:
+	enum {kPalDefaultCiaVal = 11822, kNtscDefaultCiaVal = 14320, kCiaBaseInterval = 0x1B51F8};
+	enum {kNumVoices = 4, kNumChannels = 8, kNumSubsongs = 32, kMaxPatternOffsets = 128, kMaxMacroOffsets = 128};
+
+	static const uint16 noteIntervalls[64];
+
+	struct Resource {
+		uint32 _trackstepOffset;	//!< Offset in mdat
+
+		byte *_mdatData;  	//!< Currently the whole mdat-File
+		byte *_sampleData;	//!< Currently the whole sample-File
+		
+		uint32 _mdatLen;  
+		uint32 _sampleLen;
+
+		byte header[10];
+		uint16 headerFlags;
+		uint32 headerUnknown;
+		char textField[6 * 40];
+
+		const uint16 *getTrackPtr(uint16 trackstep = 0) {
+			uint16 *trackData = (uint16 *)(_mdatData + _trackstepOffset + 16 * trackstep);
+
+			boundaryCheck(_mdatData, _mdatLen, trackData, 16);
+			return trackData;
+		}
+
+		const uint32 *getPatternPtr(uint32 offset) {
+			uint32 *pattData = (uint32 *)(_mdatData + offset);
+
+			boundaryCheck(_mdatData, _mdatLen, pattData, 4);
+			return pattData;
+		}
+
+		const uint32 *getMacroPtr(uint32 offset) {
+			uint32 *macroData = (uint32 *)(_mdatData + offset);
+
+			boundaryCheck(_mdatData, _mdatLen, macroData, 4);
+			return macroData;
+		}
+
+		const int8 *getSamplePtr(const uint32 offset) {
+			int8 *sampleData = (int8 *)(_sampleData + offset);
+
+			boundaryCheck(_sampleData, _sampleLen, sampleData, 2);
+			return sampleData;
+		}
+		Resource() : _mdatData(), _mdatLen(), _sampleData(), _sampleLen() {}
+
+		~Resource() {
+			delete[] _mdatData;
+			delete[] _sampleData;
+		}
+	} _resource;
+
+	uint32 _patternOffset[kMaxPatternOffsets];	//!< Offset in mdat
+	uint32 _macroOffset[kMaxMacroOffsets];	//!< Offset in mdat
+
+	struct Subsong {
+		uint16 songstart;	//!< Index in Trackstep-Table
+		uint16 songend;		//!< Last index in Trackstep-Table
+		uint16 tempo;
+	} _subsong[kNumSubsongs];
+
+	struct ChannelContext {
+		byte	paulaChannel;
+
+		uint16	macroWait;
+		uint32	macroOffset;
+		uint32	macroReturnOffset;
+		uint16	macroStep;
+		uint32	macroReturnStep;
+		uint8	macroLoopCount;
+		bool	macroRun;
+
+		bool	sfxLocked;
+		int16	sfxLockTime;
+		bool	keyUp;
+
+		bool	deferWait;
+		bool	countDmaInterrupts;
+		uint16	dmaCount;
+
+		uint32	sampleStart;
+		uint16	sampleLen;
+		uint16	period;
+
+		int8	volume;
+		uint8	relVol;
+		uint8	note;
+		uint8	prevNote;
+		uint16	fineTune;
+
+		uint16	portaDestPeriod;
+		uint16	portaPeriod;
+		uint8	portaReset;
+		uint8	portaTime;
+		int16	portaRate;
+
+		uint8	envReset;
+		uint8	envTime;
+		uint8	envRate;
+		uint8	envEndVolume;
+
+		int16	vibOffset;
+		int8	vibWidth;
+		uint8	vibFlag;
+		uint8	vibReset;
+		uint8	vibTime;
+
+		uint8	addBeginTime;
+		uint8	addBeginReset;
+		int32	addBegin;
+	} _channelCtx[kNumVoices];
+
+	struct PatternContext {
+		uint32	offset; // patternStart, Offset from mdat
+		uint32	savedOffset;	// for subroutine calls
+		uint16	step;	// distance from patternStart
+		uint16	savedStep;
+
+		uint8	command;
+		int8	expose; 
+		uint8	loopCount;
+		uint8	wait;	//!< how many ticks to wait before next Command
+	} _patternCtx[kNumChannels];
+
+	struct TrackStepContext {
+		uint16	startInd;
+		uint16	stopInd;
+		uint16	posInd;
+		int16	loopCount;
+	} _trackCtx;
+
+	struct PlayerContext {
+		bool	enabled;
+//		bool	end;
+		int8	song;	//!< >= 0 if Song is running (means process Patterns)
+
+		bool	pendingTrackstep;
+
+		uint16	patternCount;
+		uint16	patternSkip;	//!< skip that amount of CIA-Interrupts
+
+		int8	volume;	//!< Master Volume
+
+/*		int8	fadeDest;
+		int8	fadeTime;
+		int8	fadeReset;
+		int8	fadeSlope; */
+	} _playerCtx;
+
+	void initMacroProgramm(ChannelContext &channel) {
+		channel.macroStep = 0;
+		channel.macroWait = 0;
+		channel.macroRun = true;
+		channel.macroLoopCount = 0xFF;
+		channel.countDmaInterrupts = false;
+	}
+
+	void clearChannel(ChannelContext &channel) {
+		if (!channel.sfxLocked) {
+			channel.macroRun = 0;
+			channel.countDmaInterrupts = false;
+			Paula::disableChannel(channel.paulaChannel);
+		} 
+	}
+
+	void effects(ChannelContext &channel);
+	FORCEINLINE bool macroStep(ChannelContext &channel);
+	void advancePatterns();
+	FORCEINLINE bool patternStep(PatternContext &pattern);
+	bool trackStep();
+	void noteCommand(uint8 note, uint8 param1, uint8 param2, uint8 param3);
+
+};
+
+}
+
+#endif
Index: sound/mods/soundfx.cpp
===================================================================
--- sound/mods/soundfx.cpp	(Revision 41318)
+++ sound/mods/soundfx.cpp	(Arbeitskopie)
@@ -46,8 +46,7 @@
 
 	enum {
 		NUM_CHANNELS = 4,
-		NUM_INSTRUMENTS = 15,
-		CIA_FREQ = 715909
+		NUM_INSTRUMENTS = 15
 	};
 
 	SoundFx(int rate, bool stereo);
@@ -75,12 +74,12 @@
 	uint16 _curPos;
 	uint8 _ordersTable[128];
 	uint8 *_patternData;
-	int _eventsFreq;
 	uint16 _effects[NUM_CHANNELS];
 };
 
 SoundFx::SoundFx(int rate, bool stereo)
 	: Paula(stereo, rate) {
+	setTimerBaseValue(kPalCiaClock);
 	_ticks = 0;
 	_delay = 0;
 	memset(_instruments, 0, sizeof(_instruments));
@@ -89,7 +88,6 @@
 	_curPos = 0;
 	memset(_ordersTable, 0, sizeof(_ordersTable));
 	_patternData = 0;
-	_eventsFreq = 0;
 	memset(_effects, 0, sizeof(_effects));
 }
 
@@ -167,8 +165,7 @@
 	_curPos = 0;
 	_curOrder = 0;
 	_ticks = 0;
-	_eventsFreq = CIA_FREQ / _delay;
-	setInterruptFreq(getRate() / _eventsFreq);
+	setInterruptFreqUnscaled(_delay);
 	startPaula();
 }
 
@@ -252,7 +249,7 @@
 }
 
 void SoundFx::disablePaulaChannel(uint8 channel) {
-	setChannelPeriod(channel, 0);
+	disableChannel(channel);
 }
 
 void SoundFx::setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen) {
Index: sound/mods/paula.h
===================================================================
--- sound/mods/paula.h	(Revision 41318)
+++ sound/mods/paula.h	(Arbeitskopie)
@@ -40,12 +40,27 @@
 class Paula : public AudioStream {
 public:
 	static const int NUM_VOICES = 4;
+	enum {
+		kPalSystemClock		= 7093790,
+		kNtscSystemClock	= 7159090,
+		kPalCiaClock		= kPalSystemClock / 10,
+		kNtscCiaClock		= kNtscSystemClock / 10
+	};
 
-	Paula(bool stereo = false, int rate = 44100, int interruptFreq = 0);
+	Paula(bool stereo = false, int rate = 44100, uint interruptFreq = 0);
 	~Paula();
 
 	bool playing() const { return _playing; }
-	void setInterruptFreq(int freq) { _curInt = _intFreq = freq; }
+	void setTimerBaseValue( uint32 ticksPerSecond ) { _timerBase = ticksPerSecond; }
+	uint32 getTimerBaseValue() { return _timerBase; }
+	void setSingleInterrupt(uint sampleDelay) { assert(sampleDelay < _intFreq); _curInt = sampleDelay; }
+	void setSingleInterruptUnscaled(uint timerDelay) { 
+		setSingleInterrupt((uint)(((double)timerDelay * getRate()) / _timerBase));
+	}
+	void setInterruptFreq(uint sampleDelay) { _intFreq = sampleDelay; _curInt = 0; }
+	void setInterruptFreqUnscaled(uint timerDelay) { 
+		setInterruptFreq((uint)(((double)timerDelay * getRate()) / _timerBase));
+	}
 	void clearVoice(byte voice);
 	void clearVoices() { for (int i = 0; i < NUM_VOICES; ++i) clearVoice(i); }
 	void startPlay(void) { _playing = true; }
@@ -65,9 +80,11 @@
 		uint32 length;
 		uint32 lengthRepeat;
 		int16 period;
+		int16 periodRepeat;
 		byte volume;
 		frac_t offset;
 		byte panning; // For stereo mixing: 0 = far left, 255 = far right
+		int dmaCount;
 	};
 
 	bool _end;
@@ -90,9 +107,24 @@
 		_voice[channel].panning = panning;
 	}
 
+	void disableChannel(byte channel) {
+		assert(channel < NUM_VOICES);
+		_voice[channel].data = 0;
+	}
+
+	void enableChannel(byte channel) {
+		assert(channel < NUM_VOICES);
+		Channel &ch = _voice[channel];
+		ch.data = ch.dataRepeat;
+		ch.length = ch.lengthRepeat;
+		// actually first 2 bytes are dropped?
+		ch.offset = intToFrac(0);
+		ch.period = ch.periodRepeat;
+	}
+
 	void setChannelPeriod(byte channel, int16 period) {
 		assert(channel < NUM_VOICES);
-		_voice[channel].period = period;
+		_voice[channel].periodRepeat = period;
 	}
 
 	void setChannelVolume(byte channel, byte volume) {
@@ -100,6 +132,17 @@
 		_voice[channel].volume = volume;
 	}
 
+	void setChannelSampleStart(byte channel, const int8 *data) {
+		assert(channel < NUM_VOICES);
+		_voice[channel].dataRepeat = data;
+	}
+
+	void setChannelSampleLen(byte channel, uint32 length) {
+		assert(channel < NUM_VOICES);
+		assert(length < 32768/2);
+		_voice[channel].lengthRepeat = 2 * length;
+	}
+
 	void setChannelData(uint8 channel, const int8 *data, const int8 *dataRepeat, uint32 length, uint32 lengthRepeat, int32 offset = 0) {
 		assert(channel < NUM_VOICES);
 
@@ -110,11 +153,14 @@
 		assert(lengthRepeat < 32768);
 
 		Channel &ch = _voice[channel];
-		ch.data = data;
+
+		ch.dataRepeat = data;
+		ch.lengthRepeat = length;
+		enableChannel(channel);
+		ch.offset = intToFrac(offset);
+
 		ch.dataRepeat = dataRepeat;
-		ch.length = length;
 		ch.lengthRepeat = lengthRepeat;
-		ch.offset = intToFrac(offset);
 	}
 
 	void setChannelOffset(byte channel, frac_t offset) {
@@ -128,13 +174,24 @@
 		return _voice[channel].offset;
 	}
 
+	int getChannelDmaCount(byte channel) {
+		assert(channel < NUM_VOICES);
+		return _voice[channel].dmaCount;
+	}
+
+	void setChannelDmaCount(byte channel, int dmaVal = 0) {
+		assert(channel < NUM_VOICES);
+		_voice[channel].dmaCount = dmaVal;
+	}
+
 private:
 	Channel _voice[NUM_VOICES];
 
 	const bool _stereo;
 	const int _rate;
-	int _intFreq;
-	int _curInt;
+	uint _intFreq;
+	uint _curInt;
+	uint32 _timerBase;
 	bool _playing;
 
 	template<bool stereo>
Index: common/scummsys.h
===================================================================
--- common/scummsys.h	(Revision 41318)
+++ common/scummsys.h	(Arbeitskopie)
@@ -44,6 +44,7 @@
 
 		#ifdef _MSC_VER
 		#pragma once
+		#if (_MSC_VER < 1300)
 		#pragma warning( disable : 4068 ) // turn off "unknown pragma" warning
 		#pragma	warning( disable : 4103 ) // turn off "alignement changed after including header" warning. We use pack-start.h file
 		#pragma warning( disable : 4244 ) // turn off "conversion type" warning
@@ -54,6 +55,7 @@
 		#pragma warning( disable : 4610 ) // turn off "struct can never be instantiated - user defined constructor required"
 		#pragma warning( disable : 4701 ) // turn off "potentially uninitialized variables" warning
 		#pragma warning( disable : 4800 ) // turn off "forcing value to bool 'true' or 'false' (performance warning)"
+		#endif
 
 		// vsnprintf is already defined in Visual Studio 2008
 		#if (_MSC_VER < 1500)
Index: Makefile.common
===================================================================
--- Makefile.common	(Revision 41318)
+++ Makefile.common	(Arbeitskopie)
@@ -27,6 +27,7 @@
 	graphics \
 	sound \
 	backends \
+	tfmx \
 	common \
 
 ifdef USE_MT32EMU
Index: base/main.cpp
===================================================================
--- base/main.cpp	(Revision 41318)
+++ base/main.cpp	(Arbeitskopie)
@@ -295,6 +295,9 @@
 
 }
 
+#if 1
+void tfmxmain(int argc, const char * const argv[]);
+
 extern "C" int scummvm_main(int argc, const char * const argv[]) {
 	Common::String specialDebug;
 	Common::String command;
@@ -306,6 +309,37 @@
 	// Register config manager defaults
 	Base::registerDefaults();
 
+	// Load the plugins.
+	PluginManager::instance().loadPlugins();
+
+	// Init the backend. Must take place after all config data (including
+	// the command line params) was read.
+	system.initBackend();
+
+	// pass control to my own main-function, including arguments
+	tfmxmain(argc,argv);
+
+	PluginManager::instance().unloadPlugins();
+	PluginManager::destroy();
+	Common::ConfigManager::destroy();
+	Common::SearchManager::destroy();
+	GUI::GuiManager::destroy();
+
+	return 0;
+}
+#else
+
+extern "C" int scummvm_main(int argc, const char * const argv[]) {
+	Common::String specialDebug;
+	Common::String command;
+
+	// Verify that the backend has been initialized (i.e. g_system has been set).
+	assert(g_system);
+	OSystem &system = *g_system;
+
+	// Register config manager defaults
+	Base::registerDefaults();
+
 	// Parse the command line
 	Common::StringMap settings;
 	command = Base::parseCommandLine(settings, argc, argv);
@@ -415,3 +449,5 @@
 
 	return 0;
 }
+
+#endif
Index: tfmx/tfmxdebug.cpp
===================================================================
--- tfmx/tfmxdebug.cpp	(Revision 0)
+++ tfmx/tfmxdebug.cpp	(Revision 0)
@@ -0,0 +1,189 @@
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/debug.h"
+#include "common/stream.h"
+#include "common/util.h"
+
+#include "sound/mods/tfmx.h"
+
+#include "tfmx/tfmxdebug.h"
+
+
+const char *pattcmds[]={
+	"End --Next track  step--",
+	"Loop[count     / step.w]",
+	"Cont[patternno./ step.w]",
+	"Wait[count 00-FF--------",
+	"Stop--Stop this pattern-",
+	"Kup^-Set key up/channel]",
+	"Vibr[speed     / rate.b]",
+	"Enve[speed /endvolume.b]",
+	"GsPt[patternno./ step.w]",
+	"RoPt-Return old pattern-",
+	"Fade[speed /endvolume.b]",
+	"PPat[patt./track+transp]",
+	"Lock---------ch./time.b]",
+	"----------No entry------",
+	"Stop-Stop custompattern-",
+	"NOP!-no operation-------"
+};
+
+const char *macrocmds[]={
+	"DMAoff+Resetxx/xx/xx flag/addset/vol   ",
+	"DMAon (start sample at selected begin) ",
+	"SetBegin    xxxxxx   sample-startadress",
+	"SetLen      ..xxxx   sample-length     ",
+	"Wait        ..xxxx   count (VBI''s)    ",
+	"Loop        xx/xxxx  count/step        ",
+	"Cont        xx/xxxx  macro-number/step ",
+	"-------------STOP----------------------",
+	"AddNote     xx/xxxx  note/detune       ",
+	"SetNote     xx/xxxx  note/detune       ",
+	"Reset   Vibrato-Portamento-Envelope    ",
+	"Portamento  xx/../xx count/speed       ",
+	"Vibrato     xx/../xx speed/intensity   ",
+	"AddVolume   ....xx   volume 00-3F      ",
+	"SetVolume   ....xx   volume 00-3F      ",
+	"Envelope    xx/xx/xx speed/count/endvol",
+	"Loop key up xx/xxxx  count/step        ",
+	"AddBegin    xx/xxxx  count/add to start",
+	"AddLen      ..xxxx   add to sample-len ",
+	"DMAoff stop sample but no clear        ",
+	"Wait key up ....xx   count (VBI''s)    ",
+	"Go submacro xx/xxxx  macro-number/step ",
+	"--------Return to old macro------------",
+	"Setperiod   ..xxxx   DMA period        ",
+	"Sampleloop  ..xxxx   relative adress   ",
+	"-------Set one shot sample-------------",
+	"Wait on DMA ..xxxx   count (Wavecycles)",
+	"Random play xx/xx/xx macro/speed/mode  ",
+	"Splitkey    xx/xxxx  key/macrostep     ",
+	"Splitvolume xx/xxxx  volume/macrostep  ",
+	"Addvol+note xx/fe/xx note/CONST./volume",
+	"SetPrevNote xx/xxxx  note/detune       ",
+	"Signal      xx/xxxx  signalnumber/value",
+	"Play macro  xx/.x/xx macro/chan/detune ",
+	"SID setbeg  xxxxxx   sample-startadress",
+	"SID setlen  xx/xxxx  buflen/sourcelen  ",
+	"SID op3 ofs xxxxxx   offset            ",
+	"SID op3 frq xx/xxxx  speed/amplitude   ",
+	"SID op2 ofs xxxxxx   offset            ",
+	"SID op2 frq xx/xxxx  speed/amplitude   ",
+	"SID op1     xx/xx/xx speed/amplitude/TC",
+	"SID stop    xx....   flag (1=clear all)"
+};
+
+const char *const trackstepFmt[] = {
+	"---Stop Player----",
+	"Loop step/count   ",
+	"Tempo tempo/ciaDiv",
+	"Timeshare ?/?     ",
+	"Fade start/end    "
+	"Unknown (cc)      "
+};
+
+void displayPatternstep(const void *const vptr) {
+	const byte *const patData = (const byte *const)vptr;
+
+	const byte command = patData[0];
+
+	if (command < 0xF0) { // Playnote
+		const byte flags = command >> 6; // 0-1 means note+detune, 2 means wait, 3 means portamento?
+		char *flagsSt[] = {"Note ", "Note ", "Wait ", "Porta"};
+		debug("%s %02X%02X%02X%02X", flagsSt[flags], patData[0], patData[1], patData[2], patData[3]);
+	} else {
+		debug("%s %02X%02X%02X",pattcmds[command&0xF], patData[1], patData[2], patData[3]);
+	}
+
+}
+
+void displayTrackstep(const void *const vptr) {
+	const uint16 *const trackData = (const uint16 *const)vptr;
+
+	if (trackData[0] == FROM_BE_16(0xEFFE)) {
+		// 16 byte Trackstep Command
+		const uint16 command = READ_BE_UINT16(&trackData[1]);
+		const uint16 param1 = READ_BE_UINT16(&trackData[2]);
+		const uint16 param2 = READ_BE_UINT16(&trackData[3]);
+
+
+		if (command >= ARRAYSIZE(trackstepFmt))
+			debug("Unknown (%04X)    : %04X %04X", command, param1, param2);
+		else
+			debug("%s: %04X %04X", trackstepFmt[command], param1, param2);
+	} else {
+		const byte *const ptr = (const byte *const)vptr;
+		// 8 commands for Patterns
+		debug("%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X",
+			ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], 
+			ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
+	}
+}
+
+void displayMacroStep(const void *const vptr) {
+	const byte *const macroData = (const byte *const)vptr;
+	if (macroData[0] < ARRAYSIZE(macrocmds))
+		debug("%s %02X%02X%02X", macrocmds[macroData[0]], macroData[1], macroData[2], macroData[3]);
+	else
+		debug("Unkown Macro #%02X %02X%02X%02X", macroData[0], macroData[1], macroData[2], macroData[3]);
+}
+
+void dumpTracksteps(Audio::Tfmx &player, uint16 first, uint16 last) {
+	for ( ; first <= last; ++first) {
+		displayTrackstep(player._resource.getTrackPtr(first));
+	}
+}
+
+void dumpTrackstepsBySong(Audio::Tfmx &player, int song) {
+	dumpTracksteps(player, player._subsong[song].songstart, player._subsong[song].songend);
+}
+
+void dumpMacro(Audio::Tfmx &player, uint16 macroIndex, uint16 len, uint16 start) {
+	const uint32 * macroPtr = player._resource.getMacroPtr(player._macroOffset[macroIndex]);
+	bool untilMacroStop = (len == 0);
+	while (len--) {
+		displayMacroStep(macroPtr++);
+	}
+	while (untilMacroStop) {
+		untilMacroStop = *(const byte *)macroPtr != 7;
+		displayMacroStep(macroPtr++);
+	}
+}
+
+void dumpPattern(Audio::Tfmx &player, uint16 pattIndex, uint16 len, uint16 start) {
+	const uint32 * pattPtr = player._resource.getPatternPtr(player._patternOffset[pattIndex]);
+	if (len == 0)
+		len = (player._patternOffset[pattIndex+1] - player._patternOffset[pattIndex])/4;
+	bool untilMacroStop = (len == 0);
+	while (len--) {
+		displayPatternstep(pattPtr++);
+	}
+	while (untilMacroStop) {
+		byte cmd = *(const byte *)pattPtr;
+		untilMacroStop = cmd != 0 && cmd != 4;
+		displayPatternstep(pattPtr++);
+	}
+}
+
+void countAllMacros1(Audio::Tfmx &player, uint16 macroIndex, int *list) {
+	const uint32 * macroPtr = player._resource.getMacroPtr(player._macroOffset[macroIndex]);
+	bool untilMacroStop = true;
+	while (untilMacroStop) {
+		const int type = *(const byte *)macroPtr++;
+		untilMacroStop = type != 7;
+		list[type]++;
+	}
+}
+
+void countAllMacros(Audio::Tfmx &player) {
+	int list[256] = {0};
+	for (int i = 0; i < 128; ++i)
+		countAllMacros1(player, i, list);
+	byte fakeMacro[4] = {0};
+	for (int i = 0; i < 256; ++i) {
+		fakeMacro[0] = (byte)i;
+		if (list[i] > 0)
+			displayMacroStep(fakeMacro);
+	}
+
+}
Index: tfmx/module.mk
===================================================================
--- tfmx/module.mk	(Revision 0)
+++ tfmx/module.mk	(Revision 0)
@@ -0,0 +1,8 @@
+MODULE := tfmx
+
+MODULE_OBJS := \
+	tfmxplayer.o \
+	tfmxdebug.o
+
+# Include common rules
+include $(srcdir)/rules.mk
Index: tfmx/tfmxdebug.h
===================================================================
--- tfmx/tfmxdebug.h	(Revision 0)
+++ tfmx/tfmxdebug.h	(Revision 0)
@@ -0,0 +1,12 @@
+#ifndef TFMXDEBUG_H
+
+void displayTrackstep(const void *const vptr);
+void displayPatternstep(const void *const vptr);
+void displayMacroStep(const void *const vptr);
+void dumpTracksteps(Audio::Tfmx &player, uint16 first, uint16 last);
+void dumpTrackstepsBySong(Audio::Tfmx &player, int song);
+void dumpMacro(Audio::Tfmx &player, uint16 macroIndex, uint16 len = 0, uint16 start = 0);
+void dumpPattern(Audio::Tfmx &player, uint16 pattIndex, uint16 len = 0, uint16 start = 0);
+void countAllMacros(Audio::Tfmx &player);
+
+#endif // TFMXDEBUG_H
\ No newline at end of file
Index: tfmx/tfmxplayer.cpp
===================================================================
--- tfmx/tfmxplayer.cpp	(Revision 0)
+++ tfmx/tfmxplayer.cpp	(Revision 0)
@@ -0,0 +1,201 @@
+#include "common/scummsys.h"
+#include "common/system.h"
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/fs.h"
+#include "common/endian.h"
+#include "common/debug.h"
+
+#include "sound/mixer.h"
+#include "sound/mods/protracker.h"
+#include "sound/mods/tfmx.h"
+
+#include "tfmx/tfmxdebug.h"
+
+#define FILEDIR "" 
+
+using namespace Common;
+
+void simplePlaybacktest(int argc, const char *const argv[]) {
+	const char *modFilename = "mod.protracker";
+	if (argc == 2)
+		modFilename = argv[1];
+
+
+	// get Mixer, assume this never fails 
+	Audio::Mixer *mixer = g_system->getMixer();
+
+	FSNode fileDir(FILEDIR);
+	debug( "searching for Files in Directory: %s", fileDir.getPath().c_str());
+
+	FSNode musicFile = fileDir.getChild(modFilename);
+
+	SeekableReadStream *fileIn = musicFile.createReadStream();
+	if (0 == fileIn) {
+		debug( "cant open File %s", musicFile.getName().c_str());
+		return;
+	}
+
+	Audio::AudioStream *stream = Audio::makeProtrackerStream(fileIn);
+	delete fileIn;
+	if (0 == stream) {
+		debug( "cant open File %s as Protacker-Stream", musicFile.getName().c_str());
+		return;
+	}
+
+	Audio::SoundHandle soundH;
+
+	mixer->playInputStream(Audio::Mixer::kMusicSoundType, &soundH, stream);
+	while (mixer->isSoundHandleActive(soundH))
+		g_system->delayMillis(1000);
+	
+
+	//mixer->stopAll();
+}
+
+#define MUSICFILE "mdat.monkey"
+#define SAMPLEFILE "smpl.monkey"
+
+//#define MUSICFILE "mdat.tworld_1"
+//#define SAMPLEFILE "smpl.tworld_1"
+Audio::Tfmx *loadTfmxfile(const char *mdatName, const char *sampleName) {
+	FSNode fileDir(FILEDIR);
+	FSNode musicNode = fileDir.getChild(mdatName);
+	FSNode sampleNode = fileDir.getChild(sampleName);
+	SeekableReadStream *musicIn = musicNode.createReadStream();
+	if (0 == musicIn) {
+		debug("Couldnt load file %s", MUSICFILE);
+		return 0;
+	}
+
+	SeekableReadStream *sampleIn = sampleNode.createReadStream();
+	if (0 == sampleIn) {
+		debug("Couldnt load file %s", SAMPLEFILE);
+		delete musicIn;
+		return 0;
+	}
+
+	Audio::Tfmx *player = new Audio::Tfmx(44100, true);
+	player->load(*musicIn, *sampleIn);
+	delete musicIn;
+	delete sampleIn;
+
+	return player;
+}
+
+void runFlac(int chan, int bits, int sr, const char *fileName);
+
+void tfmxmain(const int argc, const char *const argv[]) {
+	debug("Started Scumm&VM");
+	debug("Sound celebrating utility for monkey melodies & Various Malfunctions");
+	debug("");
+
+	//simplePlaybacktest(argc, argv);
+
+	Audio::Tfmx *player = loadTfmxfile(MUSICFILE, SAMPLEFILE);
+	if (!player) {
+		debug("couldnt create TFMX-Player");
+		return;
+	}
+
+	int i = 1;
+	int playflag = 0;
+
+	
+	if (i < argc && argv[i][0] == '-' + strlen(argv[i]) == 2) {
+		int param;
+		switch (argv[i++][1]) {
+		case 'm':
+			if (i < argc) {
+				param = atoi(argv[i]);
+				debug( "play Macro %02X", param);
+				dumpMacro(*player, 0x11);
+				playflag = 1;
+				player->doMacro(param,0x40);
+				++i;
+			}
+			break;
+		case 's':
+			if (i < argc) {
+				param = atoi(argv[i]);
+				debug( "play Song %02X", param);
+				dumpTrackstepsBySong(*player, param);
+				playflag = 1;
+				player->doSong(param);
+				++i;
+			}
+		}
+	}
+
+	if (!playflag) {
+		playflag = 1;
+		// player->doMacro(0x18,0x40);
+		player->doSong(4);
+		dumpTrackstepsBySong(*player, 4);
+	}
+
+
+
+	
+#if 0
+	int16 buf[2 * 1024];
+
+	while( true)
+		player->readBuffer(buf, ARRAYSIZE(buf));
+
+#endif
+	int maxsecs = 3*60;
+	if (playflag == 1) {
+		// get Mixer, assume this never fails 
+		Audio::Mixer *mixer = g_system->getMixer();
+
+		Audio::SoundHandle soundH;
+
+		mixer->playInputStream(Audio::Mixer::kMusicSoundType, &soundH, player);
+		while (mixer->isSoundHandleActive(soundH) && --maxsecs)
+			g_system->delayMillis(1000);
+//		player->AllOff();
+
+		while (mixer->isSoundHandleActive(soundH));
+
+		mixer->stopHandle(soundH);
+		player = 0;
+	}
+
+	if (playflag == 2) {
+		Common::FSNode file("out.raw");
+		WriteStream *wav = file.createWriteStream();
+		int16 buf[2 * 1024];
+		int32 maxsamples = (maxsecs <= 0) ? 0 : maxsecs * 44100;
+		while (!player->endOfData() && maxsamples > 0) {
+			int read = player->readBuffer(buf, ARRAYSIZE(buf));
+			wav->write(buf, read * 2);
+			maxsamples -= read/2;
+		}
+		delete wav;
+
+		runFlac(2, 16, 44100, "out.raw");
+	}
+
+
+	printf("\npress a key");
+	getc(stdin);
+	
+	delete player;
+}
+
+void runFlac( int chan, int bits, int sr, const char *fileName) {
+	const char *format = "flac --endian="
+#ifdef SCUMM_BIG_ENDIAN
+			"big"
+#else
+			"little"
+#endif
+			" --channels=%d -f --bps=%d --sample-rate=%d --sign=signed --force-raw-format %s";
+	char cmd[1024];
+	sprintf(cmd, format, chan, bits, sr, fileName);
+			debug(cmd);
+	system(cmd);
+}
+
+
