aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.common1
-rw-r--r--backends/platform/sdl/sdl.cpp14
-rw-r--r--base/main.cpp36
-rw-r--r--common/scummsys.h2
-rw-r--r--dists/msvc9/ScummVM_Debug.vsprops25
-rw-r--r--dists/msvc9/ScummVM_Global.vsprops30
-rw-r--r--dists/msvc9/ScummVM_Release.vsprops24
-rw-r--r--dists/msvc9/kyra.vcproj698
-rw-r--r--dists/msvc9/scumm.vcproj958
-rw-r--r--dists/msvc9/scummvm-tfmx.sln48
-rw-r--r--dists/msvc9/scummvm-tfmx.vcproj2018
-rw-r--r--engines/kyra/kyra_v1.cpp2
-rw-r--r--engines/kyra/module.mk1
-rw-r--r--engines/kyra/sound_amiga.cpp101
-rw-r--r--engines/kyra/sound_intern.h28
-rw-r--r--engines/scumm/module.mk1
-rw-r--r--engines/scumm/palette.cpp223
-rw-r--r--engines/scumm/player_v4a.cpp186
-rw-r--r--engines/scumm/player_v4a.h96
-rw-r--r--engines/scumm/scumm.cpp6
-rw-r--r--engines/scumm/scumm.h2
-rw-r--r--engines/scumm/sound.cpp20
-rw-r--r--sound/mods/maxtrax.cpp717
-rw-r--r--sound/mods/maxtrax.h260
-rw-r--r--sound/mods/paula.cpp38
-rw-r--r--sound/mods/paula.h71
-rw-r--r--sound/mods/soundfx.cpp11
-rw-r--r--sound/mods/tfmx.cpp996
-rw-r--r--sound/mods/tfmx.h296
-rw-r--r--sound/module.mk2
-rw-r--r--tfmx/module.mk9
-rw-r--r--tfmx/mxtxplayer.cpp148
-rw-r--r--tfmx/tfmxdebug.cpp200
-rw-r--r--tfmx/tfmxdebug.h14
-rw-r--r--tfmx/tfmxplayer.cpp171
35 files changed, 6888 insertions, 565 deletions
diff --git a/Makefile.common b/Makefile.common
index 51261d65d9..251711301f 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -25,6 +25,7 @@ MODULES += \
engines \
gui \
graphics \
+ tfmx \
sound \
backends \
common \
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index b353c79495..57a277d1ff 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -89,7 +89,12 @@ void OSystem_SDL::initBackend() {
assert(!_inited);
int joystick_num = ConfMan.getInt("joystick_num");
- uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+ joystick_num = 0;
+#if !defined(TFMX_CMDLINE_TOOL) && !defined(MXTX_CMDLINE_TOOL)
+ uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+#else
+ uint32 sdlFlags = /*SDL_INIT_VIDEO |*/ SDL_INIT_AUDIO | SDL_INIT_TIMER;
+#endif
if (ConfMan.hasKey("disable_sdl_parachute"))
sdlFlags |= SDL_INIT_NOPARACHUTE;
@@ -108,10 +113,11 @@ void OSystem_SDL::initBackend() {
error("Could not initialize SDL: %s", SDL_GetError());
}
- _graphicsMutex = createMutex();
+ _graphicsMutex = createMutex();
+#if !defined(TFMX_CMDLINE_TOOL) && !defined(MXTX_CMDLINE_TOOL)
SDL_ShowCursor(SDL_DISABLE);
-
+
// Enable unicode support if possible
SDL_EnableUNICODE(1);
@@ -163,7 +169,7 @@ void OSystem_SDL::initBackend() {
_savefile = new DefaultSaveFileManager();
#endif
}
-
+#endif
// Create and hook up the mixer, if none exists yet (we check for this to
// allow subclasses to provide their own).
if (_mixer == 0) {
diff --git a/base/main.cpp b/base/main.cpp
index 2d4091c0d5..6f8a61a595 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -295,6 +295,40 @@ static void setupKeymapper(OSystem &system) {
}
+#if defined(TFMX_CMDLINE_TOOL) || defined(MXTX_CMDLINE_TOOL)
+void modcmdmain(int argc, const char * const argv[]);
+
+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();
+
+ // 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
+ modcmdmain(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;
@@ -419,3 +453,5 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
return 0;
}
+
+#endif
diff --git a/common/scummsys.h b/common/scummsys.h
index a9c5fb3266..4fa3c80f71 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -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)
diff --git a/dists/msvc9/ScummVM_Debug.vsprops b/dists/msvc9/ScummVM_Debug.vsprops
deleted file mode 100644
index 910096cab6..0000000000
--- a/dists/msvc9/ScummVM_Debug.vsprops
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="ScummVM_Debug32"
- InheritedPropertySheets=".\ScummVM_Global.vsprops"
- >
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- EnableFunctionLevelLinking="true"
- WarnAsError="false"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- IgnoreDefaultLibraryNames="libcmt.lib"
- />
-</VisualStudioPropertySheet>
diff --git a/dists/msvc9/ScummVM_Global.vsprops b/dists/msvc9/ScummVM_Global.vsprops
deleted file mode 100644
index 7ba00aac7b..0000000000
--- a/dists/msvc9/ScummVM_Global.vsprops
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="ScummVM_Global"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)/$(ProjectName)"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4068;4100;4103;4121;4127;4189;4201;4221;4244;4250;4310;4351;4355;4510;4511;4512;4610;4701;4702;4706;4800;4996"
- AdditionalIncludeDirectories="../..;../../engines"
- PreprocessorDefinitions="USE_NASM;USE_ZLIB;USE_MAD;USE_VORBIS;USE_MPEG2;USE_MT32EMU;ENABLE_AGI;ENABLE_AGOS;ENABLE_CINE;ENABLE_CRUISE;ENABLE_DRASCULA;ENABLE_GOB;ENABLE_IGOR;ENABLE_KYRA;ENABLE_LOL;ENABLE_LURE;ENABLE_M4;ENABLE_MADE;ENABLE_PARALLACTION;ENABLE_QUEEN;ENABLE_SAGA;ENABLE_IHNM;ENABLE_SAGA2;ENABLE_SCI;ENABLE_SCUMM;ENABLE_SKY;ENABLE_SWORD1;ENABLE_SWORD2;ENABLE_TOUCHE;ENABLE_SCUMM_7_8;ENABLE_HE;ENABLE_TINSEL;ENABLE_TUCKER;ENABLE_GROOVIE"
- ExceptionHandling="0"
- RuntimeTypeInfo="false"
- WarningLevel="4"
- WarnAsError="true"
- CompileAs="0"
- />
- <Tool
- Name="VCLibrarianTool"
- IgnoreDefaultLibraryNames=""
- />
- <Tool
- Name="VCLinkerTool"
- IgnoreDefaultLibraryNames=""
- SubSystem="1"
- EntryPointSymbol="WinMainCRTStartup"
- />
-</VisualStudioPropertySheet>
diff --git a/dists/msvc9/ScummVM_Release.vsprops b/dists/msvc9/ScummVM_Release.vsprops
deleted file mode 100644
index 837be3b94c..0000000000
--- a/dists/msvc9/ScummVM_Release.vsprops
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioPropertySheet
- ProjectType="Visual C++"
- Version="8.00"
- Name="ScummVM_Release32"
- InheritedPropertySheets=".\ScummVM_Global.vsprops"
- >
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- EnableIntrinsicFunctions="true"
- WholeProgramOptimization="true"
- PreprocessorDefinitions="WIN32"
- StringPooling="true"
- BufferSecurityCheck="false"
- DebugInformationFormat="0"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="1"
- IgnoreDefaultLibraryNames=""
- SetChecksum="true"
- />
-</VisualStudioPropertySheet>
diff --git a/dists/msvc9/kyra.vcproj b/dists/msvc9/kyra.vcproj
index 98b2609718..97befa059d 100644
--- a/dists/msvc9/kyra.vcproj
+++ b/dists/msvc9/kyra.vcproj
@@ -9,128 +9,588 @@
TargetFrameworkVersion="131072"
>
<Platforms>
- <Platform Name="Win32" />
+ <Platform
+ Name="Win32"
+ />
</Platforms>
+ <ToolFiles>
+ </ToolFiles>
<Configurations>
- <Configuration Name="Debug|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Debug.vsprops" />
- <Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" />
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\ScummVM_Debug.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\ScummVM_Release.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
+ <References>
+ </References>
<Files>
- <File RelativePath="..\..\engines\kyra\animator_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\animator_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\animator_lok.h" />
- <File RelativePath="..\..\engines\kyra\animator_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\animator_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\debugger.cpp" />
- <File RelativePath="..\..\engines\kyra\debugger.h" />
- <File RelativePath="..\..\engines\kyra\detection.cpp" />
- <File RelativePath="..\..\engines\kyra\gui.cpp" />
- <File RelativePath="..\..\engines\kyra\gui.h" />
- <File RelativePath="..\..\engines\kyra\gui_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\gui_hof.h" />
- <File RelativePath="..\..\engines\kyra\gui_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\gui_lok.h" />
- <File RelativePath="..\..\engines\kyra\gui_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\gui_lol.h" />
- <File RelativePath="..\..\engines\kyra\gui_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\gui_mr.h" />
- <File RelativePath="..\..\engines\kyra\gui_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\gui_v2.h" />
- <File RelativePath="..\..\engines\kyra\items_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\items_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\items_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\items_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\items_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\kyra_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\kyra_hof.h" />
- <File RelativePath="..\..\engines\kyra\kyra_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\kyra_lok.h" />
- <File RelativePath="..\..\engines\kyra\kyra_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\kyra_mr.h" />
- <File RelativePath="..\..\engines\kyra\kyra_v1.cpp" />
- <File RelativePath="..\..\engines\kyra\kyra_v1.h" />
- <File RelativePath="..\..\engines\kyra\kyra_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\kyra_v2.h" />
- <File RelativePath="..\..\engines\kyra\lol.cpp" />
- <File RelativePath="..\..\engines\kyra\lol.h" />
- <File RelativePath="..\..\engines\kyra\resource.cpp" />
- <File RelativePath="..\..\engines\kyra\resource.h" />
- <File RelativePath="..\..\engines\kyra\resource_intern.cpp" />
- <File RelativePath="..\..\engines\kyra\resource_intern.h" />
- <File RelativePath="..\..\engines\kyra\saveload.cpp" />
- <File RelativePath="..\..\engines\kyra\saveload_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\saveload_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\saveload_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\saveload_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\scene_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\scene_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\scene_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\scene_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\scene_v1.cpp" />
- <File RelativePath="..\..\engines\kyra\scene_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\screen.cpp" />
- <File RelativePath="..\..\engines\kyra\screen.h" />
- <File RelativePath="..\..\engines\kyra\screen_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\screen_hof.h" />
- <File RelativePath="..\..\engines\kyra\screen_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\screen_lok.h" />
- <File RelativePath="..\..\engines\kyra\screen_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\screen_lol.h" />
- <File RelativePath="..\..\engines\kyra\screen_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\screen_mr.h" />
- <File RelativePath="..\..\engines\kyra\screen_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\screen_v2.h" />
- <File RelativePath="..\..\engines\kyra\script.cpp" />
- <File RelativePath="..\..\engines\kyra\script.h" />
- <File RelativePath="..\..\engines\kyra\script_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\script_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\script_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\script_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\script_tim.cpp" />
- <File RelativePath="..\..\engines\kyra\script_tim.h" />
- <File RelativePath="..\..\engines\kyra\script_v1.cpp" />
- <File RelativePath="..\..\engines\kyra\script_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\seqplayer.cpp" />
- <File RelativePath="..\..\engines\kyra\seqplayer.h" />
- <File RelativePath="..\..\engines\kyra\sequences_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\sequences_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\sequences_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\sequences_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\sequences_v2.cpp" />
- <File RelativePath="..\..\engines\kyra\sound.cpp" />
- <File RelativePath="..\..\engines\kyra\sound.h" />
- <File RelativePath="..\..\engines\kyra\sound_adlib.cpp" />
- <File RelativePath="..\..\engines\kyra\sound_digital.cpp" />
- <File RelativePath="..\..\engines\kyra\sound_intern.h" />
- <File RelativePath="..\..\engines\kyra\sound_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\sound_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\sound_midi.cpp" />
- <File RelativePath="..\..\engines\kyra\sound_pcspk.cpp" />
- <File RelativePath="..\..\engines\kyra\sound_towns.cpp" />
- <File RelativePath="..\..\engines\kyra\sprites.cpp" />
- <File RelativePath="..\..\engines\kyra\sprites.h" />
- <File RelativePath="..\..\engines\kyra\sprites_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\staticres.cpp" />
- <File RelativePath="..\..\engines\kyra\text.cpp" />
- <File RelativePath="..\..\engines\kyra\text.h" />
- <File RelativePath="..\..\engines\kyra\text_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\text_hof.h" />
- <File RelativePath="..\..\engines\kyra\text_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\text_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\text_lol.h" />
- <File RelativePath="..\..\engines\kyra\text_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\text_mr.h" />
- <File RelativePath="..\..\engines\kyra\timer.cpp" />
- <File RelativePath="..\..\engines\kyra\timer.h" />
- <File RelativePath="..\..\engines\kyra\timer_hof.cpp" />
- <File RelativePath="..\..\engines\kyra\timer_lok.cpp" />
- <File RelativePath="..\..\engines\kyra\timer_lol.cpp" />
- <File RelativePath="..\..\engines\kyra\timer_mr.cpp" />
- <File RelativePath="..\..\engines\kyra\util.cpp" />
- <File RelativePath="..\..\engines\kyra\util.h" />
- <File RelativePath="..\..\engines\kyra\vqa.cpp" />
- <File RelativePath="..\..\engines\kyra\vqa.h" />
- <File RelativePath="..\..\engines\kyra\wsamovie.cpp" />
- <File RelativePath="..\..\engines\kyra\wsamovie.h" />
+ <File
+ RelativePath="..\..\engines\kyra\animator_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\animator_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\animator_lok.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\animator_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\animator_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\debugger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\debugger.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\detection.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_hof.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_lok.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_lol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_mr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\gui_v2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\items_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\items_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\items_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\items_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\items_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_hof.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_lok.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_mr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_v1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_v1.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\kyra_v2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\lol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\resource.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\resource_intern.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\resource_intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\saveload.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\saveload_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\saveload_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\saveload_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\saveload_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\scene_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\scene_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\scene_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\scene_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\scene_v1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\scene_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_hof.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_lok.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_lol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_mr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\screen_v2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_tim.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_tim.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_v1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\script_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\seqplayer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\seqplayer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sequences_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sequences_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sequences_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sequences_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sequences_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_adlib.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_amiga.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_digital.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_midi.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_pcspk.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sound_towns.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sprites.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sprites.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\sprites_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\staticres.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_hof.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_lol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\text_mr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\timer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\timer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\timer_hof.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\timer_lok.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\timer_lol.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\timer_mr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\util.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\vqa.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\vqa.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\wsamovie.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\kyra\wsamovie.h"
+ >
+ </File>
</Files>
+ <Globals>
+ </Globals>
</VisualStudioProject>
diff --git a/dists/msvc9/scumm.vcproj b/dists/msvc9/scumm.vcproj
index c2c116ef8b..9176461d8c 100644
--- a/dists/msvc9/scumm.vcproj
+++ b/dists/msvc9/scumm.vcproj
@@ -9,186 +9,800 @@
TargetFrameworkVersion="131072"
>
<Platforms>
- <Platform Name="Win32" />
+ <Platform
+ Name="Win32"
+ />
</Platforms>
+ <ToolFiles>
+ </ToolFiles>
<Configurations>
- <Configuration Name="Debug|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Debug.vsprops" />
- <Configuration Name="Release|Win32" ConfigurationType="4" InheritedPropertySheets=".\ScummVM_Release.vsprops" />
-
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\ScummVM_Debug.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets=".\ScummVM_Release.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
+ <References>
+ </References>
<Files>
- <Filter Name="smush">
- <File RelativePath="..\..\engines\scumm\smush\channel.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\channel.h" />
- <File RelativePath="..\..\engines\scumm\smush\chunk_type.h" />
- <File RelativePath="..\..\engines\scumm\smush\codec1.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\codec37.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\codec37.h" />
- <File RelativePath="..\..\engines\scumm\smush\codec47.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\codec47.h" />
- <File RelativePath="..\..\engines\scumm\smush\imuse_channel.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\saud_channel.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\smush_font.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\smush_font.h" />
- <File RelativePath="..\..\engines\scumm\smush\smush_mixer.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\smush_mixer.h" />
- <File RelativePath="..\..\engines\scumm\smush\smush_player.cpp" />
- <File RelativePath="..\..\engines\scumm\smush\smush_player.h" />
+ <Filter
+ Name="smush"
+ >
+ <File
+ RelativePath="..\..\engines\scumm\smush\channel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\channel.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\chunk_type.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\codec1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\codec37.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\codec37.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\codec47.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\codec47.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\imuse_channel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\saud_channel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\smush_font.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\smush_font.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\smush_mixer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\smush_mixer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\smush_player.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\smush\smush_player.h"
+ >
+ </File>
</Filter>
- <Filter Name="imuse_digi">
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse.h" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_bndmgr.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_bndmgr.h" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_codecs.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_music.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_script.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_sndmgr.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_sndmgr.h" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_tables.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_tables.h" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.h" />
+ <Filter
+ Name="imuse_digi"
+ >
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_bndmgr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_bndmgr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_codecs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_music.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_script.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_sndmgr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_sndmgr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_tables.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_tables.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse_digi\dimuse_track.h"
+ >
+ </File>
</Filter>
- <Filter Name="insane">
- <File RelativePath="..\..\engines\scumm\insane\insane.cpp" />
- <File RelativePath="..\..\engines\scumm\insane\insane.h" />
- <File RelativePath="..\..\engines\scumm\insane\insane_ben.cpp" />
- <File RelativePath="..\..\engines\scumm\insane\insane_enemy.cpp" />
- <File RelativePath="..\..\engines\scumm\insane\insane_iact.cpp" />
- <File RelativePath="..\..\engines\scumm\insane\insane_scenes.cpp" />
+ <Filter
+ Name="insane"
+ >
+ <File
+ RelativePath="..\..\engines\scumm\insane\insane.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\insane\insane.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\insane\insane_ben.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\insane\insane_enemy.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\insane\insane_iact.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\insane\insane_scenes.cpp"
+ >
+ </File>
</Filter>
- <Filter Name="he">
- <File RelativePath="..\..\engines\scumm\he\animation_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\animation_he.h" />
- <File RelativePath="..\..\engines\scumm\he\cup_player_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\cup_player_he.h" />
- <File RelativePath="..\..\engines\scumm\he\floodfill_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\floodfill_he.h" />
- <File RelativePath="..\..\engines\scumm\he\intern_he.h" />
- <File RelativePath="..\..\engines\scumm\he\logic_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\logic_he.h" />
- <File RelativePath="..\..\engines\scumm\he\palette_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\resource_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\resource_he.h" />
- <File RelativePath="..\..\engines\scumm\he\script_v100he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\script_v60he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\script_v70he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\script_v71he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\script_v72he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\script_v80he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\script_v90he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\sound_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\sound_he.h" />
- <File RelativePath="..\..\engines\scumm\he\sprite_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\sprite_he.h" />
- <File RelativePath="..\..\engines\scumm\he\wiz_he.cpp" />
- <File RelativePath="..\..\engines\scumm\he\wiz_he.h" />
+ <Filter
+ Name="he"
+ >
+ <File
+ RelativePath="..\..\engines\scumm\he\animation_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\animation_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\cup_player_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\cup_player_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\floodfill_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\floodfill_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\intern_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\logic_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\logic_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\palette_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\resource_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\resource_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v100he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v60he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v70he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v71he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v72he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v80he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\script_v90he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\sound_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\sound_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\sprite_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\sprite_he.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\wiz_he.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\he\wiz_he.h"
+ >
+ </File>
</Filter>
- <Filter Name="imuse">
- <File RelativePath="..\..\engines\scumm\imuse\imuse.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse\imuse.h" />
- <File RelativePath="..\..\engines\scumm\imuse\imuse_internal.h" />
- <File RelativePath="..\..\engines\scumm\imuse\imuse_part.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse\imuse_player.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse\instrument.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse\instrument.h" />
- <File RelativePath="..\..\engines\scumm\imuse\sysex.h" />
- <File RelativePath="..\..\engines\scumm\imuse\sysex_samnmax.cpp" />
- <File RelativePath="..\..\engines\scumm\imuse\sysex_scumm.cpp" />
+ <Filter
+ Name="imuse"
+ >
+ <File
+ RelativePath="..\..\engines\scumm\imuse\imuse.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\imuse.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\imuse_internal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\imuse_part.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\imuse_player.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\instrument.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\instrument.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\sysex.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\sysex_samnmax.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\imuse\sysex_scumm.cpp"
+ >
+ </File>
</Filter>
- <File RelativePath="..\..\engines\scumm\actor.cpp" />
- <File RelativePath="..\..\engines\scumm\actor.h" />
- <File RelativePath="..\..\engines\scumm\akos.cpp" />
- <File RelativePath="..\..\engines\scumm\akos.h" />
- <File RelativePath="..\..\engines\scumm\base-costume.cpp" />
- <File RelativePath="..\..\engines\scumm\base-costume.h" />
- <File RelativePath="..\..\engines\scumm\bomp.cpp" />
- <File RelativePath="..\..\engines\scumm\bomp.h" />
- <File RelativePath="..\..\engines\scumm\boxes.cpp" />
- <File RelativePath="..\..\engines\scumm\boxes.h" />
- <File RelativePath="..\..\engines\scumm\camera.cpp" />
- <File RelativePath="..\..\engines\scumm\charset-fontdata.cpp" />
- <File RelativePath="..\..\engines\scumm\charset.cpp" />
- <File RelativePath="..\..\engines\scumm\charset.h" />
- <File RelativePath="..\..\engines\scumm\costume.cpp" />
- <File RelativePath="..\..\engines\scumm\costume.h" />
- <File RelativePath="..\..\engines\scumm\cursor.cpp" />
- <File RelativePath="..\..\engines\scumm\debugger.cpp" />
- <File RelativePath="..\..\engines\scumm\debugger.h" />
- <File RelativePath="..\..\engines\scumm\detection.cpp" />
- <File RelativePath="..\..\engines\scumm\detection.h" />
- <File RelativePath="..\..\engines\scumm\detection_tables.h" />
- <File RelativePath="..\..\engines\scumm\dialogs.cpp" />
- <File RelativePath="..\..\engines\scumm\dialogs.h" />
- <File RelativePath="..\..\engines\scumm\file.cpp" />
- <File RelativePath="..\..\engines\scumm\file.h" />
- <File RelativePath="..\..\engines\scumm\file_nes.cpp" />
- <File RelativePath="..\..\engines\scumm\file_nes.h" />
- <File RelativePath="..\..\engines\scumm\gfx.cpp" />
- <File RelativePath="..\..\engines\scumm\gfx.h" />
- <File RelativePath="..\..\engines\scumm\help.cpp" />
- <File RelativePath="..\..\engines\scumm\help.h" />
- <File RelativePath="..\..\engines\scumm\input.cpp" />
- <File RelativePath="..\..\engines\scumm\intern.h" />
- <File RelativePath="..\..\engines\scumm\midiparser_eup.cpp" />
- <File RelativePath="..\..\engines\scumm\midiparser_ro.cpp" />
- <File RelativePath="..\..\engines\scumm\music.h" />
- <File RelativePath="..\..\engines\scumm\nut_renderer.cpp" />
- <File RelativePath="..\..\engines\scumm\nut_renderer.h" />
- <File RelativePath="..\..\engines\scumm\object.cpp" />
- <File RelativePath="..\..\engines\scumm\object.h" />
- <File RelativePath="..\..\engines\scumm\palette.cpp" />
- <File RelativePath="..\..\engines\scumm\player_mod.cpp" />
- <File RelativePath="..\..\engines\scumm\player_mod.h" />
- <File RelativePath="..\..\engines\scumm\player_nes.cpp" />
- <File RelativePath="..\..\engines\scumm\player_nes.h" />
- <File RelativePath="..\..\engines\scumm\player_v1.cpp" />
- <File RelativePath="..\..\engines\scumm\player_v1.h" />
- <File RelativePath="..\..\engines\scumm\player_v2.cpp" />
- <File RelativePath="..\..\engines\scumm\player_v2.h" />
- <File RelativePath="..\..\engines\scumm\player_v2a.cpp" />
- <File RelativePath="..\..\engines\scumm\player_v2a.h" />
- <File RelativePath="..\..\engines\scumm\player_v2cms.cpp" />
- <File RelativePath="..\..\engines\scumm\player_v3a.cpp" />
- <File RelativePath="..\..\engines\scumm\player_v3a.h" />
- <File RelativePath="..\..\engines\scumm\resource.cpp" />
- <File RelativePath="..\..\engines\scumm\resource.h" />
- <File RelativePath="..\..\engines\scumm\resource_v2.cpp" />
- <File RelativePath="..\..\engines\scumm\resource_v3.cpp" />
- <File RelativePath="..\..\engines\scumm\resource_v4.cpp" />
- <File RelativePath="..\..\engines\scumm\room.cpp" />
- <File RelativePath="..\..\engines\scumm\saveload.cpp" />
- <File RelativePath="..\..\engines\scumm\saveload.h" />
- <File RelativePath="..\..\engines\scumm\script.cpp" />
- <File RelativePath="..\..\engines\scumm\script.h" />
- <File RelativePath="..\..\engines\scumm\script_v0.cpp" />
- <File RelativePath="..\..\engines\scumm\script_v2.cpp" />
- <File RelativePath="..\..\engines\scumm\script_v3.cpp" />
- <File RelativePath="..\..\engines\scumm\script_v4.cpp" />
- <File RelativePath="..\..\engines\scumm\script_v5.cpp" />
- <File RelativePath="..\..\engines\scumm\script_v6.cpp" />
- <File RelativePath="..\..\engines\scumm\script_v8.cpp" />
- <File RelativePath="..\..\engines\scumm\scumm-md5.h" />
- <File RelativePath="..\..\engines\scumm\scumm.cpp" />
- <File RelativePath="..\..\engines\scumm\scumm.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v0.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v2.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v3.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v4.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v5.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v6.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v7.h" />
- <File RelativePath="..\..\engines\scumm\scumm_v8.h" />
- <File RelativePath="..\..\engines\scumm\sound.cpp" />
- <File RelativePath="..\..\engines\scumm\sound.h" />
- <File RelativePath="..\..\engines\scumm\string.cpp" />
- <File RelativePath="..\..\engines\scumm\usage_bits.cpp" />
- <File RelativePath="..\..\engines\scumm\usage_bits.h" />
- <File RelativePath="..\..\engines\scumm\util.cpp" />
- <File RelativePath="..\..\engines\scumm\util.h" />
- <File RelativePath="..\..\engines\scumm\vars.cpp" />
- <File RelativePath="..\..\engines\scumm\verbs.cpp" />
- <File RelativePath="..\..\engines\scumm\verbs.h" />
+ <File
+ RelativePath="..\..\engines\scumm\actor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\actor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\akos.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\akos.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\base-costume.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\base-costume.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\bomp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\bomp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\boxes.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\boxes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\camera.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\charset-fontdata.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\charset.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\charset.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\costume.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\costume.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\cursor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\debugger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\debugger.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\detection.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\detection.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\detection_tables.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\dialogs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\dialogs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\file.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\file_nes.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\file_nes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\gfx.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\gfx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\help.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\help.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\input.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\intern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\midiparser_eup.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\midiparser_ro.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\music.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\nut_renderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\nut_renderer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\object.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\object.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\palette.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_mod.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_mod.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_nes.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_nes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v1.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v2a.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v2a.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v2cms.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v3a.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v3a.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v4a.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\player_v4a.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\resource.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\resource_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\resource_v3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\resource_v4.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\room.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\saveload.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\saveload.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v0.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v4.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v5.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v6.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\script_v8.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm-md5.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v0.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v2.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v4.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v5.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v6.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v7.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\scumm_v8.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\sound.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\sound.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\string.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\usage_bits.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\usage_bits.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\util.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\util.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\vars.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\verbs.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\scumm\verbs.h"
+ >
+ </File>
</Files>
+ <Globals>
+ </Globals>
</VisualStudioProject>
diff --git a/dists/msvc9/scummvm-tfmx.sln b/dists/msvc9/scummvm-tfmx.sln
new file mode 100644
index 0000000000..208703fc17
--- /dev/null
+++ b/dists/msvc9/scummvm-tfmx.sln
@@ -0,0 +1,48 @@
+
+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}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF} = {B6AFD548-63D2-40CD-A652-E87095AFCBAF}
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC} = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scumm", "scumm.vcproj", "{B6AFD548-63D2-40CD-A652-E87095AFCBAF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kyra", "kyra.vcproj", "{9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_Command|Win32 = Debug_Command|Win32
+ Debug|Win32 = Debug|Win32
+ Release_Command|Win32 = Release_Command|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.Debug_Command|Win32.ActiveCfg = Debug_Command|Win32
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.Debug_Command|Win32.Build.0 = Debug_Command|Win32
+ {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_Command|Win32.ActiveCfg = Release_Command|Win32
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.Release_Command|Win32.Build.0 = Release_Command|Win32
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.Release|Win32.ActiveCfg = Release|Win32
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.Release|Win32.Build.0 = Release|Win32
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF}.Debug_Command|Win32.ActiveCfg = Debug|Win32
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF}.Debug|Win32.Build.0 = Debug|Win32
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF}.Release_Command|Win32.ActiveCfg = Release|Win32
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF}.Release|Win32.ActiveCfg = Release|Win32
+ {B6AFD548-63D2-40CD-A652-E87095AFCBAF}.Release|Win32.Build.0 = Release|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Debug_Command|Win32.ActiveCfg = Debug|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Debug_Command|Win32.Build.0 = Debug|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Debug|Win32.Build.0 = Debug|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Release_Command|Win32.ActiveCfg = Release|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Release_Command|Win32.Build.0 = Release|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Release|Win32.ActiveCfg = Release|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/dists/msvc9/scummvm-tfmx.vcproj b/dists/msvc9/scummvm-tfmx.vcproj
new file mode 100644
index 0000000000..def94c898e
--- /dev/null
+++ b/dists/msvc9/scummvm-tfmx.vcproj
@@ -0,0 +1,2018 @@
+<?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"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\ScummVM_Debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="0"
+ UsePrecompiledHeader="0"
+ SuppressStartupBanner="false"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4512"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib"
+ OutputFile="$(OutDir)\$(ProjectName)-tfmx.exe"
+ ProgramDatabaseFile="$(OutDir)/scummvm.pdb"
+ />
+ <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"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\ScummVM_Release.vsprops"
+ 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"
+ OmitFramePointers="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;ENABLE_SCUMM;ENABLE_LOL;USE_ZLIB"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winmm.lib sdl.lib zlib.lib"
+ OutputFile="$(OutDir)\$(ProjectName)-tfmx.exe"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="false"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug_Command|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\ScummVM_Debug.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NOT_TFMX_CMDLINE_TOOL;MXTX_CMDLINE_TOOL"
+ UsePrecompiledHeader="0"
+ SuppressStartupBanner="false"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4512"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib"
+ OutputFile="$(OutDir)\$(ProjectName)-tfmx.exe"
+ ProgramDatabaseFile="$(OutDir)/scummvm.pdb"
+ />
+ <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_Command|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\ScummVM_Release.vsprops"
+ 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"
+ OmitFramePointers="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;TFMX_CMDLINE_TOOL"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ AdditionalDependencies="winmm.lib sdl.lib"
+ OutputFile="$(OutDir)\$(ProjectName)-tfmx.exe"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="false"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ />
+ <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_sound.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sound\iff_sound.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>
+ <FileConfiguration
+ Name="Debug_Command|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)/$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Command|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>
+ <FileConfiguration
+ Name="Debug_Command|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)/$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Command|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>
+ <FileConfiguration
+ Name="Debug_Command|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)/$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)/$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Command|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\maxtrax.cpp"
+ >
+ <FileConfiguration
+ Name="Debug_Command|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Command|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\sound\mods\maxtrax.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"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AssemblerOutput="2"
+ />
+ </FileConfiguration>
+ </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>
+ <FileConfiguration
+ Name="Debug_Command|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Command|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>
+ <FileConfiguration
+ Name="Debug_Command|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\sjis.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\sjis.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>
+ <FileConfiguration
+ Name="Debug_Command|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_Command|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>
+ <FileConfiguration
+ Name="Debug_Command|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_Command|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\mxtxplayer.cpp"
+ >
+ </File>
+ <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>
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index 258d0c402f..186b270e58 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -113,6 +113,8 @@ Common::Error KyraEngine_v1::init() {
_sound = new SoundPC98(this, _mixer);
else
_sound = new SoundTownsPC98_v2(this, _mixer);
+ } else if (_flags.platform == Common::kPlatformAmiga) {
+ _sound = new SoundAmiga(this, _mixer);
} else if (midiDriver == MD_ADLIB) {
_sound = new SoundAdlibPC(this, _mixer);
} else {
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index 7b0c0dfb68..b484fa345f 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -50,6 +50,7 @@ MODULE_OBJS := \
sequences_hof.o \
sequences_mr.o \
sound_adlib.o \
+ sound_amiga.o \
sound_digital.o \
sound_midi.o \
sound_pcspk.o \
diff --git a/engines/kyra/sound_amiga.cpp b/engines/kyra/sound_amiga.cpp
new file mode 100644
index 0000000000..985afa2d32
--- /dev/null
+++ b/engines/kyra/sound_amiga.cpp
@@ -0,0 +1,101 @@
+/* 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/system.h"
+#include "common/mutex.h"
+#include "kyra/resource.h"
+#include "kyra/sound_intern.h"
+
+#include "sound/mixer.h"
+#include "sound/mods/maxtrax.h"
+#include "sound/audiostream.h"
+
+namespace Kyra {
+
+const char *const SoundAmiga::kFilenameTable[3][2] = {
+ { "introscr.mx", "introinst.mx" },
+ { "kyramusic.mx", 0 },
+ { "finalescr.mx", 0 }
+};
+
+SoundAmiga::SoundAmiga(KyraEngine_v1 *vm, Audio::Mixer *mixer) :
+ Sound(vm, mixer), _driver(0), _fileLoaded(-1) {
+}
+
+SoundAmiga::~SoundAmiga() {
+ delete _driver;
+}
+
+bool SoundAmiga::init() {
+ _driver = new Audio::MaxTrax(_mixer->getOutputRate(), true);
+
+ return _driver != 0;
+}
+
+void SoundAmiga::loadSoundFile(uint file) {
+ assert(file < ARRAYSIZE(kFilenameTable));
+
+ if (_fileLoaded == file)
+ return;
+
+ Common::SeekableReadStream *scoreIn = _vm->resource()->createReadStream(kFilenameTable[file][0]);
+ if (kFilenameTable[file][1]) {
+ Common::SeekableReadStream *sampleIn = _vm->resource()->createReadStream(kFilenameTable[file][1]);
+ if (scoreIn && sampleIn) {
+ _driver->load(*scoreIn, true, false);
+ _driver->load(*sampleIn, false, true);
+ _fileLoaded = file;
+ }
+ delete sampleIn;
+ } else {
+ if (scoreIn) {
+ _driver->load(*scoreIn);
+ _fileLoaded = file;
+ }
+ }
+ delete scoreIn;
+}
+void SoundAmiga::loadSoundFile(Common::String) {
+ assert("Dont call me" == 0);
+}
+
+void SoundAmiga::playTrack(uint8 track) {
+ _driver->doSong(track - 2);
+ if (!_mixer->isSoundHandleActive(_soundChannels[0]))
+ _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_soundChannels[0], _driver);
+}
+
+void SoundAmiga::haltTrack() {
+
+}
+
+void SoundAmiga::beginFadeOut() {
+
+}
+
+void SoundAmiga::playSoundEffect(uint8 track) {
+ assert("Dont call me" == 0);
+}
+} // end of namespace Kyra \ No newline at end of file
diff --git a/engines/kyra/sound_intern.h b/engines/kyra/sound_intern.h
index 975672b76a..792887ab35 100644
--- a/engines/kyra/sound_intern.h
+++ b/engines/kyra/sound_intern.h
@@ -37,6 +37,7 @@
namespace Audio {
class PCSpeaker;
+class MaxTrax;
} // end of namespace Audio
namespace Kyra {
@@ -284,6 +285,33 @@ private:
static const uint8 _noteTable2[];
};
+class SoundAmiga : public Sound {
+public:
+ SoundAmiga(KyraEngine_v1 *vm, Audio::Mixer *mixer);
+ ~SoundAmiga();
+
+ virtual kType getMusicType() const { return kPC98; } //FIXME
+
+ bool init();
+
+ void process() {}
+ void loadSoundFile(uint file);
+ void loadSoundFile(Common::String);
+
+ void playTrack(uint8 track);
+ void haltTrack();
+ void beginFadeOut();
+
+ int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, bool isSfx) { return -1; }
+ void playSoundEffect(uint8);
+
+protected:
+ Audio::MaxTrax *_driver;
+ uint _fileLoaded;
+
+ static const char *const kFilenameTable[3][2];
+};
+
} // end of namespace Kyra
#endif
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 58d8db91fc..51fbecdb0d 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -40,6 +40,7 @@ MODULE_OBJS := \
player_v2a.o \
player_v2cms.o \
player_v3a.o \
+ player_v4a.o \
resource_v2.o \
resource_v3.o \
resource_v4.o \
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index c356e7a06c..6adf5c524e 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -70,121 +70,80 @@ void ScummEngine::resetPalette() {
else
setEGAPalette();
}
+ } else if ((_game.platform == Common::kPlatformAmiga) && _game.version == 4) {
+ // if rendermode is set to EGA we use the full palette from the resources
+ // else we initialise and then lock down the first 16 colors.
+ if (_renderMode != Common::kRenderEGA)
+ setAmigaMIPalette();
} else
setDirtyColors(0, 255);
}
-void ScummEngine::setC64Palette() {
- setPalColor( 0, 0x00, 0x00, 0x00);
- setPalColor( 1, 0xFD, 0xFE, 0xFC);
- setPalColor( 2, 0xBE, 0x1A, 0x24);
- setPalColor( 3, 0x30, 0xE6, 0xC6);
- setPalColor( 4, 0xB4, 0x1A, 0xE2);
- setPalColor( 5, 0x1F, 0xD2, 0x1E);
- setPalColor( 6, 0x21, 0x1B, 0xAE);
- setPalColor( 7, 0xDF, 0xF6, 0x0A);
- setPalColor( 8, 0xB8, 0x41, 0x04);
- setPalColor( 9, 0x6A, 0x33, 0x04);
- setPalColor(10, 0xFE, 0x4A, 0x57);
- setPalColor(11, 0x42, 0x45, 0x40);
- setPalColor(12, 0x70, 0x74, 0x6F);
- setPalColor(13, 0x59, 0xFE, 0x59);
- setPalColor(14, 0x5F, 0x53, 0xFE);
- setPalColor(15, 0xA4, 0xA7, 0xA2);
+void ScummEngine::setHardcodedPaletteRGB(const byte *ptr, int numcolor, int index) {
+ for ( ; numcolor > 0; --numcolor, ++index, ptr += 3)
+ setPalColor( index, ptr[0], ptr[1], ptr[2]);
+}
+void ScummEngine::setC64Palette() {
// Use 17 color table for v1 games to allow correct color for inventory and
// sentence line. Original games used some kind of dynamic color table
// remapping between rooms.
- setPalColor(16, 255, 85, 255);
+ static const byte ctable[] = {
+ 0x00, 0x00, 0x00, 0xFD, 0xFE, 0xFC, 0xBE, 0x1A, 0x24, 0x30, 0xE6, 0xC6,
+ 0xB4, 0x1A, 0xE2, 0x1F, 0xD2, 0x1E, 0x21, 0x1B, 0xAE, 0xDF, 0xF6, 0x0A,
+ 0xB8, 0x41, 0x04, 0x6A, 0x33, 0x04, 0xFE, 0x4A, 0x57, 0x42, 0x45, 0x40,
+ 0x70, 0x74, 0x6F, 0x59, 0xFE, 0x59, 0x5F, 0x53, 0xFE, 0xA4, 0xA7, 0xA2,
+
+ 0xFF, 0x55, 0xFF
+ };
+ setHardcodedPaletteRGB(ctable, ARRAYSIZE(ctable) / 3);
}
void ScummEngine::setNESPalette() {
- setPalColor(0x00,0x00,0x00,0x00); // 0x1D
- setPalColor(0x01,0x00,0x24,0x92);
- setPalColor(0x02,0x00,0x00,0xDB);
- setPalColor(0x03,0x6D,0x49,0xDB);
- setPalColor(0x04,0x92,0x00,0x6D);
- setPalColor(0x05,0xB6,0x00,0x6D);
- setPalColor(0x06,0xB6,0x24,0x00);
- setPalColor(0x07,0x92,0x49,0x00);
- setPalColor(0x08,0x6D,0x49,0x00);
- setPalColor(0x09,0x24,0x49,0x00);
- setPalColor(0x0A,0x00,0x6D,0x24);
- setPalColor(0x0B,0x00,0x92,0x00);
- setPalColor(0x0C,0x00,0x49,0x49);
- setPalColor(0x0D,0x00,0x00,0x00);
- setPalColor(0x0E,0x00,0x00,0x00);
- setPalColor(0x0F,0x00,0x00,0x00);
-
- setPalColor(0x10,0xB6,0xB6,0xB6);
- setPalColor(0x11,0x00,0x6D,0xDB);
- setPalColor(0x12,0x00,0x49,0xFF);
- setPalColor(0x13,0x92,0x00,0xFF);
- setPalColor(0x14,0xB6,0x00,0xFF);
- setPalColor(0x15,0xFF,0x00,0x92);
- setPalColor(0x16,0xFF,0x00,0x00);
- setPalColor(0x17,0xDB,0x6D,0x00);
- setPalColor(0x18,0x92,0x6D,0x00);
- setPalColor(0x19,0x24,0x92,0x00);
- setPalColor(0x1A,0x00,0x92,0x00);
- setPalColor(0x1B,0x00,0xB6,0x6D);
- setPalColor(0x1C,0x00,0x92,0x92);
- setPalColor(0x1D,0x6D,0x6D,0x6D); // 0x00
- setPalColor(0x1E,0x00,0x00,0x00);
- setPalColor(0x1F,0x00,0x00,0x00);
-
- setPalColor(0x20,0xFF,0xFF,0xFF);
- setPalColor(0x21,0x6D,0xB6,0xFF);
- setPalColor(0x22,0x92,0x92,0xFF);
- setPalColor(0x23,0xDB,0x6D,0xFF);
- setPalColor(0x24,0xFF,0x00,0xFF);
- setPalColor(0x25,0xFF,0x6D,0xFF);
- setPalColor(0x26,0xFF,0x92,0x00);
- setPalColor(0x27,0xFF,0xB6,0x00);
- setPalColor(0x28,0xDB,0xDB,0x00);
- setPalColor(0x29,0x6D,0xDB,0x00);
- setPalColor(0x2A,0x00,0xFF,0x00);
- setPalColor(0x2B,0x49,0xFF,0xDB);
- setPalColor(0x2C,0x00,0xFF,0xFF);
- setPalColor(0x2D,0x49,0x49,0x49);
- setPalColor(0x2E,0x00,0x00,0x00);
- setPalColor(0x2F,0x00,0x00,0x00);
-
- setPalColor(0x30,0xFF,0xFF,0xFF);
- setPalColor(0x31,0xB6,0xDB,0xFF);
- setPalColor(0x32,0xDB,0xB6,0xFF);
- setPalColor(0x33,0xFF,0xB6,0xFF);
- setPalColor(0x34,0xFF,0x92,0xFF);
- setPalColor(0x35,0xFF,0xB6,0xB6);
- setPalColor(0x36,0xFF,0xDB,0x92);
- setPalColor(0x37,0xFF,0xFF,0x49);
- setPalColor(0x38,0xFF,0xFF,0x6D);
- setPalColor(0x39,0xB6,0xFF,0x49);
- setPalColor(0x3A,0x92,0xFF,0x6D);
- setPalColor(0x3B,0x49,0xFF,0xDB);
- setPalColor(0x3C,0x92,0xDB,0xFF);
- setPalColor(0x3D,0x92,0x92,0x92);
- setPalColor(0x3E,0x00,0x00,0x00);
- setPalColor(0x3F,0x00,0x00,0x00);
+ static const byte ctable[] = {
+ /* 0x1D */
+ 0x00, 0x00, 0x00, 0x00, 0x24, 0x92, 0x00, 0x00, 0xDB, 0x6D, 0x49, 0xDB,
+ 0x92, 0x00, 0x6D, 0xB6, 0x00, 0x6D, 0xB6, 0x24, 0x00, 0x92, 0x49, 0x00,
+ 0x6D, 0x49, 0x00, 0x24, 0x49, 0x00, 0x00, 0x6D, 0x24, 0x00, 0x92, 0x00,
+ 0x00, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0xB6, 0xB6, 0xB6, 0x00, 0x6D, 0xDB, 0x00, 0x49, 0xFF, 0x92, 0x00, 0xFF,
+ 0xB6, 0x00, 0xFF, 0xFF, 0x00, 0x92, 0xFF, 0x00, 0x00, 0xDB, 0x6D, 0x00,
+ 0x92, 0x6D, 0x00, 0x24, 0x92, 0x00, 0x00, 0x92, 0x00, 0x00, 0xB6, 0x6D,
+ /* 0x00 */
+ 0x00, 0x92, 0x92, 0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0xFF, 0xFF, 0xFF, 0x6D, 0xB6, 0xFF, 0x92, 0x92, 0xFF, 0xDB, 0x6D, 0xFF,
+ 0xFF, 0x00, 0xFF, 0xFF, 0x6D, 0xFF, 0xFF, 0x92, 0x00, 0xFF, 0xB6, 0x00,
+ 0xDB, 0xDB, 0x00, 0x6D, 0xDB, 0x00, 0x00, 0xFF, 0x00, 0x49, 0xFF, 0xDB,
+ 0x00, 0xFF, 0xFF, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0xFF, 0xFF, 0xFF, 0xB6, 0xDB, 0xFF, 0xDB, 0xB6, 0xFF, 0xFF, 0xB6, 0xFF,
+ 0xFF, 0x92, 0xFF, 0xFF, 0xB6, 0xB6, 0xFF, 0xDB, 0x92, 0xFF, 0xFF, 0x49,
+ 0xFF, 0xFF, 0x6D, 0xB6, 0xFF, 0x49, 0x92, 0xFF, 0x6D, 0x49, 0xFF, 0xDB,
+ 0x92, 0xDB, 0xFF, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ setHardcodedPaletteRGB(ctable, ARRAYSIZE(ctable) / 3);
}
void ScummEngine::setAmigaPalette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 0, 0, 187);
- setPalColor( 2, 0, 187, 0);
- setPalColor( 3, 0, 187, 187);
- setPalColor( 4, 187, 0, 0);
- setPalColor( 5, 187, 0, 187);
- setPalColor( 6, 187, 119, 0);
- setPalColor( 7, 187, 187, 187);
- setPalColor( 8, 119, 119, 119);
- setPalColor( 9, 119, 119, 255);
- setPalColor(10, 0, 255, 0);
- setPalColor(11, 0, 255, 255);
- setPalColor(12, 255, 136, 136);
- setPalColor(13, 255, 0, 255);
- setPalColor(14, 255, 255, 0);
- setPalColor(15, 255, 255, 255);
+ static const byte ctable[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0xBB, 0x00, 0x00, 0xBB, 0xBB,
+ 0xBB, 0x00, 0x00, 0xBB, 0x00, 0xBB, 0xBB, 0x77, 0x00, 0xBB, 0xBB, 0xBB,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x88, 0x88, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF
+ };
+ setHardcodedPaletteRGB(ctable, ARRAYSIZE(ctable) / 3);
+}
+
+void ScummEngine::setAmigaMIPalette() {
+ static const byte ctable[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x88, 0x22, 0x00, 0x66, 0x77,
+ 0xBB, 0x66, 0x66, 0xAA, 0x22, 0xAA, 0x88, 0x55, 0x22, 0x77, 0x77, 0x77,
+ 0x33, 0x33, 0x33, 0x22, 0x55, 0xDD, 0x22, 0xDD, 0x44, 0x00, 0xCC, 0xFF,
+ 0xFF, 0x99, 0x99, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF
+ };
+ setHardcodedPaletteRGB(ctable, ARRAYSIZE(ctable) / 3);
}
void ScummEngine::setHercPalette() {
@@ -214,50 +173,32 @@ void ScummEngine::setCGAPalette() {
}
void ScummEngine::setEGAPalette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 0, 0, 170);
- setPalColor( 2, 0, 170, 0);
- setPalColor( 3, 0, 170, 170);
- setPalColor( 4, 170, 0, 0);
- setPalColor( 5, 170, 0, 170);
- setPalColor( 6, 170, 85, 0);
- setPalColor( 7, 170, 170, 170);
- setPalColor( 8, 85, 85, 85);
- setPalColor( 9, 85, 85, 255);
- setPalColor(10, 85, 255, 85);
- setPalColor(11, 85, 255, 255);
- setPalColor(12, 255, 85, 85);
- setPalColor(13, 255, 85, 255);
- setPalColor(14, 255, 255, 85);
- setPalColor(15, 255, 255, 255);
+ static const byte ctable[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
+ 0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA,
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
+ 0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF
+ };
+ setHardcodedPaletteRGB(ctable, ARRAYSIZE(ctable) / 3);
}
void ScummEngine::setV1Palette() {
- setPalColor( 0, 0, 0, 0);
- setPalColor( 1, 255, 255, 255);
- setPalColor( 2, 170, 0, 0);
- setPalColor( 3, 0, 170, 170);
- setPalColor( 4, 170, 0, 170);
- setPalColor( 5, 0, 170, 0);
- setPalColor( 6, 0, 0, 170);
- setPalColor( 7, 255, 255, 85);
- setPalColor( 8, 255, 85, 85);
- setPalColor( 9, 170, 85, 0);
- setPalColor(10, 255, 85, 85);
- setPalColor(11, 85, 85, 85);
- setPalColor(12, 170, 170, 170);
- setPalColor(13, 85, 255, 85);
- setPalColor(14, 85, 85, 255);
+ static const byte ctable[] = {
+ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xAA,
+ 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xFF, 0xFF, 0x55,
+ 0xFF, 0x55, 0x55, 0xAA, 0x55, 0x00, 0xFF, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0xAA, 0xAA, 0xAA, 0x55, 0xFF, 0x55, 0x55, 0x55, 0xFF, 0x55, 0x55, 0x55,
+
+ 0xFF, 0x55, 0xFF
+ };
+ setHardcodedPaletteRGB(ctable, ARRAYSIZE(ctable) / 3);
if (_game.id == GID_ZAK)
setPalColor(15, 170, 170, 170);
- else
- setPalColor(15, 85, 85, 85);
-
- setPalColor(16, 255, 85, 255);
}
void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) {
+ int firstIndex = 0;
int i;
byte *dest, r, g, b;
@@ -277,7 +218,13 @@ void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) {
dest = _currentPalette;
- for (i = 0; i < numcolor; i++) {
+ if ((_game.platform == Common::kPlatformAmiga) && _game.version == 4 && _renderMode != Common::kRenderEGA) {
+ firstIndex = 16;
+ dest += 3 * 16;
+ ptr += 3 * 16;
+ }
+
+ for (i = firstIndex; i < numcolor; i++) {
r = *ptr++;
g = *ptr++;
b = *ptr++;
@@ -302,7 +249,7 @@ void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) {
memcpy(_darkenPalette, _currentPalette, 768);
}
- setDirtyColors(0, numcolor - 1);
+ setDirtyColors(firstIndex, numcolor - 1);
}
void ScummEngine::setDirtyColors(int min, int max) {
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/player_v4a.cpp
new file mode 100644
index 0000000000..7c3aab0462
--- /dev/null
+++ b/engines/scumm/player_v4a.cpp
@@ -0,0 +1,186 @@
+/* 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 "engines/engine.h"
+#include "scumm/player_v4a.h"
+#include "scumm/scumm.h"
+
+#include "common/file.h"
+
+namespace Scumm {
+
+Player_V4A::Player_V4A(ScummEngine *scumm, Audio::Mixer *mixer)
+ : _vm(scumm), _mixer(mixer), _musicId(), _sfxSlots(), _tfmxPlay(0), _tfmxSfx(0), _musicHandle(), _sfxHandle() {
+ init();
+}
+
+bool Player_V4A::init() {
+ if (_vm->_game.id != GID_MONKEY_VGA)
+ error("player_v4a - unknown game");
+
+ Common::File fileMdat;
+ Common::File fileSample;
+ bool mdatExists = fileMdat.open("music.dat");
+ bool sampleExists = fileSample.open("sample.dat");
+
+ if (mdatExists && sampleExists) {
+ Audio::Tfmx *play = new Audio::Tfmx(_mixer->getOutputRate(), true);
+ if (play->load(fileMdat, fileSample)) {
+ play->setSignalPtr(_signal);
+ _tfmxPlay = play;
+ } else
+ delete play;
+
+ play = new Audio::Tfmx(_mixer->getOutputRate(), true);
+ fileMdat.seek(0);
+ fileSample.seek(0);
+ if (play->load(fileMdat, fileSample)) {
+ _tfmxSfx = play;
+ } else
+ delete play;
+ }
+ return _tfmxPlay != 0;
+}
+
+Player_V4A::~Player_V4A() {
+ _mixer->stopHandle(_musicHandle);
+ _mixer->stopHandle(_sfxHandle);
+ delete _tfmxPlay;
+ delete _tfmxSfx;
+}
+
+void Player_V4A::setMusicVolume(int vol) {
+ debug(5, "player_v4a: setMusicVolume %i", vol);
+}
+
+void Player_V4A::stopAllSounds() {
+ debug(5, "player_v4a: stopAllSounds");
+ if (_tfmxPlay) {
+ _tfmxPlay->stopSong();
+ _signal[0] = 0;
+ }
+ _musicId = 0;
+ if (_tfmxSfx)
+ _tfmxSfx->stopSong();
+ clearSfxSlots();
+}
+
+void Player_V4A::stopSound(int nr) {
+ debug(5, "player_v4a: stopSound %d", nr);
+ if (nr == 0)
+ return;
+ if (nr == _musicId) {
+ _musicId = 0;
+ _tfmxPlay->stopSong();
+ _signal[0] = 0;
+ } else {
+ const int chan = getSfxChan(nr);
+ if (chan != -1) {
+ setSfxSlot(chan, 0);
+ _tfmxSfx->stopMacroEffect(chan);
+ }
+ }
+}
+
+void Player_V4A::startSound(int nr) {
+ assert(_vm);
+ const byte *ptr = _vm->getResourceAddress(rtSound, nr);
+ assert(ptr);
+
+ static const int8 monkeyCommands[52] = {
+ -1, -2, -3, -4, -5, -6, -7, -8,
+ -9, -10, -11, -12, -13, -14, 18, 17,
+ -17, -18, -19, -20, -21, -22, -23, -24,
+ -25, -26, -27, -28, -29, -30, -31, -32,
+ -33, 16, -35, 0, 1, 2, 3, 7,
+ 8, 10, 11, 4, 5, 14, 15, 12,
+ 6, 13, 9, 19
+ };
+
+ const int val = ptr[9];
+ if (val < 0 || val >= ARRAYSIZE(monkeyCommands)) {
+ warning("player_v4a: illegal Songnumber %i", val);
+ return;
+ }
+
+ if (!_tfmxSfx || !_tfmxPlay)
+ return;
+
+ int index = monkeyCommands[val];
+ const byte type = ptr[6];
+ if (index < 0) {
+ // SoundFX
+ index = -index - 1;
+ debug(3, "player_v4a: play %d: custom %i - %02X", nr, index, type);
+
+ if (_tfmxSfx->getSongIndex() < 0)
+ _tfmxSfx->doSong(0x18);
+ const int chan = _tfmxSfx->doSfx((uint16)index);
+ if (chan >= 0 && chan < ARRAYSIZE(_sfxSlots))
+ setSfxSlot(chan, nr, type);
+ else
+ warning("player_v4a: custom %i is not of required type", index);
+
+ if (!_mixer->isSoundHandleActive(_sfxHandle))
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _tfmxSfx, -1, Audio::Mixer::kMaxChannelVolume, 0, false);
+ } else {
+ // Song
+ debug(3, "player_v4a: play %d: song %i - %02X", nr, index, type);
+ if (ptr[6] != 0x7F)
+ warning("player_v4a: Song has wrong type");
+
+ _tfmxPlay->doSong(index);
+ _signal[0] = 2;
+ _musicId = nr;
+
+ if (!_mixer->isSoundHandleActive(_musicHandle))
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, _tfmxPlay, -1, Audio::Mixer::kMaxChannelVolume, 0, false);
+ }
+}
+
+int Player_V4A::getMusicTimer() const {
+ if (_musicId) {
+ // TODO: The titlesong is running with ~70 ticks per second and the scale seems to be based on that.
+ // Other songs dont and I have no clue if this scalevalue is anything close to correct for them.
+ // The Amiga-Game doesnt counts the ticks of the song, but has an own timer and I hope thespeed is constant through the game
+ const int magicScale = 357; // ~ 1000 * 25 * (10173 / 709379.0)
+ return (_mixer->getSoundElapsedTime(_musicHandle)) / magicScale;
+ }
+ return 0;
+}
+
+int Player_V4A::getSoundStatus(int nr) const {
+ bool a = nr == _musicId;
+ bool b = _tfmxPlay->getSongIndex() >= 0;
+ int c = _signal[0];
+
+ debug(5, "player_v4a: getSoundStatus music=%d, active=%d, signal=%d", a, b, c);
+ if (nr == _musicId)
+ return _signal[0];
+ return 0;
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/player_v4a.h b/engines/scumm/player_v4a.h
new file mode 100644
index 0000000000..3b454e9349
--- /dev/null
+++ b/engines/scumm/player_v4a.h
@@ -0,0 +1,96 @@
+/* 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 SCUMM_PLAYER_V4A_H
+#define SCUMM_PLAYER_V4A_H
+
+#include "common/scummsys.h"
+#include "scumm/music.h"
+#include "sound/mixer.h"
+#include "sound/mods/tfmx.h"
+
+class Mixer;
+
+namespace Scumm {
+
+class ScummEngine;
+
+/**
+ * Scumm V4 Amiga sound/music driver.
+ */
+class Player_V4A : public MusicEngine {
+public:
+ Player_V4A(ScummEngine *scumm, Audio::Mixer *mixer);
+ virtual ~Player_V4A();
+
+ virtual void setMusicVolume(int vol);
+ virtual void startSound(int sound);
+ virtual void stopSound(int sound);
+ virtual void stopAllSounds();
+ virtual int getMusicTimer() const;
+ virtual int getSoundStatus(int sound) const;
+
+private:
+ ScummEngine *_vm;
+
+ Audio::Tfmx *_tfmxPlay;
+ Audio::Tfmx *_tfmxSfx;
+ Audio::Mixer *_mixer;
+ Audio::SoundHandle _musicHandle;
+ Audio::SoundHandle _sfxHandle;
+
+ int _musicId;
+ uint16 _signal[4];
+
+ struct SfxChan {
+ int id;
+ byte type;
+ } _sfxSlots[4];
+
+ int getSfxChan(int id) const {
+ for (int i = 0; i < ARRAYSIZE(_sfxSlots); ++i)
+ if (_sfxSlots[i].id == id)
+ return i;
+ return -1;
+ }
+
+ void setSfxSlot(int channel, int id, byte type = 0) {
+ _sfxSlots[channel].id = id;
+ _sfxSlots[channel].type = type;
+ }
+
+ void clearSfxSlots() {
+ for (int i = 0; i < ARRAYSIZE(_sfxSlots); ++i){
+ _sfxSlots[i].id = 0;
+ _sfxSlots[i].type = 0;
+ }
+ }
+
+ bool init();
+};
+
+} // End of namespace Scumm
+
+#endif
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 42fbb590b3..b02c3b3346 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -55,6 +55,7 @@
#include "scumm/player_v2.h"
#include "scumm/player_v2a.h"
#include "scumm/player_v3a.h"
+#include "scumm/player_v4a.h"
#include "scumm/he/resource_he.h"
#include "scumm/scumm_v0.h"
#include "scumm/scumm_v8.h"
@@ -493,7 +494,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
case Common::kRenderCGA:
case Common::kRenderEGA:
case Common::kRenderAmiga:
- if ((_game.version >= 4 && !(_game.features & GF_16COLOR)) || (_game.features & GF_OLD256))
+ if ((_game.version >= 4 && !(_game.features & GF_16COLOR) && !(_game.platform == Common::kPlatformAmiga && _renderMode == Common::kRenderEGA))
+ || (_game.features & GF_OLD256))
_renderMode = Common::kRenderDefault;
break;
@@ -1670,7 +1672,7 @@ void ScummEngine::setupMusic(int midi) {
} else if (_game.platform == Common::kPlatformPCEngine && _game.version == 3) {
// TODO: Add support for music format
} else if (_game.platform == Common::kPlatformAmiga && _game.version <= 4) {
- // TODO: Add support for music format
+ _musicEngine = new Player_V4A(this, _mixer);
} else if (_game.id == GID_MANIAC && _game.version == 1) {
_musicEngine = new Player_V1(this, _mixer, midiDriver != MD_PCSPK);
} else if (_game.version <= 2) {
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 3d16bea2b1..143051c162 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1018,9 +1018,11 @@ protected:
const byte *getPalettePtr(int palindex, int room);
+ void setHardcodedPaletteRGB(const byte *ptr, int numcolor, int firstIndex = 0);
void setC64Palette();
void setNESPalette();
void setAmigaPalette();
+ void setAmigaMIPalette();
void setHercPalette();
void setCGAPalette();
void setEGAPalette();
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index ad48029bd2..2a681ffd62 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -440,26 +440,6 @@ void Sound::playSound(int soundID) {
if (_vm->_game.id == GID_MONKEY_VGA || _vm->_game.id == GID_MONKEY_EGA
|| (_vm->_game.id == GID_MONKEY && _vm->_game.platform == Common::kPlatformMacintosh)) {
- // Sound is currently not supported at all in the amiga versions of these games
- if (_vm->_game.platform == Common::kPlatformAmiga) {
- int track = -1;
- if (soundID == 50)
- track = 17;
- else if (ptr[6] == 0x7F && ptr[7] == 0x00 && ptr[8] == 0x80) {
- static const char tracks[16] = {13,14,10,3,4,9,16,5,1,8,2,15,6,7,11,12};
- if (ptr[9] == 0x0E)
- track = 18;
- else
- track = tracks[ptr[9] - 0x23];
- }
- if (track != -1) {
- playCDTrack(track,((track < 5) || (track > 16)) ? 1 : -1,0,0);
- stopCDTimer();
- _currentCDSound = soundID;
- }
- return;
- }
-
// Works around the fact that in some places in MonkeyEGA/VGA,
// the music is never explicitly stopped.
// Rather it seems that starting a new music is supposed to
diff --git a/sound/mods/maxtrax.cpp b/sound/mods/maxtrax.cpp
new file mode 100644
index 0000000000..686a74864e
--- /dev/null
+++ b/sound/mods/maxtrax.cpp
@@ -0,0 +1,717 @@
+/* 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/maxtrax.h"
+
+namespace Audio {
+
+MaxTrax::MaxTrax(int rate, bool stereo)
+ : Paula(stereo, rate, rate/50), _playerCtx(), _voiceCtx(), _patch(), _channelCtx(), _scores(), _numScores(), _microtonal() {
+ _playerCtx.maxScoreNum = 128;
+ _playerCtx.vBlankFreq = 50;
+ _playerCtx.frameUnit = (uint16)((1000 * (1<<8)) / _playerCtx.vBlankFreq);
+ _playerCtx.scoreIndex = -1;
+ // glob_CurrentScore = _scoreptr;
+ _playerCtx.volume = 0x64;
+
+ _playerCtx.tempoTime = 0;
+
+ uint32 uinqueId = 0;
+ byte flags = 0;
+
+ uint32 colorClock = kPalSystemClock / 2;
+
+ for (int i = 0; i < kNumChannels; ++i)
+ resetChannel(_channelCtx[i], (i & 1) != 0);
+
+ // init extraChannel
+ // extraChannel. chan_Number = 16, chan_Flags = chan_VoicesActive = 0
+}
+
+MaxTrax::~MaxTrax() {
+ stopMusic();
+ freePatches();
+ freeScores();
+}
+
+void MaxTrax::interrupt() {
+ // a5 - maxtraxm a4 . globaldata
+
+ // TODO
+ // test for changes in shared struct and make changes
+ // specifically all used channels get marked altered
+
+ _playerCtx.ticks += _playerCtx.tickUnit;
+ const int32 millis = _playerCtx.ticks >> 8; // d4
+ for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) {
+ VoiceContext &voice = _voiceCtx[i]; // a3
+ if (voice.channel && voice.stopEventCommand < 0x80) {
+ const int channelNo = voice.stopEventParameter;
+ assert(channelNo == voice.channel - _channelCtx); // TODO remove
+ voice.stopEventTime -= (channelNo < kNumChannels) ? _playerCtx.tickUnit : _playerCtx.frameUnit;
+ if (voice.stopEventTime <= 0) {
+ noteOff(voice, voice.stopEventCommand);
+ voice.stopEventCommand = 0xFF;
+ }
+ }
+ }
+
+ if (_playerCtx.musicPlaying) {
+ const Event *curEvent = _playerCtx.nextEvent;
+ int32 eventDelta = _playerCtx.nextEventTime - millis;
+ for (; eventDelta <= 0; eventDelta += (++curEvent)->startTime) {
+ const byte cmd = curEvent->command;
+ const byte data = curEvent->parameter;
+ const uint16 stopTime = curEvent->stopTime;
+ ChannelContext &channel = _channelCtx[data & 0x0F];
+
+ outPutEvent(*curEvent);
+ debug("CurTime, EventDelta, NextDelta: %d, %d, %d", millis, eventDelta, eventDelta + curEvent[1].startTime );
+
+ if (cmd < 0x80) { // Note
+ const uint16 vol = (data & 0xF0) >> 1;
+ const int8 voiceIndex = noteOn(channel, cmd, vol, kPriorityScore);
+ if (voiceIndex >= 0) {
+ VoiceContext &voice = _voiceCtx[voiceIndex];
+ voice.stopEventCommand = cmd;
+ voice.stopEventParameter = data & 0x0F;
+ voice.stopEventTime = (eventDelta + stopTime) << 8;
+ }
+
+ } else {
+ switch (cmd) {
+
+ case 0x80: // TEMPO
+ if ((_playerCtx.tickUnit >> 8) > stopTime) {
+ setTempo(data << 4);
+ _playerCtx.tempoTime = 0;
+ } else {
+ _playerCtx.tempoStart = _playerCtx.tempo;
+ _playerCtx.tempoDelta = (data << 4) - _playerCtx.tempoStart;
+ _playerCtx.tempoTime = (stopTime << 8);
+ _playerCtx.tempoTicks = 0;
+ }
+ break;
+
+/* case 0xA0: // SPECIAL
+ break;
+
+ case 0xB0: // CONTROL
+ // TODO: controlChange((byte)stopTime, (byte)(stopTime >> 8))
+ break;
+
+*/ case 0xC0: // PROGRAM
+ channel.patch = &_patch[stopTime & (kNumPatches - 1)];
+ break;
+
+ case 0xE0: // BEND
+ channel.pitchBend = ((stopTime & 0x7F00) >> 1) | (stopTime & 0x7f);
+ // channel.pitchReal = ((int32)(channel.pitchBendRange << 8) * (channel.pitchBend - (64 << 7))) / (64 << 7);
+ channel.pitchReal = (((int32)channel.pitchBendRange * channel.pitchBend) >> 5) - (channel.pitchBendRange << 8);
+ channel.isAltered = true;
+ break;
+
+ case 0xFF: // END
+ if (_playerCtx.musicLoop) {
+ curEvent = _scores[_playerCtx.scoreIndex].events;
+ eventDelta = curEvent->startTime - millis;
+ _playerCtx.ticks = 0;
+ } else
+ _playerCtx.musicPlaying = false;
+ // stop processing for this tick
+ goto endOfEventLoop;
+
+ default:
+ debug("Unhandled Command");
+ outPutEvent(*curEvent);
+ }
+ }
+ }
+endOfEventLoop:
+ _playerCtx.nextEvent = curEvent;
+ _playerCtx.nextEventTime = eventDelta + millis;
+
+ // tempoEffect
+ if (_playerCtx.tempoTime) {
+ _playerCtx.tempoTicks += _playerCtx.tickUnit;
+ uint16 newTempo = _playerCtx.tempoStart;
+ if (_playerCtx.tempoTicks < _playerCtx.tempoTime) {
+ newTempo += (uint16)((_playerCtx.tempoTicks * _playerCtx.tempoDelta) / _playerCtx.tempoTime);
+ } else {
+ _playerCtx.tempoTime = 0;
+ newTempo += _playerCtx.tempoDelta;
+ }
+ setTempo(_playerCtx.tempoStart + newTempo);
+ }
+ }
+
+ // Handling of Envelopes and Portamento
+ for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i) {
+ VoiceContext &voice = _voiceCtx[i];
+ if (!voice.channel)
+ continue;
+ const ChannelContext &channel = *voice.channel;
+ const Patch &patch = *voice.patch;
+
+ switch (voice.status) {
+ case VoiceContext::kStatusSustain:
+ if (!channel.isAltered && !voice.hasPortamento && !channel.modulation)
+ continue;
+ // Update Volume and Period
+ break;
+
+ case VoiceContext::kStatusHalt:
+ killVoice((byte)i);
+ continue;
+
+ case VoiceContext::kStatusStart:
+ if (patch.attackLen) {
+ voice.envelope = patch.attackPtr;
+ const uint16 duration = voice.envelope->duration;
+ voice.envelopeLeft = patch.attackLen;
+ voice.ticksLeft = duration << 8;
+ voice.status = VoiceContext::kStatusAttack;
+ voice.incrVolume = calcVolumeDelta((int32)voice.envelope->volume, duration);
+ // Process Envelope
+ } else {
+ voice.status = VoiceContext::kStatusSustain;
+ voice.baseVolume = patch.volume;
+ // Update Volume and Period
+ }
+ break;
+
+ case VoiceContext::kStatusRelease:
+ if (patch.releaseLen) {
+ voice.envelope = patch.attackPtr + patch.attackLen;
+ const uint16 duration = voice.envelope->duration;
+ voice.envelopeLeft = patch.releaseLen;
+ voice.ticksLeft = duration << 8;
+ voice.status = VoiceContext::kStatusDecay;
+ voice.incrVolume = calcVolumeDelta((int32)voice.envelope->volume - voice.baseVolume, duration);
+ // Process Envelope
+ } else {
+ voice.status = VoiceContext::kStatusHalt;
+ voice.lastVolume = 0;
+ // Send Audio Packet
+ }
+ break;
+ }
+
+ // Process Envelope
+ const uint16 envUnit = _playerCtx.frameUnit;
+ if (voice.envelope) {
+ // TODO remove paranoid asserts
+ assert(voice.status != VoiceContext::kStatusSustain);
+ assert(voice.status == VoiceContext::kStatusAttack || VoiceContext::kStatusRelease);
+ assert(voice.envelope);
+ assert(voice.envelopeLeft >= 0);
+ if (voice.ticksLeft > envUnit) { // envelope still active
+ voice.baseVolume = (uint16)MIN(MAX(0, voice.baseVolume + voice.incrVolume), 0x8000);
+ voice.ticksLeft -= envUnit;
+ // Update Volume and Period
+
+ } else { // next or last Envelope
+ voice.baseVolume = voice.envelope->volume;
+ assert(voice.envelopeLeft > 0);
+ if (--voice.envelopeLeft) {
+ ++voice.envelope;
+ const uint16 duration = voice.envelope->duration;
+ voice.ticksLeft = duration << 8;
+ voice.incrVolume = calcVolumeDelta((int32)voice.envelope->volume - voice.baseVolume, duration);
+ // Update Volume and Period
+ } else if (voice.status == VoiceContext::kStatusDecay) {
+ voice.status = VoiceContext::kStatusHalt;
+ voice.envelope = 0;
+ voice.lastVolume = 0;
+ // Send Audio Packet
+ } else {
+ assert(voice.status == VoiceContext::kStatusAttack);
+ voice.status = VoiceContext::kStatusSustain;
+ voice.envelope = 0;
+ // Update Volume and Period
+ }
+ }
+ }
+
+ // Update Volume and Period
+ if (voice.status >= VoiceContext::kStatusDecay) {
+ // Calc volume
+ uint16 vol = (voice.noteVolume < (1 << 7)) ? (voice.noteVolume * _playerCtx.volume) >> 7 : _playerCtx.volume;
+ if (voice.baseVolume < (1 << 15))
+ vol = (uint16)(((uint32)vol * voice.baseVolume) >> 15);
+ if (voice.channel->volume < (1 << 7))
+ vol = (vol * voice.channel->volume) >> 7;
+ voice.lastVolume = (byte)MIN(vol, (uint16)0x64);
+
+ // Calc Period
+ if (voice.hasPortamento) {
+ voice.portaTicks += envUnit;
+ if ((uint16)(voice.portaTicks >> 8) >= channel.portamentoTime) {
+ voice.hasPortamento = false;
+ voice.baseNote = voice.endNote;
+ voice.preCalcNote = precalcNote(voice.baseNote, patch.tune, voice.octave);
+ }
+ voice.lastPeriod = calcNote(voice);
+ } else if (channel.isAltered || channel.modulation)
+ voice.lastPeriod = calcNote(voice);
+ }
+
+ // Send Audio Packet
+ Paula::setChannelPeriod(i, (voice.lastPeriod) ? voice.lastPeriod : 1000);
+ Paula::setChannelVolume(i, (voice.lastPeriod) ? voice.lastVolume : 0);
+ }
+ for (ChannelContext *c = _channelCtx; c != &_channelCtx[ARRAYSIZE(_channelCtx)]; ++c)
+ c->isAltered = false;
+
+
+ //modulation stuff, sinevalue += tickunit
+}
+
+int32 MaxTrax::calcVolumeDelta(int32 delta, uint16 time) {
+ const int32 div = time * _playerCtx.vBlankFreq;
+ if (div <= 1000)
+ return delta; // time to small or 0
+ return (1000 * delta) / div;
+}
+
+void MaxTrax::stopMusic() {
+}
+
+bool MaxTrax::doSong(int songIndex, int advance) {
+ if (songIndex < 0 || songIndex >= _numScores)
+ return false;
+ Paula::pausePlay(true);
+ _playerCtx.musicPlaying = false;
+ _playerCtx.musicLoop = false;
+
+ setTempo(_playerCtx.tempoInitial << 4);
+ _playerCtx.nextEvent = _scores[songIndex].events;
+ _playerCtx.nextEventTime = _playerCtx.nextEvent->startTime;
+ _playerCtx.scoreIndex = songIndex;
+
+ _playerCtx.musicPlaying = true;
+ Paula::startPaula();
+ return true;
+}
+
+void MaxTrax::killVoice(byte num) {
+ VoiceContext &voice = _voiceCtx[num];
+ --(voice.channel->voicesActive);
+ voice.channel = 0;
+ voice.envelope = 0;
+ voice.status = VoiceContext::kStatusFree;
+ voice.flags = 0;
+ voice.hasPortamento = false;
+ voice.priority = 0;
+ //voice.uinqueId = 0;
+
+ // "stop" voice, set period to 1, vol to 0
+ Paula::disableChannel(num);
+ Paula::setChannelPeriod(num, 1);
+ Paula::setChannelVolume(num, 0);
+}
+
+int8 MaxTrax::pickvoice(const VoiceContext voices[4], uint pick, int16 pri) {
+ pick &= 3;
+ enum { kPrioFlagFixedSide = 1 << 3 };
+ if ((pri & (kPrioFlagFixedSide)) == 0) {
+ const bool leftSide = (uint)(pick - 1) > 1;
+ const int leftBest = MIN(voices[0].status, voices[3].status);
+ const int rightBest = MIN(voices[1].status, voices[2].status);
+ const int sameSide = (leftSide) ? leftBest : rightBest;
+ const int otherSide = leftBest + rightBest - sameSide;
+
+ if (sameSide > VoiceContext::kStatusRelease && otherSide <= VoiceContext::kStatusRelease) {
+ pick ^= 1; // switches sides
+ }
+ }
+ pri &= ~kPrioFlagFixedSide;
+
+ for (int i = 1; i > 0; --i) {
+ const VoiceContext *voice = &voices[pick];
+ const VoiceContext *alternate = &voices[pick ^ 3];
+
+ if (voice->status > alternate->status
+ || (voice->status == alternate->status && voice->lastVolume > alternate->lastVolume)) {
+ // TODO: tiebreaking
+ pick ^= 3; // switch channels
+ const VoiceContext *tmp = voice;
+ voice = alternate;
+ alternate = tmp;
+ }
+
+ if ((voice->flags & VoiceContext::kFlagBlocked) != 0 || voice->priority > pri) {
+ pick ^= 3; // switch channels
+ if ((alternate->flags & VoiceContext::kFlagBlocked) != 0 || alternate->priority > pri) {
+ // if not already done, switch sides and try again
+ pick ^= 1;
+ continue;
+ }
+ }
+ // succeded
+ return (int8)pick;
+ }
+ // failed
+ return -1;
+}
+
+uint16 MaxTrax::calcNote(const VoiceContext &voice) {
+ const ChannelContext &channel = *voice.channel;
+ int16 bend = channel.pitchReal;
+ if (voice.hasPortamento)
+ bend += (int16)(((int8)(voice.endNote - voice.baseNote)) * voice.portaTicks) / channel.portamentoTime;
+
+ // 0x9fd77 ~ log2(1017) MIDI F5 ?
+ // 0x8fd77 ~ log2(508.5) MIDI F4 ?
+ // 0x6f73d ~ log2(125) ~ 5675Hz
+ enum { K_VALUE = 0x9fd77, PREF_PERIOD = 0x8fd77, PERIOD_LIMIT = 0x6f73d };
+
+ // tone = voice.baseNote << 8 + microtonal
+ // bend = channelPitch + porta + modulation
+
+ const int32 tone = voice.preCalcNote + (bend << 6) / 3;
+
+ if (tone >= PERIOD_LIMIT + (1 << 16)) {
+ // calculate 2^tone and round towards nearest integer
+ // 2*2^tone = exp((tone+1) * ln(2))
+ const uint16 periodX2 = (uint16)expf((float)tone * (float)(0.69314718055994530942 / (1 << 16)));
+ return (periodX2 + 1) / 2;
+ }
+ return 0;
+}
+
+int8 MaxTrax::noteOn(ChannelContext &channel, const byte note, uint16 volume, uint16 pri) {
+ if (channel.microtonal >= 0)
+ _microtonal[note % 127] = channel.microtonal;
+ if (!volume)
+ return -1;
+
+ const Patch &patch = *channel.patch;
+ if (!patch.samplePtr)
+ return -1;
+ int8 voiceNum = -1;
+ if ((channel.flags & ChannelContext::kFlagMono) != 0 && channel.voicesActive) {
+ VoiceContext *voice = _voiceCtx + ARRAYSIZE(_voiceCtx) - 1;
+ for (voiceNum = ARRAYSIZE(_voiceCtx) - 1; voiceNum >= 0 && voice->channel != &channel; --voiceNum, --voice)
+ ;
+ if (voiceNum >= 0 && voice->status >= VoiceContext::kStatusSustain && (channel.flags & ChannelContext::kFlagPortamento) != 0) {
+ // reset previous porta
+ if (voice->hasPortamento)
+ voice->baseNote = voice->endNote;
+ voice->preCalcNote = precalcNote(voice->baseNote, patch.tune, voice->octave);
+ voice->portaTicks = 0;
+ voice->hasPortamento = true;
+ voice->endNote = channel.lastNote = note;
+ voice->noteVolume = (_playerCtx.handleVolume) ? volume + 1 : 128;
+ }
+
+ } else {
+ voiceNum = pickvoice(_voiceCtx, (channel.flags & ChannelContext::kFlagRightChannel) != 0 ? 1 : 0, pri);
+ if (voiceNum >= 0) {
+ VoiceContext &voice = _voiceCtx[voiceNum];
+ voice.flags = 0;
+ voice.hasPortamento = false;
+ if (voice.channel) {
+ killVoice(voiceNum);
+ voice.flags |= VoiceContext::kFlagStolen;
+ }
+ voice.channel = &channel;
+ voice.patch = &patch;
+ voice.baseNote = note;
+
+ const int32 plainNote = precalcNote(voice.baseNote, patch.tune, 0);
+ const int32 PREF_PERIOD1 = 0x8fd77 + (1 << 16);
+ // calculate which sample to use
+ const int useOctave = (plainNote <= PREF_PERIOD1) ? 0 : MIN<int32>((plainNote + 0xFFFF - PREF_PERIOD1) >> 16, patch.sampleOctaves - 1);
+ voice.octave = (byte)useOctave;
+ voice.preCalcNote = plainNote - (useOctave << 16);
+
+ voice.lastPeriod = calcNote(voice);
+
+ voice.priority = (byte)pri;
+ voice.status = VoiceContext::kStatusStart;
+
+ voice.noteVolume = (_playerCtx.handleVolume) ? volume + 1 : 128;
+
+ // ifeq HAS_FULLCHANVOL macro
+ if (channel.volume < 128)
+ voice.noteVolume = (voice.noteVolume * channel.volume) >> 7;
+
+ voice.baseVolume = 0;
+
+ const uint16 period = (voice.lastPeriod) ? voice.lastPeriod : 1000;
+
+ // TODO: since the original player is using the OS-functions, more than 1 sample could be queued up already
+ // get samplestart for the given octave
+ const int8 *samplePtr = patch.samplePtr + (patch.sampleTotalLen << useOctave) - patch.sampleTotalLen;
+ if (patch.sampleAttackLen) {
+ Paula::setChannelSampleStart(voiceNum, samplePtr);
+ Paula::setChannelSampleLen(voiceNum, (patch.sampleAttackLen << useOctave) / 2);
+ Paula::setChannelPeriod(voiceNum, period);
+ Paula::setChannelVolume(voiceNum, 0);
+
+ Paula::enableChannel(voiceNum);
+ // wait for dma-clear
+ // FIXME: this is a workaround to enable oneshot-samples and it currently might crash Paula
+ if (patch.sampleTotalLen == patch.sampleAttackLen) {
+ Paula::setChannelSampleStart(voiceNum, 0);
+ Paula::setChannelSampleLen(voiceNum, 0);
+ }
+ }
+
+ if (patch.sampleTotalLen > patch.sampleAttackLen) {
+ Paula::setChannelSampleStart(voiceNum, samplePtr + (patch.sampleAttackLen << useOctave));
+ Paula::setChannelSampleLen(voiceNum, ((patch.sampleTotalLen - patch.sampleAttackLen) << useOctave) / 2);
+ if (!patch.sampleAttackLen) {
+ // need to enable channel
+ Paula::setChannelPeriod(voiceNum, period);
+ Paula::setChannelVolume(voiceNum, 0);
+
+ Paula::enableChannel(voiceNum);
+ }
+ // another pointless wait for DMA-Clear???
+ }
+
+ channel.voicesActive++;
+ if (&channel < &_channelCtx[kNumChannels]) {
+ if ((channel.flags & ChannelContext::kFlagPortamento) != 0) {
+ if ((channel.flags & ChannelContext::kFlagMono) != 0 && channel.lastNote < 0x80 && channel.lastNote != voice.baseNote) {
+ voice.portaTicks = 0;
+ voice.endNote = voice.baseNote;
+ voice.baseNote = channel.lastNote;
+ voice.preCalcNote = precalcNote(voice.baseNote, patch.tune, voice.octave);
+ voice.hasPortamento = true;
+ }
+ channel.lastNote = note;
+ }
+ }
+ }
+ }
+ return voiceNum;
+}
+
+void MaxTrax::noteOff(VoiceContext &voice, const byte note) {
+ ChannelContext &channel = *voice.channel;
+ if (channel.voicesActive && voice.status != VoiceContext::kStatusRelease) {
+ // TODO is this check really necessary?
+ const byte refNote = (voice.hasPortamento) ? voice.endNote : voice.baseNote;
+ assert(refNote == note);
+ if (refNote == note) {
+ if ((channel.flags & ChannelContext::kFlagDamper) != 0)
+ voice.flags |= VoiceContext::kFlagDamper;
+ else
+ voice.status = VoiceContext::kStatusRelease;
+ }
+ }
+}
+
+void MaxTrax::resetChannel(ChannelContext &chan, bool rightChannel) {
+ chan.modulation = 0;
+ chan.modulationTime = 1000;
+ chan.microtonal = -1;
+ chan.portamentoTime = 500;
+ chan.pitchBend = 64 << 7;
+ chan.pitchReal = 0;
+ chan.pitchBendRange = 24;
+ chan.volume = 128;
+ chan.flags &= ~ChannelContext::kFlagPortamento & ~ChannelContext::kFlagMicrotonal;
+ chan.isAltered = true;
+ if (rightChannel)
+ chan.flags |= ChannelContext::kFlagRightChannel;
+ else
+ chan.flags &= ~ChannelContext::kFlagRightChannel;
+}
+
+void MaxTrax::freeScores() {
+ if (_scores) {
+ for (int i = 0; i < _numScores; ++i)
+ delete[] _scores[i].events;
+ delete[] _scores;
+ _scores = 0;
+ }
+ _numScores = 0;
+ memset(_microtonal, 0, sizeof(_microtonal));
+}
+
+void MaxTrax::freePatches() {
+ for (int i = 0; i < ARRAYSIZE(_patch); ++i) {
+ delete[] _patch[i].samplePtr;
+ delete[] _patch[i].attackPtr;
+ }
+ memset(const_cast<Patch *>(_patch), 0, sizeof(_patch));
+}
+
+int MaxTrax::playNote(byte note, byte patch, uint16 duration, uint16 volume, bool rightSide) {
+ assert(patch < ARRAYSIZE(_patch));
+
+ ChannelContext &channel = _channelCtx[kNumChannels];
+ channel.flags = (rightSide) ? ChannelContext::kFlagRightChannel : 0;
+ channel.isAltered = false;
+ channel.patch = &_patch[patch];
+ const int8 voiceIndex = noteOn(channel, note, (byte)volume, kPriorityNote);
+ if (voiceIndex >= 0) {
+ VoiceContext &voice = _voiceCtx[voiceIndex];
+ voice.stopEventCommand = note;
+ voice.stopEventParameter = kNumChannels;
+ voice.stopEventTime = duration << 8;
+ }
+ return voiceIndex;
+}
+
+bool MaxTrax::load(Common::SeekableReadStream &musicData, bool loadScores, bool loadSamples) {
+ bool res = false;
+ stopMusic();
+ if (loadSamples)
+ freePatches();
+ if (loadScores)
+ freeScores();
+ // 0x0000: 4 Bytes Header "MXTX"
+ // 0x0004: uint16 tempo
+ // 0x0006: uint16 flags. bit0 = lowpassfilter, bit1 = attackvolume, bit15 = microtonal
+ if (musicData.readUint32BE() != 0x4D585458) {
+ warning("Maxtrax: File is not a Maxtrax Module");
+ return false;
+ }
+ const uint16 songTempo = musicData.readUint16BE();
+ const uint16 flags = musicData.readUint16BE();
+ if (loadScores) {
+ _playerCtx.tempoInitial = songTempo;
+ _playerCtx.filterOn = (flags & 1) != 0;
+ _playerCtx.handleVolume = (flags & 2) != 0;
+ debug("Header: MXTX %02X %02X", _playerCtx.tempo, flags);
+ }
+
+ if (flags & (1 << 15)) {
+ debug("Song has microtonal");
+ if (loadScores) {
+ for (int i = 0; i < ARRAYSIZE(_microtonal); ++i)
+ _microtonal[i] = musicData.readUint16BE();
+ } else
+ musicData.skip(128 * 2);
+ }
+
+ int scoresLoaded = 0;
+ // uint16 number of Scores
+ const uint16 scoresInFile = musicData.readUint16BE();
+
+ if (loadScores) {
+ const uint16 tempScores = MIN(scoresInFile, _playerCtx.maxScoreNum);
+ debug("#Scores: %d, loading # of scores: %d", scoresInFile, tempScores);
+ Score *curScore =_scores = new Score[tempScores];
+
+ for (int i = tempScores; i > 0; --i, ++curScore) {
+ const uint32 numEvents = musicData.readUint32BE();
+ Event *curEvent = new Event[numEvents];
+ curScore->events = curEvent;
+ for (int j = numEvents; j > 0; --j, ++curEvent) {
+ curEvent->command = musicData.readByte();
+ curEvent->parameter = musicData.readByte();
+ curEvent->startTime = musicData.readUint16BE();
+ curEvent->stopTime = musicData.readUint16BE();
+ }
+ curScore->numEvents = numEvents;
+ }
+ _numScores = scoresLoaded = tempScores;
+ }
+
+ if (false && !loadSamples)
+ return true;
+
+ // skip over remaining scores in file
+ for (int i = scoresInFile - scoresLoaded; i > 0; --i)
+ musicData.skip(musicData.readUint32BE() * 6);
+
+ for (int i = 0; i < _numScores; ++i)
+ outPutScore(_scores[i], i);
+
+ debug("samples start at filepos %08X", musicData.pos());
+ // uint16 number of Samples
+ const uint16 wavesInFile = musicData.readUint16BE();
+ if (loadSamples) {
+ for (int i = wavesInFile; i > 0; --i) {
+ // load disksample structure
+ const uint16 number = musicData.readUint16BE();
+ assert(number < ARRAYSIZE(_patch));
+ // pointer to samples needed?
+ Patch &curPatch = const_cast<Patch &>(_patch[number]);
+
+ curPatch.tune = musicData.readSint16BE();
+ curPatch.volume = musicData.readUint16BE();
+ curPatch.sampleOctaves = musicData.readUint16BE();
+ curPatch.sampleAttackLen = musicData.readUint32BE();
+ const uint32 sustainLen = musicData.readUint32BE();
+ curPatch.sampleTotalLen = curPatch.sampleAttackLen + sustainLen;
+ // each octave the number of samples doubles.
+ const uint32 totalSamples = curPatch.sampleTotalLen * ((1 << curPatch.sampleOctaves) - 1);
+ curPatch.attackLen = musicData.readUint16BE();
+ curPatch.releaseLen = musicData.readUint16BE();
+ const uint32 totalEnvs = curPatch.attackLen + curPatch.releaseLen;
+
+ debug("wave nr %d at %08X - %d octaves", number, musicData.pos(), curPatch.sampleOctaves);
+ // Allocate space for both attack and release Segment.
+ Envelope *envPtr = new Envelope[totalEnvs];
+ // Attack Segment
+ curPatch.attackPtr = envPtr;
+ // Release Segment
+ // curPatch.releasePtr = envPtr + curPatch.attackLen;
+
+ // Read Attack and Release Segments
+ for (int j = totalEnvs; j > 0; --j, ++envPtr) {
+ envPtr->duration = musicData.readUint16BE();
+ envPtr->volume = musicData.readUint16BE();
+ }
+
+ // read Samples
+ int8 *allocSamples = new int8[totalSamples];
+ curPatch.samplePtr = allocSamples;
+ musicData.read(allocSamples, totalSamples);
+ }
+ } else if (wavesInFile > 0){
+ uint32 skipLen = 3 * 2;
+ for (int i = wavesInFile; i > 0; --i) {
+ musicData.skip(skipLen);
+ const uint16 octaves = musicData.readUint16BE();
+ const uint32 attackLen = musicData.readUint32BE();
+ const uint32 sustainLen = musicData.readUint32BE();
+ const uint16 attackCount = musicData.readUint16BE();
+ const uint16 releaseCount = musicData.readUint16BE();
+ debug("wave nr %d at %08X", 0, musicData.pos());
+
+ skipLen = attackCount * 4 + releaseCount * 4
+ + (attackLen + sustainLen) * ((1 << octaves) - 1)
+ + 3 * 2;
+ }
+ musicData.skip(skipLen - 3 * 2);
+ }
+ debug("endpos %08X", musicData.pos());
+ return res;
+}
+
+} // End of namespace Audio \ No newline at end of file
diff --git a/sound/mods/maxtrax.h b/sound/mods/maxtrax.h
new file mode 100644
index 0000000000..cbc4a5b59f
--- /dev/null
+++ b/sound/mods/maxtrax.h
@@ -0,0 +1,260 @@
+/* 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_MAXTRAX_H
+#define SOUND_MODS_MAXTRAX_H
+
+#include "sound/mods/paula.h"
+
+namespace Audio {
+
+class MaxTrax : public Paula {
+public:
+ MaxTrax(int rate, bool stereo);
+ virtual ~MaxTrax();
+
+protected:
+ void interrupt();
+
+private:
+public:
+
+ enum { kNumPatches = 64, kNumVoices = 4, kNumChannels = 16, kNumExtraChannels = 1 };
+ enum { kPriorityScore, kPriorityNote, kPrioritySound };
+ int16 _microtonal[128];
+ struct Event;
+
+ struct PlayerContext {
+ uint16 vBlankFreq;
+ int32 ticks;
+ int32 tickUnit;
+ uint16 frameUnit;
+
+ uint16 maxScoreNum;
+ uint16 tempo;
+ uint16 tempoInitial;
+ uint16 tempoStart;
+ int16 tempoDelta;
+ int32 tempoTime;
+ int32 tempoTicks;
+
+ byte volume;
+
+ bool filterOn;
+ bool handleVolume;
+ bool musicPlaying;
+ bool musicLoop;
+
+ int scoreIndex;
+ const Event *nextEvent;
+ int32 nextEventTime;
+ } _playerCtx;
+
+ struct Envelope {
+ uint16 duration;
+ uint16 volume;
+ };
+
+ const struct Patch {
+ const Envelope *attackPtr;
+ //Envelope *releasePtr;
+ uint16 attackLen;
+ uint16 releaseLen;
+
+ int16 tune;
+ uint16 volume;
+
+ // this was the SampleData struct in the assembler source
+ const int8 *samplePtr;
+ uint32 sampleTotalLen;
+ uint32 sampleAttackLen;
+ uint16 sampleOctaves;
+ } _patch[kNumPatches];
+
+ struct Event {
+ uint16 startTime;
+ uint16 stopTime;
+ byte command;
+ byte parameter;
+ };
+
+ struct Score {
+ const Event *events;
+ uint32 numEvents;
+ } *_scores;
+
+ int _numScores;
+
+ struct ChannelContext {
+ const Patch *patch;
+ uint16 regParamNumber;
+
+ uint16 modulation;
+ uint16 modulationTime;
+
+ int16 microtonal;
+
+ uint16 portamentoTime;
+
+ int16 pitchBend;
+ int16 pitchReal;
+ int8 pitchBendRange;
+
+ uint8 volume;
+ uint8 voicesActive;
+// uint8 number;
+
+ enum {
+ kFlagRightChannel = 1 << 0,
+ kFlagPortamento = 1 << 1,
+ kFlagDamper = 1 << 2,
+ kFlagMono = 1 << 3,
+ kFlagMicrotonal = 1 << 4,
+ kFlagModVolume = 1 << 5//,
+ //kFlagAltered = 1 << 6
+ };
+ byte flags;
+ bool isAltered;
+
+ uint8 lastNote;
+ uint8 program;
+
+ } _channelCtx[kNumChannels + kNumExtraChannels];
+
+ struct VoiceContext {
+ ChannelContext *channel;
+ const Patch *patch;
+ const Envelope *envelope;
+// uint32 uinqueId;
+ int32 preCalcNote;
+ uint32 ticksLeft;
+ int32 portaTicks;
+ int32 incrVolume;
+// int32 periodOffset;
+ /*ifne FASTSOUND
+ APTR voice_CurFastIOB ; current fast iob playing
+ APTR voice_NextFastIOB ; next fast iob to play
+ APTR voice_FastBuffer ; pointer to buffer area
+ endc*/
+ uint16 envelopeLeft;
+ uint16 noteVolume;
+ uint16 baseVolume;
+ uint16 lastPeriod;
+ byte baseNote;
+ byte endNote;
+ byte octave;
+// byte number;
+// byte link;
+ byte priority;
+ enum {
+ kStatusFree,
+ kStatusHalt,
+ kStatusDecay,
+ kStatusRelease,
+ kStatusSustain,
+ kStatusAttack,
+ kStatusStart
+ };
+ byte status;
+ enum {
+ kFlagStolen = 1 << 0,
+ //kFlagPortamento = 1 << 1,
+ kFlagDamper = 1 << 2,
+ kFlagBlocked = 1 << 3,
+ kFlagRecalc = 1 << 4
+ };
+ byte flags;
+ byte lastVolume;
+ bool hasPortamento;
+
+ int32 stopEventTime;
+ byte stopEventCommand; // TODO: Remove?
+ byte stopEventParameter; // TODO: Remove?
+ } _voiceCtx[kNumVoices];
+
+ bool load(Common::SeekableReadStream &musicData, bool loadScores = true, bool loadSamples = true);
+ bool doSong(int songIndex, int advance = 0);
+
+ void stopMusic();
+ void freePatches();
+ void freeScores();
+ void resetChannel(ChannelContext &chan, bool rightChannel);
+
+ static int8 pickvoice(const VoiceContext voice[4], uint pick, int16 pri);
+ int32 calcVolumeDelta(int32 delta, uint16 time);
+ static uint16 calcNote(const VoiceContext &voice);
+ int8 noteOn(ChannelContext &channel, byte note, uint16 volume, uint16 pri);
+ void noteOff(VoiceContext &voice, byte note);
+ void killVoice(byte num);
+ int playNote(byte note, byte patch, uint16 duration, uint16 volume, bool rightSide);
+
+ void setTempo(const uint16 tempo) {
+ _playerCtx.tickUnit = (int32)(((uint32)(tempo & 0xFFF0) << 8) / (uint16)(5 * _playerCtx.vBlankFreq));
+ }
+
+ static int32 precalcNote(byte baseNote, int16 tune, byte octave) {
+ return 0x9fd77 + 0x3C000 + (1 << 16) - ((baseNote << 14) + (tune << 11) / 3) / 3 - (octave << 16);
+ }
+
+ static void outPutEvent(const Event &ev, int num = -1) {
+ struct {
+ byte cmd;
+ const char *name;
+ const char *param;
+ } COMMANDS[] = {
+ {0x80, "TEMPO ", "TEMPO, N/A "},
+ {0xa0, "SPECIAL ", "CHAN, SPEC # | VAL"},
+ {0xb0, "CONTROL ", "CHAN, CTRL # | VAL"},
+ {0xc0, "PROGRAM ", "CHANNEL, PROG # "},
+ {0xe0, "BEND ", "CHANNEL, BEND VALUE"},
+ {0xf0, "SYSEX ", "TYPE, SIZE "},
+ {0xf8, "REALTIME", "REALTIME, N/A "},
+ {0xff, "END ", "N/A, N/A "},
+ {0xff, "NOTE ", "VOL | CHAN, STOP"},
+ };
+
+ int i = 0;
+ for (; i < ARRAYSIZE(COMMANDS) - 1 && ev.command != COMMANDS[i].cmd; ++i)
+ ;
+
+ if (num == -1)
+ debug("Event : %02X %s %s %02X %04X %04X", ev.command, COMMANDS[i].name, COMMANDS[i].param, ev.parameter, ev.startTime, ev.stopTime);
+ else
+ debug("Event %3d: %02X %s %s %02X %04X %04X", num, ev.command, COMMANDS[i].name, COMMANDS[i].param, ev.parameter, ev.startTime, ev.stopTime);
+ }
+
+ static void outPutScore(const Score &sc, int num = -1) {
+ if (num == -1)
+ debug("score : %i Events", sc.numEvents);
+ else
+ debug("score %2d: %i Events", num, sc.numEvents);
+ for (uint i = 0; i < sc.numEvents; ++i)
+ outPutEvent(sc.events[i], i);
+ debug("");
+ }
+};
+} // End of namespace Audio
+
+#endif
diff --git a/sound/mods/paula.cpp b/sound/mods/paula.cpp
index 545390ff93..2e19927d83 100644
--- a/sound/mods/paula.cpp
+++ b/sound/mods/paula.cpp
@@ -27,19 +27,20 @@
namespace Audio {
-Paula::Paula(bool stereo, int rate, int interruptFreq) :
- _stereo(stereo), _rate(rate), _intFreq(interruptFreq) {
+Paula::Paula(bool stereo, int rate, uint interruptFreq) :
+ _stereo(stereo), _rate(rate), _periodScale((kPalSystemClock / 2.0) / rate), _intFreq(interruptFreq) {
clearVoices();
- _voice[0].panning = 63;
- _voice[1].panning = 191;
- _voice[2].panning = 191;
- _voice[3].panning = 63;
+ _voice[0].panning = 191;
+ _voice[1].panning = 63;
+ _voice[2].panning = 63;
+ _voice[3].panning = 191;
- if (_intFreq <= 0)
+ if (_intFreq == 0)
_intFreq = _rate;
- _curInt = _intFreq;
+ _curInt = 0;
+ _timerBase = 1;
_playing = false;
_end = true;
}
@@ -57,6 +58,7 @@ void Paula::clearVoice(byte voice) {
_voice[voice].period = 0;
_voice[voice].volume = 0;
_voice[voice].offset = 0;
+ _voice[voice].dmaCount = 0;
}
int Paula::readBuffer(int16 *buffer, const int numSamples) {
@@ -95,18 +97,17 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
// 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++) {
-
// No data, or paused -> skip channel
if (!_voice[voice].data || (_voice[voice].period <= 0))
continue;
@@ -115,8 +116,7 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
// 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;
- frac_t rate = doubleToFrac(frequency / _rate);
+ frac_t rate = doubleToFrac(_periodScale / _voice[voice].period);
// Cap the volume
_voice[voice].volume = MIN((byte) 0x40, _voice[voice].volume);
@@ -126,6 +126,7 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
frac_t offset = _voice[voice].offset;
frac_t sLen = intToFrac(_voice[voice].length);
const int8 *data = _voice[voice].data;
+ int dmaCount = _voice[voice].dmaCount;
int16 *p = buffer;
int end = 0;
int neededSamples = nSamples;
@@ -141,7 +142,6 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
// 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].data = data = _voice[voice].dataRepeat;
_voice[voice].length = _voice[voice].lengthRepeat;
@@ -150,12 +150,15 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
// 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
+ // TODO: This messes up dmaCount
if (sLen < rate)
rate %= sLen;
// Repeat as long as necessary.
while (neededSamples > 0) {
- offset = 0;
+ // TODO offset -= sLen, but only if same rate otherwise need to scale first
+ offset &= FRAC_LO_MASK;
+ dmaCount++;
// Compute the number of samples to generate (see above) and mix 'em.
end = MIN(neededSamples, (int)((sLen - offset + rate - 1) / rate));
@@ -166,10 +169,11 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) {
// Write back the cached data
_voice[voice].offset = offset;
+ _voice[voice].dmaCount = dmaCount;
}
buffer += _stereo ? nSamples * 2 : nSamples;
- _curInt += nSamples;
+ _curInt -= nSamples;
samples -= nSamples;
}
return numSamples;
diff --git a/sound/mods/paula.h b/sound/mods/paula.h
index e3c6002451..05bc67cd78 100644
--- a/sound/mods/paula.h
+++ b/sound/mods/paula.h
@@ -40,12 +40,27 @@ namespace Audio {
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; }
@@ -68,6 +83,7 @@ protected:
byte volume;
frac_t offset;
byte panning; // For stereo mixing: 0 = far left, 255 = far right
+ int dmaCount;
};
bool _end;
@@ -90,6 +106,21 @@ protected:
_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;
@@ -100,6 +131,17 @@ protected:
_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 +152,14 @@ protected:
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 +173,25 @@ protected:
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;
+ const double _periodScale;
+ uint _intFreq;
+ uint _curInt;
+ uint32 _timerBase;
bool _playing;
template<bool stereo>
diff --git a/sound/mods/soundfx.cpp b/sound/mods/soundfx.cpp
index 101d8a077d..3af8ca19c6 100644
--- a/sound/mods/soundfx.cpp
+++ b/sound/mods/soundfx.cpp
@@ -46,8 +46,7 @@ public:
enum {
NUM_CHANNELS = 4,
- NUM_INSTRUMENTS = 15,
- CIA_FREQ = 715909
+ NUM_INSTRUMENTS = 15
};
SoundFx(int rate, bool stereo);
@@ -75,12 +74,12 @@ protected:
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 @@ SoundFx::SoundFx(int rate, bool stereo)
_curPos = 0;
memset(_ordersTable, 0, sizeof(_ordersTable));
_patternData = 0;
- _eventsFreq = 0;
memset(_effects, 0, sizeof(_effects));
}
@@ -167,8 +165,7 @@ void SoundFx::play() {
_curPos = 0;
_curOrder = 0;
_ticks = 0;
- _eventsFreq = CIA_FREQ / _delay;
- setInterruptFreq(getRate() / _eventsFreq);
+ setInterruptFreqUnscaled(_delay);
startPaula();
}
@@ -252,7 +249,7 @@ void SoundFx::handleTick() {
}
void SoundFx::disablePaulaChannel(uint8 channel) {
- setChannelPeriod(channel, 0);
+ disableChannel(channel);
}
void SoundFx::setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen) {
diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp
new file mode 100644
index 0000000000..b2826d6299
--- /dev/null
+++ b/sound/mods/tfmx.cpp
@@ -0,0 +1,996 @@
+/* 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"
+#ifdef _MSC_VER
+#include "tfmx/tfmxdebug.h"
+#endif
+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() {
+ _playerCtx.stopWithLastPattern = false;
+
+ for (int i = 0; i < kNumVoices; ++i)
+ _channelCtx[i].paulaChannel = (byte)i;
+
+ _playerCtx.song = -1;
+ _playerCtx.volume = 0x40;
+ _playerCtx.patternSkip = 6;
+ stopPatternChannels();
+ stopMacroChannels();
+
+ setTimerBaseValue(kPalCiaClock);
+ setInterruptFreqUnscaled(kPalDefaultCiaVal);
+}
+
+Tfmx::~Tfmx() {
+}
+
+void Tfmx::interrupt() {
+ assert(!_end);
+ ++_playerCtx.tickCount;
+ for (int i = 0; i < kNumVoices; ++i) {
+ ChannelContext &channel = _channelCtx[i];
+ if (channel.dmaIntCount) {
+ // wait for DMA Interupts to happen
+ int doneDma = getChannelDmaCount(channel.paulaChannel);
+ if (doneDma >= channel.dmaIntCount) {
+ channel.dmaIntCount = 0;
+ channel.macroRun = true;
+ }
+ }
+
+ if (channel.sfxLockTime >= 0)
+ --channel.sfxLockTime;
+ else {
+ channel.sfxLocked = false;
+ channel.customMacroPrio = 0;
+ }
+
+ // externally queued macros
+ if (channel.customMacro) {
+ const byte *const noteCmd = (const byte *)&channel.customMacro;
+ channel.sfxLocked = false;
+ noteCommand(noteCmd[0], noteCmd[1], (noteCmd[2] & 0xF0) | (uint8)i, noteCmd[3]);
+ channel.customMacro = 0;
+ channel.sfxLocked = (channel.customMacroPrio != 0);
+ }
+
+ // apply timebased effects on Parameters
+ if (channel.macroSfxRun > 0)
+ effects(channel);
+
+ // see if we have to run the macro-program
+ if (channel.macroRun) {
+ if (!channel.macroWait) {
+ macroRun(channel);
+ //assert( !channel.deferWait ); // we can remove this variable as it should be never true after macroRun?
+ }
+ else
+ --channel.macroWait;
+ }
+
+ Paula::setChannelPeriod(channel.paulaChannel, channel.period);
+ if (channel.macroSfxRun >= 0)
+ channel.macroSfxRun = 1;
+
+ // TODO: handling pending DMAOff?
+ }
+
+ // 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) {
+ // addBegin
+ if (channel.addBeginLength) {
+ channel.sampleStart += channel.addBeginDelta;
+ Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+ if (!(--channel.addBeginCount)) {
+ channel.addBeginCount = channel.addBeginLength;
+ channel.addBeginDelta = -channel.addBeginDelta;
+ }
+ }
+
+ // vibrato
+ if (channel.vibLength) {
+ channel.vibValue += channel.vibDelta;
+ if (--channel.vibCount == 0) {
+ channel.vibCount = channel.vibLength;
+ channel.vibDelta = -channel.vibDelta;
+ }
+ if (!channel.portaDelta) {
+ // 16x16 bit multiplication, casts needed for the right results
+ channel.period = (uint16)(((uint32)channel.refPeriod * (uint16)((1 << 11) + channel.vibValue)) >> 11);
+ }
+ }
+
+ // portamento
+ if (channel.portaDelta && --channel.portaCount == 0) {
+ channel.portaCount = channel.portaSkip;
+
+ bool resetPorta = true;
+ const uint16 period = channel.refPeriod;
+ uint16 portaVal = channel.portaValue;
+
+ if (period > portaVal) {
+ portaVal = ((uint32)portaVal * (uint16)((1 << 8) + channel.portaDelta)) >> 8;
+ resetPorta = (period <= portaVal);
+
+ } else if (period < portaVal) {
+ portaVal = ((uint32)portaVal * (uint16)((1 << 8) - channel.portaDelta)) >> 8;
+ resetPorta = (period >= portaVal);
+ }
+
+ if (resetPorta) {
+ channel.portaDelta = 0;
+ channel.portaValue = period & 0x7FF;
+ } else
+ channel.period = channel.portaValue = portaVal & 0x7FF;
+ }
+
+ // envelope
+ if (channel.envSkip && !channel.envCount--) {
+ channel.envCount = channel.envSkip;
+
+ const int8 endVol = channel.envEndVolume;
+ int8 volume = channel.volume;
+ bool resetEnv = true;
+
+ if (endVol > volume) {
+ volume += channel.envDelta;
+ resetEnv = endVol <= volume;
+ } else {
+ volume -= channel.envDelta;
+ resetEnv = volume <= 0 || endVol >= volume;
+ }
+
+ if (resetEnv) {
+ channel.envSkip = 0;
+ volume = endVol;
+ }
+ channel.volume = volume;
+ }
+
+ // Fade
+ if (_playerCtx.fadeDelta && !(--_playerCtx.fadeCount)) {
+ _playerCtx.fadeCount = _playerCtx.fadeSkip;
+
+ _playerCtx.volume += _playerCtx.fadeDelta;
+ if (_playerCtx.volume == _playerCtx.fadeEndVolume)
+ _playerCtx.fadeDelta = 0;
+ }
+
+ // Volume
+ const uint8 finVol = _playerCtx.volume * channel.volume >> 6;
+ Paula::setChannelVolume(channel.paulaChannel, finVol);
+}
+
+static void warnMacroUnimplemented(const byte *macroPtr, int level) {
+ if (level > 0)
+ return;
+ if (level == 0)
+ debug("Warning - Macro not supported:");
+ else
+ debug("Warning - Macro not completely supported:");
+#ifdef _MSC_VER
+ displayMacroStep(macroPtr);
+#endif
+}
+
+void Tfmx::macroRun(ChannelContext &channel) {
+ bool deferWait = false;
+ for (;;) {
+ const byte *const macroPtr = (byte *)(_resource.getMacroPtr(channel.macroOffset) + channel.macroStep);
+ ++channel.macroStep;
+
+ switch (macroPtr[0]) {
+ case 0x00: // Reset + DMA Off. Parameters: deferWait, addset, vol
+ clearEffects(channel);
+ // FT
+ case 0x13: // DMA Off. Parameters: deferWait, addset, vol
+ // TODO: implement PArameters
+ Paula::disableChannel(channel.paulaChannel);
+ channel.deferWait = deferWait = (macroPtr[1] != 0);
+ if (deferWait) {
+ // if set, then we expect a DMA On in the same tick.
+ channel.period = 4;
+ //Paula::setChannelPeriod(channel.paulaChannel, channel.period);
+ 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, remember pending dmaoff?.
+ } else {
+ //TODO ?
+ }
+
+ if (macroPtr[2])
+ channel.volume = macroPtr[3];
+ else if (macroPtr[3])
+ channel.volume = channel.relVol * 3 + macroPtr[3];
+ else
+ continue;
+ Paula::setChannelVolume(channel.paulaChannel, channel.volume);
+ continue;
+
+ case 0x01: // DMA On
+ // TODO: Parameter macroPtr[1] - en-/disable effects
+ if (macroPtr[1])
+ debug("Tfmx: DMA On %i", (int8)macroPtr[1]);
+ channel.dmaIntCount = 0;
+ if (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::setChannelPeriod(channel.paulaChannel, channel.period);
+ Paula::enableChannel(channel.paulaChannel);
+ channel.deferWait = deferWait = false;
+ continue;
+
+ case 0x02: // SetBeginn. Parameters: SampleOffset(L)
+ channel.addBeginLength = 0;
+ channel.sampleStart = READ_BE_UINT32(macroPtr) & 0xFFFFFF;
+ Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+ continue;
+
+ case 0x03: // SetLength. Parameters: SampleLength(W)
+ channel.sampleLen = READ_BE_UINT16(&macroPtr[2]);
+ Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen);
+ continue;
+
+ case 0x04: // Wait. Parameters: Ticks to wait(W).
+ // TODO: some unkown Parameter? (macroPtr[1] & 1)
+ channel.macroWait = READ_BE_UINT16(&macroPtr[2]);
+ return;
+
+ case 0x10: // Loop Key Up. Parameters: Loopcount, MacroStep(W)
+ if (channel.keyUp)
+ continue;
+ // FT
+ case 0x05: // Loop. Parameters: Loopcount, MacroStep(W)
+ if (channel.macroLoopCount != 0) {
+ if (channel.macroLoopCount == 0xFF)
+ channel.macroLoopCount = macroPtr[1];
+ channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+ }
+ --channel.macroLoopCount;
+ continue;
+
+ case 0x06: // Jump. Parameters: MacroIndex, MacroStep(W)
+ channel.macroIndex = macroPtr[1] & (kMaxMacroOffsets - 1);
+ channel.macroOffset = _macroOffset[macroPtr[1] & (kMaxMacroOffsets - 1)];
+ channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+ channel.macroLoopCount = 0xFF;
+ continue;
+
+ case 0x07: // Stop Macro
+ channel.macroRun = false;
+ --channel.macroStep;
+ return;
+
+ case 0x08: // AddNote. Parameters: Note, Finetune(W)
+ setNoteMacro(channel, channel.note + macroPtr[1], READ_BE_UINT16(&macroPtr[2]));
+ break;
+
+ case 0x09: // SetNote. Parameters: Note, Finetune(W)
+ setNoteMacro(channel, macroPtr[1], READ_BE_UINT16(&macroPtr[2]));
+ break;
+
+ case 0x0A: // Clear Effects
+ clearEffects(channel);
+ continue;
+
+ case 0x0B: // Portamento. Parameters: count, speed
+ channel.portaSkip = macroPtr[1];
+ channel.portaCount = 1;
+ // if porta is already running, then keep using old value
+ if (!channel.portaDelta)
+ channel.portaValue = channel.refPeriod;
+ channel.portaDelta = READ_BE_UINT16(&macroPtr[2]);
+ continue;
+
+ case 0x0C: // Vibrato. Parameters: Speed, intensity
+ channel.vibLength = macroPtr[1];
+ channel.vibCount = macroPtr[1] / 2;
+ channel.vibDelta = macroPtr[3];
+ if (!channel.portaDelta) {
+ channel.period = channel.refPeriod;
+ //Paula::setChannelPeriod(channel.paulaChannel, channel.period);
+ channel.vibValue = 0;
+ }
+ continue;
+
+ case 0x0D: // Add Volume. Parameters: note, addNoteFlag, volume
+ if (macroPtr[2] == 0xFE)
+ setNoteMacro(channel, channel.note + macroPtr[1], 0);
+ channel.volume = channel.relVol * 3 + macroPtr[3];
+ continue;
+
+ case 0x0E: // Set Volume. Parameters: note, addNoteFlag, volume
+ if (macroPtr[2] == 0xFE)
+ setNoteMacro(channel, channel.note + macroPtr[1], 0);
+ channel.volume = macroPtr[3];
+ continue;
+
+ case 0x0F: // Envelope. Parameters: speed, count, endvol
+ channel.envDelta = macroPtr[1];
+ channel.envCount = channel.envSkip = macroPtr[2];
+ channel.envEndVolume = macroPtr[3];
+ continue;
+
+ case 0x11: // AddBegin. Parameters: times, Offset(W)
+ channel.addBeginLength = channel.addBeginCount = macroPtr[1];
+ channel.addBeginDelta = (int16)READ_BE_UINT16(&macroPtr[2]);
+ channel.sampleStart += channel.addBeginDelta;
+ Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+ warnMacroUnimplemented(macroPtr, 1);
+ continue;
+
+ case 0x12: // AddLen. Parameters: added Length(W)
+ channel.sampleLen += (int16)READ_BE_UINT16(&macroPtr[2]);
+ Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen);
+ continue;
+
+ case 0x14: // Wait key up. Parameters: wait cycles
+ if (channel.keyUp || channel.macroLoopCount == 0) {
+ channel.macroLoopCount = 0xFF;
+ continue;
+ } else if (channel.macroLoopCount == 0xFF)
+ channel.macroLoopCount = macroPtr[3];
+ --channel.macroLoopCount;
+ --channel.macroStep;
+ return;
+
+ case 0x15: // Subroutine. Parameters: MacroIndex, Macrostep(W)
+ channel.macroReturnOffset = channel.macroOffset;
+ channel.macroReturnStep = channel.macroStep;
+
+ channel.macroOffset = _macroOffset[macroPtr[1] & (kMaxMacroOffsets - 1)];
+ channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+ // TODO: MI does some weird stuff there. Figure out which varioables need to be set
+ continue;
+
+ case 0x16: // Return from Sub.
+ channel.macroOffset = channel.macroReturnOffset;
+ channel.macroStep = channel.macroReturnStep;
+ continue;
+
+ case 0x17: // set Period. Parameters: Period(W)
+ channel.refPeriod = READ_BE_UINT16(&macroPtr[2]);
+ if (!channel.portaDelta) {
+ channel.period = channel.refPeriod;
+ //Paula::setChannelPeriod(channel.paulaChannel, channel.period);
+ }
+ continue;
+
+ case 0x18: { // Sampleloop. Parameters: Offset from Samplestart(W)
+ // TODO: MI loads 24 bit, but thats useless?
+ const uint16 temp = /* ((int8)macroPtr[1] << 16) | */ READ_BE_UINT16(&macroPtr[2]);
+ if (macroPtr[1] || (temp & 1))
+ warning("Tfmx: Problematic value for sampleloop: %i", (macroPtr[1] << 16) | temp);
+ channel.sampleStart += temp & 0xFFFE;
+ channel.sampleLen -= (temp / 2) /* & 0x7FFF */;
+ Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart));
+ Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen);
+ continue;
+ }
+ case 0x19: // set one-shot Sample
+ channel.addBeginLength = 0;
+ channel.sampleStart = 0;
+ channel.sampleLen = 1;
+ Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(0));
+ Paula::setChannelSampleLen(channel.paulaChannel, 1);
+ continue;
+
+ case 0x1A: // Wait on DMA. Parameters: Cycles-1(W) to wait
+ channel.dmaIntCount = READ_BE_UINT16(&macroPtr[2]) + 1;
+ channel.macroRun = false;
+ Paula::setChannelDmaCount(channel.paulaChannel);
+ break;
+
+ case 0x1B: // Random play. Parameters: macro/speed/mode
+ warnMacroUnimplemented(macroPtr, 0);
+ continue;
+
+ case 0x1C: // Branch on Note. Parameters: note/macrostep(W)
+ if (channel.note > macroPtr[1])
+ channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+ continue;
+
+ case 0x1D: // Branch on Volume. Parameters: volume/macrostep(W)
+ if (channel.volume > macroPtr[1])
+ channel.macroStep = READ_BE_UINT16(&macroPtr[2]);
+ continue;
+
+ case 0x1E: // Addvol+note. Parameters: note/CONST./volume
+ warnMacroUnimplemented(macroPtr, 0);
+ continue;
+
+ case 0x1F: // AddPrevNote. Parameters: Note, Finetune(W)
+ setNoteMacro(channel, channel.prevNote + macroPtr[1], READ_BE_UINT16(&macroPtr[2]));
+ break;
+
+ case 0x20: // Signal. Parameters: signalnumber/value
+ if (_playerCtx.signal)
+ _playerCtx.signal[macroPtr[1]] = READ_BE_UINT16(&macroPtr[2]);
+ continue;
+
+ case 0x21: // Play macro. Parameters: macro/chan/detune
+ noteCommand(channel.note, (channel.relVol << 4) | macroPtr[1], macroPtr[2], macroPtr[3]);
+ continue;
+ #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:
+ warnMacroUnimplemented(macroPtr, 0);
+ }
+ if (!deferWait)
+ return;
+ }
+}
+
+void Tfmx::advancePatterns() {
+startPatterns:
+ int runningPatterns = 0;
+
+ for (int i = 0; i < kNumChannels; ++i) {
+ const uint8 pattCmd = _patternCtx[i].command;
+ if (pattCmd < 0x90) { // execute Patternstep
+ ++runningPatterns;
+ if (_patternCtx[i].wait == 0) {
+ // issue all Steps for this tick
+ const bool pendingTrackstep = patternRun(_patternCtx[i]);
+
+ if (pendingTrackstep) {
+ // we load the next Trackstep Command and then process all Channels again
+ trackRun(true);
+ goto startPatterns;
+ }
+
+ } else
+ --_patternCtx[i].wait;
+
+ } else if (pattCmd == 0xFE) { // Stop voice in pattern.expose
+ _patternCtx[i].command = 0xFF;
+ ChannelContext &channel = _channelCtx[_patternCtx[i].expose & (kNumVoices - 1)];
+ if (!channel.sfxLocked) {
+ clearMacroProgramm(channel);
+ Paula::disableChannel(channel.paulaChannel);
+ }
+ } // else this pattern-Channel is stopped
+ }
+ if (_playerCtx.stopWithLastPattern && !runningPatterns) {
+ stopPaula();
+ }
+}
+
+static void warnPatternUnimplemented(const byte *patternPtr, int level) {
+ if (level > 0)
+ return;
+ if (level == 0)
+ debug("Warning - Pattern not supported:");
+ else
+ debug("Warning - Pattern not completely supported:");
+#ifdef _MSC_VER
+ displayPatternstep(patternPtr);
+#endif
+}
+
+bool Tfmx::patternRun(PatternContext &pattern) {
+ for (;;) {
+ const byte *const patternPtr = (byte *)(_resource.getPatternPtr(pattern.offset) + pattern.step);
+ ++pattern.step;
+ const byte pattCmd = patternPtr[0];
+
+ if (pattCmd < 0xF0) { // Playnote
+ bool doWait = false;
+ byte noteCmd = pattCmd + pattern.expose;
+ byte param3 = patternPtr[3];
+ if (pattCmd < 0xC0) { // Note
+ if (pattCmd >= 0x80) { // Wait
+ pattern.wait = param3;
+ param3 = 0;
+ doWait = true;
+ }
+ noteCmd &= 0x3F;
+ } // else Portamento
+ noteCommand(noteCmd, patternPtr[1], patternPtr[2], param3);
+ if (doWait)
+ return false;
+
+ } else { // Patterncommand
+ switch (pattCmd & 0xF) {
+ case 0: // End Pattern + Next Trackstep
+ pattern.command = 0xFF;
+ --pattern.step;
+ return true;
+
+ 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;
+ continue;
+
+ case 2: // Jump. Parameters: PatternIndex, PatternStep(W)
+ pattern.offset = _patternOffset[patternPtr[1]];
+ pattern.step = READ_BE_UINT16(&patternPtr[2]);
+ continue;
+
+ case 3: // Wait. Paramters: ticks to wait
+ pattern.wait = patternPtr[1];
+ return false;
+
+ case 14: // Stop custompattern
+ // TODO ?
+ warnPatternUnimplemented(patternPtr, 1);
+ // FT
+ case 4: // Stop this pattern
+ pattern.command = 0xFF;
+ --pattern.step;
+ // TODO: try figuring out if this was the last Channel?
+ return false;
+
+ case 5: // Key Up Signal
+ if (!_channelCtx[patternPtr[2] & (kNumVoices - 1)].sfxLocked)
+ _channelCtx[patternPtr[2] & (kNumVoices - 1)].keyUp = true;
+ continue;
+
+ case 6: // Vibrato
+ case 7: // Envelope
+ noteCommand(pattCmd, patternPtr[1], patternPtr[2], patternPtr[3]);
+ continue;
+
+ case 8: // Subroutine
+ warnPatternUnimplemented(patternPtr, 0);
+ continue;
+
+ case 9: // Return from Subroutine
+ warnPatternUnimplemented(patternPtr, 0);
+ continue;
+
+ case 10: // fade master volume
+ _playerCtx.fadeCount = _playerCtx.fadeSkip = patternPtr[1];
+ _playerCtx.fadeEndVolume = (int8)patternPtr[3];
+ if (_playerCtx.fadeSkip) {
+ const int diff = _playerCtx.fadeEndVolume - _playerCtx.volume;
+ _playerCtx.fadeDelta = (diff != 0) ? ((diff > 0) ? 1 : -1) : 0;
+ } else {
+ _playerCtx.volume = _playerCtx.fadeEndVolume;
+ _playerCtx.fadeDelta = 0;
+ }
+ ++_trackCtx.posInd;
+ continue;
+
+ case 11: { // play pattern. Parameters: patternCmd, channel, expose
+ PatternContext &target = _patternCtx[patternPtr[2] & (kNumChannels - 1)];
+
+ target.command = patternPtr[1];
+ target.offset = _patternOffset[patternPtr[1] & (kMaxPatternOffsets - 1)];
+ target.expose = patternPtr[3];
+ target.step = 0;
+ target.wait = 0;
+ target.loopCount = 0xFF;
+ }
+ continue;
+
+ case 12: // Lock
+ _channelCtx[patternPtr[2] & (kNumVoices - 1)].sfxLocked = (patternPtr[1] != 0);
+ _channelCtx[patternPtr[2] & (kNumVoices - 1)].sfxLockTime = patternPtr[3];
+ continue;
+
+ case 13: // Cue
+ if (_playerCtx.signal)
+ _playerCtx.signal[patternPtr[1]] = READ_BE_UINT16(&patternPtr[2]);
+ continue;
+
+ case 15: // NOP
+ continue;
+ }
+ }
+ }
+}
+
+bool Tfmx::trackRun(const bool incStep) {
+ assert(_playerCtx.song >= 0);
+ if (incStep) {
+ // TODO Optionally disable looping
+ if (_trackCtx.posInd == _trackCtx.stopInd)
+ _trackCtx.posInd = _trackCtx.startInd;
+ else
+ ++_trackCtx.posInd;
+ }
+ for (;;) {
+ const uint16 *const trackData = _resource.getTrackPtr(_trackCtx.posInd);
+
+ 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].step = 0;
+ _patternCtx[i].wait = 0;
+ _patternCtx[i].loopCount = 0xFF;
+ _patternCtx[i].offset = _patternOffset[patNum];
+ }
+ _patternCtx[i].command = (uint8)patNum;
+ _patternCtx[i].expose = patCmd & 0xFF;
+ }
+ return true;
+
+ } else {
+ // 16 byte Trackstep Command
+ switch (READ_BE_UINT16(&trackData[1])) {
+ case 0: // Stop Player. No Parameters
+ stopPaula();
+ return false;
+
+ case 1: // Branch/Loop section of tracksteps. Parameters: branch target, loopcount
+ if (_trackCtx.loopCount != 0) {
+ if (_trackCtx.loopCount < 0)
+ _trackCtx.loopCount = READ_BE_UINT16(&trackData[3]);
+ _trackCtx.posInd = READ_BE_UINT16(&trackData[2]);
+ continue;
+ }
+ --_trackCtx.loopCount;
+ break;
+
+ case 2: { // Set Tempo. Parameters: tempo, divisor
+ _playerCtx.patternCount = _playerCtx.patternSkip = READ_BE_UINT16(&trackData[2]); // tempo
+ const uint16 temp = READ_BE_UINT16(&trackData[3]); // divisor
+
+ if (!(temp & 0x8000) && (temp & 0x1FF))
+ setInterruptFreqUnscaled(temp & 0x1FF);
+ break;
+ }
+ case 4: // Fade
+ _playerCtx.fadeCount = _playerCtx.fadeSkip = (uint8)READ_BE_UINT16(&trackData[2]);
+ _playerCtx.fadeEndVolume = (int8)READ_BE_UINT16(&trackData[3]);
+
+ if (_playerCtx.fadeSkip) {
+ const int diff = _playerCtx.fadeEndVolume - _playerCtx.volume;
+ _playerCtx.fadeDelta = (diff != 0) ? ((diff > 0) ? 1 : -1) : 0;
+ } else {
+ _playerCtx.volume = _playerCtx.fadeEndVolume;
+ _playerCtx.fadeDelta = 0;
+ }
+ break;
+
+ case 3: // Unknown, stops player aswell
+ default:
+ debug("Unknown Command: %02X", READ_BE_UINT16(&trackData[1]));
+ // MI-Player handles this by stopping the player, we just continue
+ }
+ }
+
+ if (_trackCtx.posInd == _trackCtx.stopInd) {
+ warning("Tfmx: Reached invalid Song-Position");
+ return false;
+ }
+ ++_trackCtx.posInd;
+ }
+}
+
+void Tfmx::noteCommand(const uint8 note, const uint8 param1, const uint8 param2, const uint8 param3) {
+ ChannelContext &channel = _channelCtx[param2 & (kNumVoices - 1)];
+
+ 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.macroIndex = param1 & (kMaxMacroOffsets - 1);
+ channel.macroOffset = _macroOffset[param1 & (kMaxMacroOffsets - 1)];
+ channel.relVol = (param2 >> 4) & 0xF;
+ channel.fineTune = (int8)param3;
+
+ initMacroProgramm(channel);
+ channel.keyUp = false; // key down = playing a Note
+
+ } else if (note < 0xF0) { // Portamento
+ channel.portaSkip = param1;
+ channel.portaCount = 1;
+ if (!channel.portaDelta)
+ channel.portaValue = channel.refPeriod;
+ channel.portaDelta = param3;
+
+ channel.note = note & 0x3F;
+ channel.refPeriod = noteIntervalls[channel.note];
+ } else switch (note & 0xF) { // Command
+ case 5: // Key Up Signal
+ channel.keyUp = true;
+ break;
+ case 6: // Vibratio
+ channel.vibLength = param1 & 0xFE;
+ channel.vibCount = param1 / 2;
+ channel.vibValue = 0;
+ break;
+ case 7: // Envelope
+ channel.envDelta = param1;
+ channel.envSkip = channel.envCount = (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();
+ _resource.sfxTableOffset = 0x200;
+ bool getSfxIndex = false;
+
+ // This is how MI`s TFMX-Player tests for unpacked Modules.
+ if (offTrackstep == 0) {
+ offTrackstep = 0x600 + 0x200;
+ offPatternP = 0x200 + 0x200;
+ offMacroP = 0x400 + 0x200;
+ getSfxIndex = true;
+ _resource.sfxTableOffset = 0x5FC;
+ }
+
+ _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);
+
+ if (getSfxIndex)
+ _resource.sfxTableOffset = _patternOffset[127];
+
+ // 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 note, int macro, int relVol, int finetune, int channelNo) {
+ assert(0 <= macro && macro < kMaxMacroOffsets);
+ assert(0 <= note && note < 0xC0);
+ Common::StackLock lock(_mutex);
+
+ channelNo &= (kNumVoices - 1);
+ ChannelContext &channel = _channelCtx[channelNo];
+ unlockMacroChannel(channel);
+
+ noteCommand((uint8)note, (uint8)macro, (uint8)(relVol << 4) | channelNo, (uint8)finetune);
+ startPaula();
+}
+
+void Tfmx::stopSong(bool stopAudio) {
+ Common::StackLock lock(_mutex);
+ _playerCtx.song = -1;
+ if (stopAudio) {
+ stopMacroChannels();
+ stopPaula();
+ }
+}
+
+void Tfmx::doSong(int songPos, bool stopAudio) {
+ assert(0 <= songPos && songPos < kNumSubsongs);
+ Common::StackLock lock(_mutex);
+
+ stopPatternChannels();
+ if (stopAudio) {
+ stopMacroChannels();
+ stopPaula();
+ }
+
+ _playerCtx.song = (int8)songPos;
+
+ _trackCtx.loopCount = -1;
+ _trackCtx.startInd = _trackCtx.posInd = _subsong[songPos].songstart;
+ _trackCtx.stopInd = _subsong[songPos].songend;
+
+ const bool palFlag = (_resource.headerFlags & 2) != 0;
+ const uint16 tempo = _subsong[songPos].tempo;
+ uint16 ciaIntervall;
+ if (tempo >= 0x10) {
+ ciaIntervall = (uint16)(kCiaBaseInterval / tempo);
+ _playerCtx.patternSkip = 0;
+ } else {
+ ciaIntervall = palFlag ? (uint16)kPalDefaultCiaVal : (uint16)kNtscDefaultCiaVal;
+ _playerCtx.patternSkip = tempo;
+ }
+ setInterruptFreqUnscaled(ciaIntervall);
+
+ _playerCtx.patternCount = 0;
+ if (trackRun())
+ startPaula();
+}
+
+int Tfmx::doSfx(uint16 sfxIndex, bool unlockChannel) {
+ assert(0 <= sfxIndex && sfxIndex < 128);
+ Common::StackLock lock(_mutex);
+
+ const byte *sfxEntry = _resource.getSfxPtr(sfxIndex);
+ if (sfxEntry[0] == 0xFB) {
+ // custompattern
+ const uint8 patCmd = sfxEntry[2];
+ const int8 patExp = (int8)sfxEntry[3];
+ } else {
+ // custommacro
+ const byte channelNo = ((_playerCtx.song >= 0) ? sfxEntry[2] : sfxEntry[4]) & (kNumVoices - 1);
+ const byte priority = sfxEntry[5] & 0x7F;
+
+ ChannelContext &channel = _channelCtx[channelNo];
+ if (unlockChannel)
+ unlockMacroChannel(channel);
+
+ const int16 sfxLocktime = channel.sfxLockTime;
+ if (priority >= channel.customMacroPrio || sfxLocktime < 0) {
+ if (sfxIndex != channel.customMacroIndex || sfxLocktime < 0 || (sfxEntry[5] < 0x80)) {
+ channel.customMacro = READ_UINT32(sfxEntry); // intentionally not "endian-correct"
+ channel.customMacroPrio = priority;
+ channel.customMacroIndex = (uint8)sfxIndex;
+ debug(3, "Tfmx: running Macro %08X on channel %i - priority: %02X", TO_BE_32(channel.customMacro), channelNo, priority);
+ return channelNo;
+ }
+ }
+ }
+ return -1;
+}
+
+} // End of namespace Audio
diff --git a/sound/mods/tfmx.h b/sound/mods/tfmx.h
new file mode 100644
index 0000000000..2f05b0da70
--- /dev/null
+++ b/sound/mods/tfmx.h
@@ -0,0 +1,296 @@
+/* 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 stopSong(bool stopAudio = true);
+ void doSong(int songPos, bool stopAudio = false);
+ int doSfx(uint16 sfxIndex, bool unlockChannel = false);
+ void doMacro(int note, int macro, int relVol = 0, int finetune = 0, int channelNo = 0);
+ bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData);
+ int getTicks() const { return _playerCtx.tickCount; }
+ int getSongIndex() const { return _playerCtx.song; }
+ void setSignalPtr(uint16 *ptr) { _playerCtx.signal = ptr; }
+ void stopMacroEffect(int channel) {
+ assert(0 <= channel && channel < kNumVoices);
+ Common::StackLock lock(_mutex);
+ unlockMacroChannel(_channelCtx[channel]);
+ clearMacroProgramm(_channelCtx[channel]);
+ Paula::disableChannel(_channelCtx[channel].paulaChannel);
+ }
+
+// 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
+ uint32 sfxTableOffset;
+
+ 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 byte *getSfxPtr(uint16 index = 0) {
+ byte *sfxPtr = (byte *)(mdatData + sfxTableOffset + index * 8);
+
+ boundaryCheck(mdatData, mdatLen, sfxPtr, 8);
+ return sfxPtr;
+ }
+
+ 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 *sample = (int8 *)(sampleData + offset);
+
+ boundaryCheck(sampleData, sampleLen, sample, 2);
+ return sample;
+ }
+ 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;
+
+ byte macroIndex;
+ uint16 macroWait;
+ uint32 macroOffset;
+ uint32 macroReturnOffset;
+ uint16 macroStep;
+ uint16 macroReturnStep;
+ uint8 macroLoopCount;
+ bool macroRun;
+ int8 macroSfxRun;
+
+ uint32 customMacro;
+ uint8 customMacroIndex;
+ uint8 customMacroPrio;
+
+ bool sfxLocked;
+ int16 sfxLockTime;
+ bool keyUp;
+
+ bool deferWait;
+ uint16 dmaIntCount;
+
+ uint32 sampleStart;
+ uint16 sampleLen;
+ uint16 refPeriod;
+ uint16 period;
+
+ int8 volume;
+ uint8 relVol;
+ uint8 note;
+ uint8 prevNote;
+ int16 fineTune; // always a signextended byte
+
+ uint8 portaSkip;
+ uint8 portaCount;
+ uint16 portaDelta;
+ uint16 portaValue;
+
+ uint8 envSkip;
+ uint8 envCount;
+ uint8 envDelta;
+ int8 envEndVolume;
+
+ uint8 vibLength;
+ uint8 vibCount;
+ int16 vibValue;
+ int8 vibDelta;
+
+ uint8 addBeginLength;
+ uint8 addBeginCount;
+ int32 addBeginDelta;
+ } _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 {
+ int8 song; //!< >= 0 if Song is running (means process Patterns)
+
+ uint16 patternCount;
+ uint16 patternSkip; //!< skip that amount of CIA-Interrupts
+
+ int8 volume; //!< Master Volume
+
+ uint8 fadeSkip;
+ uint8 fadeCount;
+ int8 fadeEndVolume;
+ int8 fadeDelta;
+
+ int tickCount;
+
+ uint16 *signal;
+
+ bool stopWithLastPattern; //!< hack to automatically stop the whole player if no Pattern is running
+ } _playerCtx;
+private:
+ static void initMacroProgramm(ChannelContext &channel) {
+ channel.macroStep = 0;
+ channel.macroWait = 0;
+ channel.macroRun = true;
+ channel.macroSfxRun = 0;
+ channel.macroLoopCount = 0xFF;
+ channel.dmaIntCount = 0;
+ }
+
+ static void clearEffects(ChannelContext &channel) {
+ channel.addBeginLength = 0;
+ channel.envSkip = 0;
+ channel.vibLength = 0;
+ channel.portaDelta = 0;
+ }
+
+ static void clearMacroProgramm(ChannelContext &channel) {
+ channel.macroRun = false;
+ channel.macroSfxRun = 0;
+ channel.dmaIntCount = 0;
+ }
+
+ static void unlockMacroChannel(ChannelContext &channel) {
+ channel.customMacro = 0;
+ channel.customMacroPrio = false;
+ channel.sfxLocked = false;
+ channel.sfxLockTime = -1;
+ }
+
+ void stopPatternChannels() {
+ for (int i = 0; i < kNumChannels; ++i) {
+ _patternCtx[i].command = 0xFF;
+ _patternCtx[i].expose = 0;
+ }
+ }
+
+ void stopMacroChannels() {
+ for (int i = 0; i < kNumVoices; ++i) {
+ clearEffects(_channelCtx[i]);
+ unlockMacroChannel(_channelCtx[i]);
+ clearMacroProgramm(_channelCtx[i]);
+ _channelCtx[i].note = 0;
+ _channelCtx[i].volume = 0;
+ }
+ }
+
+ static void setNoteMacro(ChannelContext &channel, uint note, int fineTune) {
+ const uint16 noteInt = noteIntervalls[note & 0x3F];
+ const uint16 finetune = (uint16)(fineTune + channel.fineTune + (1 << 8));
+ channel.refPeriod = ((uint32)noteInt * finetune >> 8);
+ if (!channel.portaDelta)
+ channel.period = channel.refPeriod;
+ }
+
+ void effects(ChannelContext &channel);
+ void macroRun(ChannelContext &channel);
+ void advancePatterns();
+ bool patternRun(PatternContext &pattern);
+ bool trackRun(bool incStep = false);
+ void noteCommand(uint8 note, uint8 param1, uint8 param2, uint8 param3);
+};
+
+} // End of namespace Audio
+
+#endif
diff --git a/sound/module.mk b/sound/module.mk
index 3bcdd47c56..aabe7fe729 100644
--- a/sound/module.mk
+++ b/sound/module.mk
@@ -24,11 +24,13 @@ MODULE_OBJS := \
vorbis.o \
wave.o \
mods/infogrames.o \
+ mods/maxtrax.o \
mods/module.o \
mods/protracker.o \
mods/paula.o \
mods/rjp1.o \
mods/soundfx.o \
+ mods/tfmx.o \
softsynth/adlib.o \
softsynth/opl/dosbox.o \
softsynth/opl/mame.o \
diff --git a/tfmx/module.mk b/tfmx/module.mk
new file mode 100644
index 0000000000..5227ae7e7e
--- /dev/null
+++ b/tfmx/module.mk
@@ -0,0 +1,9 @@
+MODULE := tfmx
+
+MODULE_OBJS := \
+ mxtxplayer.o \
+ tfmxplayer.o \
+ tfmxdebug.o
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/tfmx/mxtxplayer.cpp b/tfmx/mxtxplayer.cpp
new file mode 100644
index 0000000000..f3c6887a2b
--- /dev/null
+++ b/tfmx/mxtxplayer.cpp
@@ -0,0 +1,148 @@
+#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/maxtrax.h"
+
+#if defined(MXTX_CMDLINE_TOOL)
+
+#define FILEDIR ""
+
+using namespace Common;
+
+#define MUSICFILE "introscr.mx"
+#define SAMPLEFILE "introinst.mx"
+
+Audio::MaxTrax *loadMtmxfile(const char *mdatName, const char *smplName) {
+ FSNode fileDir(FILEDIR);
+ FSNode musicNode = fileDir.getChild(mdatName);
+ FSNode sampleNode = fileDir.getChild(smplName);
+ SeekableReadStream *musicIn = musicNode.createReadStream();
+ if (0 == musicIn) {
+ debug("Couldnt load file %s", mdatName);
+ return 0;
+ }
+
+ Audio::MaxTrax *mxtxPlay = new Audio::MaxTrax(44100, true);
+
+ if (strcmp(mdatName, smplName)) {
+ SeekableReadStream *sampleIn = sampleNode.createReadStream();
+ if (0 == sampleIn) {
+ debug("Couldnt load file %s", smplName);
+ delete musicIn;
+ return 0;
+ }
+ mxtxPlay->load(*musicIn, true, false);
+ mxtxPlay->load(*sampleIn, false, true);
+ delete sampleIn;
+ } else {
+ mxtxPlay->load(*musicIn, true, true);
+ }
+
+ delete musicIn;
+
+ return mxtxPlay;
+}
+
+void runFlac(int chan, int bits, int sr, const char *fileName);
+
+void modcmdmain(const int argc, const char *const argv[]) {
+ debug("Started Scumm&VM");
+ debug("Sound celebrating utility for malcoms menace & Various Malfunctions");
+ debug("");
+
+ Audio::MaxTrax *player = loadMtmxfile(MUSICFILE, SAMPLEFILE);
+ if (!player) {
+ debug("couldnt create MXTX-Player");
+ return;
+ }
+
+ int i = 1;
+ int playflag = 1;
+ bool hasCmd = false;
+
+
+ while (i < argc && argv[i][0] == '-') {
+ int param;
+ if (!strcmp("-s", argv[i])) {
+ if (i + 1 < argc) {
+ param = atoi(argv[++i]);
+ debug( "play Song %02X", param);
+
+ player->doSong(param);
+
+ //player->noteOn(player->_channelCtx[0], 43, 64, 0);
+
+
+ hasCmd = true;
+ }
+ } else if (!strcmp("-flac", argv[i])) {
+ playflag = 2;
+ }
+ ++i;
+ }
+
+ if (!hasCmd) {
+
+ }
+
+ int maxsecs = 10 * 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");
+ }
+ delete player;
+
+#ifdef _MSC_VER
+ printf("\npress a key");
+ getc(stdin);
+#endif
+}
+
+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);
+}
+
+#endif // #if defined(MXTX_CMDLINE_TOOL) \ No newline at end of file
diff --git a/tfmx/tfmxdebug.cpp b/tfmx/tfmxdebug.cpp
new file mode 100644
index 0000000000..95bad15a96
--- /dev/null
+++ b/tfmx/tfmxdebug.cpp
@@ -0,0 +1,200 @@
+#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]",
+ "Cue [number.b/ value.w]",
+ "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 "
+};
+
+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, int chan, int index) {
+ const byte *const macroData = (const byte *const)vptr;
+
+ if (macroData[0] < ARRAYSIZE(macrocmds))
+ debug("%02X %02X %s %02X%02X%02X", chan, index, macrocmds[macroData[0]], macroData[1], macroData[2], macroData[3]);
+ else
+ debug("%02X %02X Unkown Macro #%02X %02X%02X%02X", chan, index, macroData[0], macroData[1], macroData[2], macroData[3]);
+}
+
+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) {
+ debug("Song %02X: Pos %02X - %02X. Tempo: %02X", song, player._subsong[song].songstart, player._subsong[song].songend, player._subsong[song].tempo);
+ dumpTracksteps(player, player._subsong[song].songstart, player._subsong[song].songend);
+ debug("");
+}
+
+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);
+ }
+
+}
diff --git a/tfmx/tfmxdebug.h b/tfmx/tfmxdebug.h
new file mode 100644
index 0000000000..e849e561a9
--- /dev/null
+++ b/tfmx/tfmxdebug.h
@@ -0,0 +1,14 @@
+#ifndef TFMXDEBUG_H
+#define TFMXDEBUG_H
+
+void displayTrackstep(const void *const vptr);
+void displayPatternstep(const void *const vptr);
+void displayMacroStep(const void *const vptr);
+void displayMacroStep(const void *const vptr, int chan, int index);
+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
diff --git a/tfmx/tfmxplayer.cpp b/tfmx/tfmxplayer.cpp
new file mode 100644
index 0000000000..16b71c5496
--- /dev/null
+++ b/tfmx/tfmxplayer.cpp
@@ -0,0 +1,171 @@
+#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/tfmx.h"
+
+#if defined(TFMX_CMDLINE_TOOL)
+
+#include "tfmx/tfmxdebug.h"
+
+#define FILEDIR ""
+
+using namespace Common;
+
+#define MUSICFILE "mdat.monkey"
+#define SAMPLEFILE "smpl.monkey"
+
+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", mdatName);
+ return 0;
+ }
+
+ SeekableReadStream *sampleIn = sampleNode.createReadStream();
+ if (0 == sampleIn) {
+ debug("Couldnt load file %s", sampleName);
+ 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 modcmdmain(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 = 1;
+ bool hasCmd = false;
+
+
+ while (i < argc && argv[i][0] == '-') {
+ int param;
+ if (!strcmp("-m", argv[i])) {
+ if (i + 1 < argc) {
+ param = atoi(argv[++i]);
+ debug( "play Macro %02X", param);
+ dumpMacro(*player, param);
+ player->doMacro(0x1B, param);
+ hasCmd = true;
+ }
+ } else if (!strcmp("-s", argv[i])) {
+ if (i + 1 < argc) {
+ param = atoi(argv[++i]);
+ debug( "play Song %02X", param);
+ dumpTrackstepsBySong(*player, param);
+ player->doSong(param);
+ hasCmd = true;
+ }
+ } else if (!strcmp("-c", argv[i])) {
+ if (i + 1 < argc) {
+ param = atoi(argv[++i]);
+ debug( "play custom %02X", param);
+ if (player->getSongIndex() < 0)
+ player->doSong(0x18);
+ player->doSfx(param);
+ hasCmd = true;
+ }
+ } else if (!strcmp("-flac", argv[i])) {
+ playflag = 2;
+ } else if (!strcmp("-hack-patternstop", argv[i]))
+ player->_playerCtx.stopWithLastPattern = true;
+ ++i;
+ }
+
+ if (!hasCmd) {
+ player->doSong(4);
+ dumpTrackstepsBySong(*player, 4);
+ }
+
+
+
+
+#if 0
+ int16 buf[2 * 1024];
+
+ while( true)
+ player->readBuffer(buf, ARRAYSIZE(buf));
+#endif
+ int maxsecs = 10 * 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");
+ }
+
+#ifdef _MSC_VER
+ printf("\npress a key");
+ getc(stdin);
+#endif
+
+ 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);
+}
+
+#endif // #if defined(TFMX_CMDLINE_TOOL)