diff options
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 "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + Outputs="$(OutDir)\$(InputName).obj" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + CommandLine="nasm.exe -f win32 -o "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + Outputs="$(OutDir)\$(InputName).obj" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug_Command|Win32" + > + <Tool + Name="VCCustomBuildTool" + CommandLine="nasm.exe -f win32 -g -o "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + Outputs="$(OutDir)\$(InputName).obj" + /> + </FileConfiguration> + <FileConfiguration + Name="Release_Command|Win32" + > + <Tool + Name="VCCustomBuildTool" + CommandLine="nasm.exe -f win32 -o "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + 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 "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + Outputs="$(OutDir)\$(InputName).obj" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + CommandLine="nasm.exe -f win32 -o "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + Outputs="$(OutDir)\$(InputName).obj" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug_Command|Win32" + > + <Tool + Name="VCCustomBuildTool" + CommandLine="nasm.exe -f win32 -g -o "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + Outputs="$(OutDir)\$(InputName).obj" + /> + </FileConfiguration> + <FileConfiguration + Name="Release_Command|Win32" + > + <Tool + Name="VCCustomBuildTool" + CommandLine="nasm.exe -f win32 -o "$(OutDir)\$(InputName).obj" "$(InputPath)"
" + 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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[2])); + break; + + case 0x09: // SetNote. Parameters: Note, Finetune(W) + setNoteMacro(channel, macroPtr[1], READ_BE_UINT16(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[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(¯oPtr[2]); + continue; + + case 0x1D: // Branch on Volume. Parameters: volume/macrostep(W) + if (channel.volume > macroPtr[1]) + channel.macroStep = READ_BE_UINT16(¯oPtr[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(¯oPtr[2])); + break; + + case 0x20: // Signal. Parameters: signalnumber/value + if (_playerCtx.signal) + _playerCtx.signal[macroPtr[1]] = READ_BE_UINT16(¯oPtr[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) |