[Scummvm-cvs-logs] SF.net SVN: scummvm: [22588] scummvm/trunk

aquadran at users.sourceforge.net aquadran at users.sourceforge.net
Tue May 23 16:46:13 CEST 2006


Revision: 22588
Author:   aquadran
Date:     2006-05-23 16:43:52 -0700 (Tue, 23 May 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22588&view=rev

Log Message:
-----------
imported AGI engine

Modified Paths:
--------------
    scummvm/trunk/AUTHORS
    scummvm/trunk/base/plugins.cpp
    scummvm/trunk/dists/msvc8/gob.vcproj
    scummvm/trunk/dists/msvc8/kyra.vcproj
    scummvm/trunk/dists/msvc8/scummvm.sln
    scummvm/trunk/dists/msvc8/scummvm.vcproj
    scummvm/trunk/doc/credits.tex
    scummvm/trunk/gui/credits.h
    scummvm/trunk/tools/credits.pl

Added Paths:
-----------
    scummvm/trunk/dists/msvc8/agi.vcproj
    scummvm/trunk/engines/agi/
    scummvm/trunk/engines/agi/agi.cpp
    scummvm/trunk/engines/agi/agi.h
    scummvm/trunk/engines/agi/agi_v2.cpp
    scummvm/trunk/engines/agi/agi_v3.cpp
    scummvm/trunk/engines/agi/checks.cpp
    scummvm/trunk/engines/agi/console.cpp
    scummvm/trunk/engines/agi/console.h
    scummvm/trunk/engines/agi/cycle.cpp
    scummvm/trunk/engines/agi/font.cpp
    scummvm/trunk/engines/agi/global.cpp
    scummvm/trunk/engines/agi/graphics.cpp
    scummvm/trunk/engines/agi/graphics.h
    scummvm/trunk/engines/agi/id.cpp
    scummvm/trunk/engines/agi/inv.cpp
    scummvm/trunk/engines/agi/keyboard.cpp
    scummvm/trunk/engines/agi/keyboard.h
    scummvm/trunk/engines/agi/list.h
    scummvm/trunk/engines/agi/logic.cpp
    scummvm/trunk/engines/agi/logic.h
    scummvm/trunk/engines/agi/lzw.cpp
    scummvm/trunk/engines/agi/lzw.h
    scummvm/trunk/engines/agi/menu.cpp
    scummvm/trunk/engines/agi/menu.h
    scummvm/trunk/engines/agi/module.mk
    scummvm/trunk/engines/agi/motion.cpp
    scummvm/trunk/engines/agi/objects.cpp
    scummvm/trunk/engines/agi/op_cmd.cpp
    scummvm/trunk/engines/agi/op_dbg.cpp
    scummvm/trunk/engines/agi/op_test.cpp
    scummvm/trunk/engines/agi/opcodes.h
    scummvm/trunk/engines/agi/patches.cpp
    scummvm/trunk/engines/agi/picture.cpp
    scummvm/trunk/engines/agi/picture.h
    scummvm/trunk/engines/agi/savegame.cpp
    scummvm/trunk/engines/agi/savegame.h
    scummvm/trunk/engines/agi/sound.cpp
    scummvm/trunk/engines/agi/sound.h
    scummvm/trunk/engines/agi/sprite.cpp
    scummvm/trunk/engines/agi/sprite.h
    scummvm/trunk/engines/agi/text.cpp
    scummvm/trunk/engines/agi/text.h
    scummvm/trunk/engines/agi/view.cpp
    scummvm/trunk/engines/agi/view.h
    scummvm/trunk/engines/agi/words.cpp
Modified: scummvm/trunk/AUTHORS
===================================================================
--- scummvm/trunk/AUTHORS	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/AUTHORS	2006-05-23 23:43:52 UTC (rev 22588)
@@ -24,6 +24,10 @@
        Gregory Montoir      
        Eugene Sandulenko    
 
+    AGI:
+       Pawel Kolodziejski   
+       Eugene Sandulenko    
+
     BASS:
        Robert Goeffringmann 
        Oliver Kiehl         
@@ -193,6 +197,7 @@
    Jezar            - For his freeverb filter implementation
    Jim Leiterman    - Various info on his FM-TOWNS/Marty SCUMM ports
    lloyd            - For deep tech details about C64 Zak & MM
+   Sarien Team      - Original AGI engine code
    Jimmi Thogersen  - For ScummRev, and much obscure code/documentation
    Tristan          - For additional work on the original MT-32 emulator
 

Modified: scummvm/trunk/base/plugins.cpp
===================================================================
--- scummvm/trunk/base/plugins.cpp	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/base/plugins.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -368,6 +368,9 @@
 	#ifndef DISABLE_CINE
 	LINK_PLUGIN(CINE)
 	#endif
+	#ifndef DISABLE_CINE
+	LINK_PLUGIN(AGI)
+	#endif
 
 #endif
 }

Added: scummvm/trunk/dists/msvc8/agi.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/agi.vcproj	                        (rev 0)
+++ scummvm/trunk/dists/msvc8/agi.vcproj	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="agi"
+	ProjectGUID="{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}"
+	RootNamespace="agi"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="agi_Debug"
+			IntermediateDirectory="agi_Debug"
+			ConfigurationType="4"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702 /wd4996"
+				Optimization="0"
+				AdditionalIncludeDirectories="../..;../../engines"
+				PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS"
+				MinimalRebuild="true"
+				ExceptionHandling="1"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="true"
+				EnableFunctionLevelLinking="true"
+				ForceConformanceInForLoopScope="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				WarnAsError="false"
+				SuppressStartupBanner="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="$(OutDir)/agi.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="agi_Release"
+			IntermediateDirectory="agi_Release"
+			ConfigurationType="4"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702 /wd4996"
+				Optimization="3"
+				InlineFunctionExpansion="2"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="../../;../../common"
+				PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS"
+				StringPooling="true"
+				ExceptionHandling="1"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="false"
+				ForceConformanceInForLoopScope="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				WarnAsError="true"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="$(OutDir)/agi.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\engines\agi\agi.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\agi.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\agi_v2.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\agi_v3.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\checks.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\console.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\console.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\cycle.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\font.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\global.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\graphics.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\graphics.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\id.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\inv.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\keyboard.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\keyboard.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\list.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\logic.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\logic.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\lzw.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\lzw.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\menu.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\menu.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\motion.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\objects.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\op_cmd.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\op_dbg.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\op_test.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\opcodes.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\patches.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\picture.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\picture.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\savegame.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\savegame.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\sound.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\sound.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\sprite.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\sprite.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\text.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\text.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\view.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\view.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\agi\words.cpp"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>


Property changes on: scummvm/trunk/dists/msvc8/agi.vcproj
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:eol-style
   + native

Modified: scummvm/trunk/dists/msvc8/gob.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/gob.vcproj	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/dists/msvc8/gob.vcproj	2006-05-23 23:43:52 UTC (rev 22588)
@@ -4,6 +4,7 @@
 	Version="8,00"
 	Name="gob"
 	ProjectGUID="{976D947A-A45F-4437-991E-412F695C64C7}"
+	RootNamespace="gob"
 	Keyword="Win32Proj"
 	>
 	<Platforms>
@@ -247,6 +248,14 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\engines\gob\goblin_v1.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\gob\goblin_v2.cpp"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\gob\init.cpp"
 			>
 		</File>
@@ -287,6 +296,14 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\engines\gob\map_v1.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\gob\map_v2.cpp"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\gob\mult.cpp"
 			>
 		</File>

Modified: scummvm/trunk/dists/msvc8/kyra.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/kyra.vcproj	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/dists/msvc8/kyra.vcproj	2006-05-23 23:43:52 UTC (rev 22588)
@@ -4,6 +4,7 @@
 	Version="8,00"
 	Name="kyra"
 	ProjectGUID="{9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}"
+	RootNamespace="kyra"
 	Keyword="Win32Proj"
 	>
 	<Platforms>
@@ -191,6 +192,10 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\engines\kyra\kyra3.cpp"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\kyra\plugin.cpp"
 			>
 		</File>
@@ -255,6 +260,10 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\engines\kyra\sound_digital.cpp"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\kyra\sprites.cpp"
 			>
 		</File>
@@ -279,6 +288,14 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\engines\kyra\vqa.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\engines\kyra\vqa.h"
+			>
+		</File>
+		<File
 			RelativePath="..\..\engines\kyra\wsamovie.cpp"
 			>
 		</File>

Modified: scummvm/trunk/dists/msvc8/scummvm.sln
===================================================================
--- scummvm/trunk/dists/msvc8/scummvm.sln	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/dists/msvc8/scummvm.sln	2006-05-23 23:43:52 UTC (rev 22588)
@@ -1,15 +1,16 @@
 Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual C++ Express 2005
+# Visual Studio 2005
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scummvm", "scummvm.vcproj", "{8434CB15-D08F-427D-9E6D-581AE5B28440}"
 	ProjectSection(ProjectDependencies) = postProject
 		{6CC3E421-779D-4E80-8100-520886A0F9FF} = {6CC3E421-779D-4E80-8100-520886A0F9FF}
-		{1CA4AC50-5426-433A-8B5E-FFE39568098E} = {1CA4AC50-5426-433A-8B5E-FFE39568098E}
+		{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E} = {F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}
 		{676DB4C5-9A3E-4EE1-8483-EBB79DC0700E} = {676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}
 		{9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC} = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}
 		{976D947A-A45F-4437-991E-412F695C64C7} = {976D947A-A45F-4437-991E-412F695C64C7}
 		{E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA} = {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA}
 		{6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7} = {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7}
 		{B5527758-2F51-4CCD-AAE1-B0E28654BD6A} = {B5527758-2F51-4CCD-AAE1-B0E28654BD6A}
+		{1CA4AC50-5426-433A-8B5E-FFE39568098E} = {1CA4AC50-5426-433A-8B5E-FFE39568098E}
 		{B6AFD548-63D2-40CD-A652-E87095AFCBAF} = {B6AFD548-63D2-40CD-A652-E87095AFCBAF}
 		{C8AAE83E-198B-4ECA-A877-166827953979} = {C8AAE83E-198B-4ECA-A877-166827953979}
 		{1A1CA028-61B5-4A6C-A918-F5D8721AB1AC} = {1A1CA028-61B5-4A6C-A918-F5D8721AB1AC}
@@ -37,6 +38,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cine", "cine.vcproj", "{1CA4AC50-5426-433A-8B5E-FFE39568098E}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "agi", "agi.vcproj", "{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -91,6 +94,10 @@
 		{1CA4AC50-5426-433A-8B5E-FFE39568098E}.Debug|Win32.Build.0 = Debug|Win32
 		{1CA4AC50-5426-433A-8B5E-FFE39568098E}.Release|Win32.ActiveCfg = Release|Win32
 		{1CA4AC50-5426-433A-8B5E-FFE39568098E}.Release|Win32.Build.0 = Release|Win32
+		{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}.Debug|Win32.Build.0 = Debug|Win32
+		{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}.Release|Win32.ActiveCfg = Release|Win32
+		{F5F57066-CDF4-4F80-B9E7-7F4D21850D6E}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

Modified: scummvm/trunk/dists/msvc8/scummvm.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/scummvm.vcproj	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/dists/msvc8/scummvm.vcproj	2006-05-23 23:43:52 UTC (rev 22588)
@@ -4,6 +4,7 @@
 	Version="8,00"
 	Name="scummvm"
 	ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}"
+	RootNamespace="scummvm"
 	Keyword="Win32Proj"
 	>
 	<Platforms>
@@ -67,7 +68,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib sdl.lib zdll.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib sword1_debug/sword1.lib sword2_debug/sword2.lib lure_debug/lure.lib cine_debug/cine.lib kyra_debug/kyra.lib gob_debug/gob.lib queen_debug/queen.lib saga_debug/saga.lib scumm_debug/scumm.lib simon_debug/simon.lib sky_debug/sky.lib"
+				AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib sword1_debug/sword1.lib sword2_debug/sword2.lib lure_debug/lure.lib cine_debug/cine.lib kyra_debug/kyra.lib gob_debug/gob.lib queen_debug/queen.lib saga_debug/saga.lib agi_debug/agi.lib scumm_debug/scumm.lib simon_debug/simon.lib sky_debug/sky.lib"
 				OutputFile="$(OutDir)/scummvm.exe"
 				LinkIncremental="2"
 				IgnoreDefaultLibraryNames="libc.lib;libcmt.lib"
@@ -155,7 +156,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib sdl.lib zdll.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib saga_release/saga.lib sword1_release/sword1.lib sword2_release/sword2.lib lure_release/lure.lib cine_release/cine.lib kyra_release/kyra.lib gob_release/gob.lib queen_release/queen.lib scumm_release/scumm.lib simon_release/simon.lib sky_release/sky.lib"
+				AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib saga_release/saga.lib agi_release/agi.lib sword1_release/sword1.lib sword2_release/sword2.lib lure_release/lure.lib cine_release/cine.lib kyra_release/kyra.lib gob_release/gob.lib queen_release/queen.lib scumm_release/scumm.lib simon_release/simon.lib sky_release/sky.lib"
 				OutputFile="$(OutDir)/scummvm.exe"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
@@ -998,6 +999,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\graphics\paletteman.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\paletteman.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\graphics\primitives.cpp"
 				>
 			</File>

Modified: scummvm/trunk/doc/credits.tex
===================================================================
--- scummvm/trunk/doc/credits.tex	2006-05-23 20:10:01 UTC (rev 22587)
+++ scummvm/trunk/doc/credits.tex	2006-05-23 23:43:52 UTC (rev 22588)
@@ -34,6 +34,13 @@
     Eugene Sandulenko & \textit{}\\
   \end{tabular}
 \end{list}
+\item \textbf{ AGI}
+\begin{list}{}{\setlength{\leftmargin}{0.2cm}}
+\item  \begin{tabular}[h]{p{0.3\linewidth}p{0.6\linewidth}}
+    Pawe{\l} Ko{\l}odziejski & \textit{}\\
+    Eugene Sandulenko & \textit{}\\
+  \end{tabular}
+\end{list}
 \item \textbf{ BASS}
 \begin{list}{}{\setlength{\leftmargin}{0.2cm}}
 \item  \begin{tabular}[h]{p{0.3\linewidth}p{0.6\linewidth}}
@@ -293,6 +300,7 @@
     Jezar & \textit{For his freeverb filter implementation}\\
     Jim Leiterman & \textit{Various info on his FM-TOWNS/Marty SCUMM ports}\\
     lloyd & \textit{For deep tech details about C64 Zak \& MM}\\
+    Sarien Team & \textit{Original AGI engine code}\\
     Jimmi Th{\o}gersen & \textit{For ScummRev, and much obscure code/documentation}\\
     Tristan & \textit{For additional work on the original MT-32 emulator}\\
   \end{tabular}

Added: scummvm/trunk/engines/agi/agi.cpp
===================================================================
--- scummvm/trunk/engines/agi/agi.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/agi.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,627 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2003 Sarien Team
+ *
+ * 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/stdafx.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/plugins.h"
+
+#include "backends/fs/fs.h"
+
+#include "sound/mididrv.h"
+#include "sound/mixer.h"
+
+#include "agi/agi.h"
+#include "agi/text.h"
+#include "agi/graphics.h"
+#include "agi/sprite.h"
+#include "agi/opcodes.h"
+#include "agi/keyboard.h"
+#include "agi/menu.h"
+#include "agi/savegame.h"
+
+namespace Agi {
+
+void gfx_set_palette();
+
+extern int optind;
+
+struct agi_options opt;
+struct game_id_list game_info;
+struct agi_game game;
+
+static struct agi_loader *loader;	/* loader */
+
+extern struct agi_loader agi_v2;
+extern struct agi_loader agi_v3;
+
+static volatile uint32 tick_timer = 0;
+
+#define TICK_SECONDS 20
+
+static int key_control = 0;
+static int key_alt = 0;
+
+#define KEY_QUEUE_SIZE 16
+
+static int key_queue[KEY_QUEUE_SIZE];
+static int key_queue_start = 0;
+static int key_queue_end = 0;
+
+#define key_enqueue(k) do { key_queue[key_queue_end++] = (k); \
+	key_queue_end %= KEY_QUEUE_SIZE; } while (0)
+#define key_dequeue(k) do { (k) = key_queue[key_queue_start++]; \
+	key_queue_start %= KEY_QUEUE_SIZE; } while (0)
+
+static void process_events() {
+	OSystem::Event event;
+	int key = 0;
+
+	while (g_system->pollEvent(event)) {
+		switch (event.type) {
+		case OSystem::EVENT_QUIT:
+			deinit_video();
+			deinit_machine();
+			g_system->quit();
+			break;
+		case OSystem::EVENT_LBUTTONDOWN:
+			key = BUTTON_LEFT;
+			mouse.button = 1;
+			key_enqueue(key);
+			mouse.x = event.mouse.x;
+			mouse.y = event.mouse.y;
+			break;
+		case OSystem::EVENT_RBUTTONDOWN:
+			key = BUTTON_RIGHT;
+			mouse.button = 2;
+			key_enqueue(key);
+			mouse.x = event.mouse.x;
+			mouse.y = event.mouse.y;
+			break;
+		case OSystem::EVENT_MOUSEMOVE:
+			mouse.x = event.mouse.x;
+			mouse.y = event.mouse.y;
+			break;
+		case OSystem::EVENT_LBUTTONUP:
+		case OSystem::EVENT_RBUTTONUP:
+			mouse.button = 0;
+			break;
+		case OSystem::EVENT_KEYDOWN:
+			if (event.kbd.flags == OSystem::KBD_CTRL) {
+				key_control |= 1;
+				key = 0;
+				break;
+			} else if (event.kbd.flags == OSystem::KBD_ALT) {
+				key_alt |= 1;
+				key = 0;
+				break;
+			} else if (event.kbd.flags == OSystem::KBD_SHIFT) {
+				key = 0;
+				break;
+			}
+
+			switch (key = event.kbd.keycode) {
+			case 256 + 20:	// left arrow
+				key = KEY_LEFT;
+				break;
+			case 256 + 19:	// right arrow
+				key = KEY_RIGHT;
+				break;
+			case 256 + 17:	// up arrow
+				key = KEY_UP;
+				break;
+			case 256 + 18:	// down arrow
+				key = KEY_DOWN;
+				break;
+			case 256 + 24:	// page up
+				key = KEY_UP_RIGHT;
+				break;
+			case 256 + 25:	// page down
+				key = KEY_DOWN_RIGHT;
+				break;
+			case 256 + 22:	// home
+				key = KEY_UP_LEFT;
+				break;
+			case 256 + 23:	// end
+				key = KEY_DOWN_LEFT;
+				break;
+			case '+':
+				key = '+';
+				break;
+			case '-':
+				key = '-';
+				break;
+			case 9:
+				key = 0x0009;
+				break;
+			case 282:
+				key = 0x3b00;
+				break;
+			case 283:
+				key = 0x3c00;
+				break;
+			case 284:
+				key = 0x3d00;
+				break;
+			case 285:
+				key = 0x3e00;
+				break;
+			case 286:
+				key = 0x3f00;
+				break;
+			case 287:
+				key = 0x4000;
+				break;
+			case 288:
+				key = 0x4100;
+				break;
+			case 289:
+				key = 0x4200;
+				break;
+			case 290:
+				key = 0x4300;
+				break;
+			case 291:
+				key = 0x4400;
+				break;
+			case 292:
+				key = KEY_STATUSLN;
+				break;
+			case 293:
+				key = KEY_PRIORITY;
+				break;
+			case 27:
+				key = 0x1b;
+				break;
+			case '\n':
+			case '\r':
+				key = KEY_ENTER;
+				break;
+			default:
+				if (!isalpha(key))
+					break;
+				if (key_control)
+					key = (key & ~0x20) - 0x40;
+				else if (key_alt)
+					key = scancode_table[(key & ~0x20) - 0x41] << 8;
+				break;
+			}
+			if (key)
+				key_enqueue(key);
+			break;
+		case OSystem::EVENT_KEYUP:
+			if (event.kbd.flags == OSystem::KBD_CTRL) {
+				key_control &= ~1;
+				key = 0;
+				break;
+			} else if (event.kbd.flags == OSystem::KBD_ALT) {
+				key_alt &= ~1;
+				key = 0;
+				break;
+			} else if (event.kbd.flags == OSystem::KBD_SHIFT) {
+				key = 0;
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+int agi_is_keypress_low() {
+	process_events();
+	return key_queue_start != key_queue_end;
+}
+
+void agi_timer_low() {
+	static uint32 m = 0;
+	uint32 dm;
+
+	if (tick_timer < m)
+		m = 0;
+
+	while ((dm = tick_timer - m) < 5) {
+		process_events();
+		g_system->delayMillis(10);
+		g_system->updateScreen();
+	}
+	m = tick_timer;
+}
+
+int agi_get_keypress_low() {
+	int k;
+
+	while (key_queue_start == key_queue_end)	/* block */
+		agi_timer_low();
+	key_dequeue(k);
+
+	return k;
+}
+
+static uint32 agi_timer_function_low(uint32 i) {
+	tick_timer++;
+	return i;
+}
+
+static void init_pri_table() {
+	int i, p, y = 0;
+
+	for (p = 1; p < 15; p++) {
+		for (i = 0; i < 12; i++) {
+			game.pri_table[y++] = p < 4 ? 4 : p;
+		}
+	}
+}
+
+int agi_init() {
+	int ec, i;
+
+	debug(2, "initializing");
+	debug(2, "game.ver = 0x%x", game.ver);
+
+	/* reset all flags to false and all variables to 0 */
+	for (i = 0; i < MAX_FLAGS; i++)
+		game.flags[i] = 0;
+	for (i = 0; i < MAX_VARS; i++)
+		game.vars[i] = 0;
+
+	/* clear all resources and events */
+	for (i = 0; i < MAX_DIRS; i++) {
+		memset(&game.views[i], 0, sizeof(struct agi_view));
+		memset(&game.pictures[i], 0, sizeof(struct agi_picture));
+		memset(&game.logics[i], 0, sizeof(struct agi_logic));
+		memset(&game.sounds[i], 0, sizeof(struct agi_sound));
+	}
+
+	/* clear view table */
+	for (i = 0; i < MAX_VIEWTABLE; i++)
+		memset(&game.view_table[i], 0, sizeof(struct vt_entry));
+
+	init_words();
+
+	menu_init();
+	init_pri_table();
+
+	/* clear string buffer */
+	for (i = 0; i < MAX_STRINGS; i++)
+		game.strings[i][0] = 0;
+
+	/* setup emulation */
+
+	switch (loader->int_version >> 12) {
+	case 2:
+		report("Emulating Sierra AGI v%x.%03x\n",
+				(int)(loader->int_version >> 12) & 0xF,
+				(int)(loader->int_version) & 0xFFF);
+		break;
+	case 3:
+		report("Emulating Sierra AGI v%x.002.%03x\n",
+				(int)(loader->int_version >> 12) & 0xF,
+				(int)(loader->int_version) & 0xFFF);
+		break;
+	}
+
+	game.game_flags |= opt.amiga ? ID_AMIGA : 0;
+	game.game_flags |= opt.agds ? ID_AGDS : 0;
+
+	if (game.game_flags & ID_AMIGA)
+		report("Amiga padded game detected.\n");
+
+	if (game.game_flags & ID_AGDS)
+		report("AGDS mode enabled.\n");
+
+	ec = loader->init();	/* load vol files, etc */
+
+	if (ec == err_OK)
+		ec = loader->load_objects(OBJECTS);
+
+	/* note: demogs has no words.tok */
+	if (ec == err_OK)
+		ec = loader->load_words(WORDS);
+
+	/* FIXME: load IIgs instruments and samples */
+	/* load_instruments("kq.sys16"); */
+
+	/* Load logic 0 into memory */
+	if (ec == err_OK)
+		ec = loader->load_resource(rLOGIC, 0);
+
+	return ec;
+}
+
+/*
+ * Public functions
+ */
+
+void agi_unload_resources() {
+	int i;
+
+	/* Make sure logic 0 is always loaded */
+	for (i = 1; i < MAX_DIRS; i++) {
+		loader->unload_resource(rLOGIC, i);
+	}
+	for (i = 0; i < MAX_DIRS; i++) {
+		loader->unload_resource(rVIEW, i);
+		loader->unload_resource(rPICTURE, i);
+		loader->unload_resource(rSOUND, i);
+	}
+}
+
+int agi_deinit() {
+	int ec;
+
+	clean_input();		/* remove all words from memory */
+	agi_unload_resources();	/* unload resources in memory */
+	loader->unload_resource(rLOGIC, 0);
+	ec = loader->deinit();
+	unload_objects();
+	unload_words();
+
+	clear_image_stack();
+
+	return ec;
+}
+
+int agi_detect_game() {
+	int ec = err_OK;
+
+	loader = &agi_v2;
+	ec = loader->detect_game();
+
+	if (ec != err_OK) {
+		loader = &agi_v3;
+		ec = loader->detect_game();
+	}
+
+	return ec;
+}
+
+int agi_version() {
+	return loader->version;
+}
+
+int agi_get_release() {
+	return loader->int_version;
+}
+
+void agi_set_release(int n) {
+	loader->int_version = n;
+}
+
+int agi_load_resource(int r, int n) {
+	int i;
+
+	i = loader->load_resource(r, n);
+#ifdef PATCH_LOGIC
+	if (r == rLOGIC)
+		patch_logic(n);
+#endif
+
+	return i;
+}
+
+int agi_unload_resource(int r, int n) {
+	return loader->unload_resource(r, n);
+}
+
+const char *_savePath;
+extern AGIMusic *g_agi_music;
+
+struct GameSettings {
+	const char *gameid;
+	const char *description;
+	byte id;
+	uint32 features;
+	const char *detectname;
+};
+
+static const GameSettings agi_settings[] = {
+	{"agi", "AGI game", GID_AGI, MDT_ADLIB, "VIEWDIR"},
+	{NULL, NULL, 0, 0, NULL}
+};
+
+Common::RandomSource * rnd;
+
+AgiEngine::AgiEngine(OSystem * syst) : Engine(syst) {
+
+	// Setup mixer
+	if (!_mixer->isReady()) {
+		warning("Sound initialization failed.");
+	}
+
+	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+
+	_savePath = _saveFileMan->getSavePath();
+
+	const GameSettings *g;
+
+	const char *gameid = ConfMan.get("gameid").c_str();
+	for (g = agi_settings; g->gameid; ++g)
+		if (!scumm_stricmp(g->gameid, gameid))
+			_gameId = g->id;
+
+	rnd = new Common::RandomSource();
+
+	game.clock_enabled = false;
+	game.state = STATE_INIT;
+}
+
+void AgiEngine::initialize() {
+	memset(&opt, 0, sizeof(struct agi_options));
+	opt.gamerun = GAMERUN_RUNGAME;
+#ifdef USE_HIRES
+	opt.hires = true;
+#endif
+	opt.soundemu = SOUND_EMU_NONE;
+
+	init_machine();
+
+	game.color_fg = 15;
+	game.color_bg = 0;
+
+	*game.name = 0;
+
+	game.sbuf = (uint8 *) calloc(_WIDTH, _HEIGHT);
+#ifdef USE_HIRES
+	game.hires = (uint8 *) calloc(_WIDTH * 2, _HEIGHT);
+#endif
+
+	init_sprites();
+	init_video();
+
+	tick_timer = 0;
+	Common::g_timer->installTimerProc((Common::Timer::TimerProc) agi_timer_function_low, 10 * 1000, NULL);
+
+	console_init();
+
+	game.ver = -1;		/* Don't display the conf file warning */
+
+	debugC(2, kDebugLevelMain, "Detect game");
+	if (agi_detect_game() == err_OK) {
+		game.state = STATE_LOADED;
+		debugC(2, kDebugLevelMain, "game loaded");
+	} else {
+		report("Could not open AGI game");
+	}
+
+	debugC(2, kDebugLevelMain, "Init sound");
+	init_sound();
+	g_agi_music = new AGIMusic(_mixer);
+}
+
+AgiEngine::~AgiEngine() {
+	agi_deinit();
+	delete g_agi_music;
+	deinit_sound();
+	deinit_video();
+	deinit_sprites();
+#ifdef USE_HIRES
+	free(game.hires);
+#endif
+	free(game.sbuf);
+	deinit_machine();
+	delete rnd;
+}
+
+void AgiEngine::errorString(const char *buf1, char *buf2) {
+	strcpy(buf2, buf1);
+}
+
+int AgiEngine::init() {
+	// Initialize backend
+	_system->beginGFXTransaction();
+	initCommonGFX(false);
+	_system->initSize(320, 200);
+	_system->endGFXTransaction();
+
+	Common::addSpecialDebugLevel(kDebugLevelMain, "Main", "Generic debug level");
+	Common::addSpecialDebugLevel(kDebugLevelResources, "Resources", "Resources debugging");
+	Common::addSpecialDebugLevel(kDebugLevelSprites, "Sprites", "Sprites debugging");
+	Common::addSpecialDebugLevel(kDebugLevelInventory, "Inventory", "Inventory debugging");
+	Common::addSpecialDebugLevel(kDebugLevelInput, "Input", "Input events debugging");
+	Common::addSpecialDebugLevel(kDebugLevelMenu, "Menu", "Menu debugging");
+	Common::addSpecialDebugLevel(kDebugLevelScripts, "Scrpits", "Scripts debugging");
+	Common::addSpecialDebugLevel(kDebugLevelSound, "Sound", "Sound debugging");
+	Common::addSpecialDebugLevel(kDebugLevelText, "Text", "Text output debugging");
+
+	initialize();
+
+	gfx_set_palette();
+
+	return 0;
+}
+
+int AgiEngine::go() {
+	_system->showMouse(true);
+
+	report(" \nAGI engine " VERSION " is ready.\n");
+	if (game.state < STATE_LOADED) {
+		console_prompt();
+		do {
+			main_cycle();
+		} while (game.state < STATE_RUNNING);
+		if (game.ver < 0)
+			game.ver = 0;	/* Enable conf file warning */
+	}
+
+	run_game();
+
+	return 0;
+}
+
+}                             // End of namespace Agi
+
+GameList Engine_AGI_gameIDList() {
+	GameList games;
+	const Agi::GameSettings *g = Agi::agi_settings;
+
+	while (g->gameid) {
+		games.push_back(*g);
+		g++;
+	}
+
+	return games;
+}
+
+GameDescriptor Engine_AGI_findGameID(const char *gameid) {
+	const Agi::GameSettings *g = Agi::agi_settings;
+	while (g->gameid) {
+		if (0 == scumm_stricmp(gameid, g->gameid))
+			break;
+		g++;
+	}
+	return *g;
+}
+
+DetectedGameList Engine_AGI_detectGames(const FSList &fslist) {
+	DetectedGameList detectedGames;
+	const Agi::GameSettings * g;
+
+	for (g = Agi::agi_settings; g->gameid; ++g) {
+		// Iterate over all files in the given directory
+		for (FSList::const_iterator file = fslist.begin();
+		    file != fslist.end(); ++file) {
+			const char *gameName = file->displayName().c_str();
+
+			if (0 == scumm_stricmp(g->detectname, gameName)) {
+				// Match found, add to list of candidates, then abort inner loop.
+				detectedGames.push_back(*g);
+				break;
+			}
+		}
+	}
+	return detectedGames;
+}
+
+PluginError Engine_AGI_create(OSystem *syst, Engine **engine) {
+	assert(engine);
+	*engine = new Agi::AgiEngine(syst);
+	return kNoError;
+}
+
+REGISTER_PLUGIN(AGI, "AGI Engine");


Property changes on: scummvm/trunk/engines/agi/agi.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/agi.h
===================================================================
--- scummvm/trunk/engines/agi/agi.h	                        (rev 0)
+++ scummvm/trunk/engines/agi/agi.h	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,545 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2001 Sarien Team
+ *
+ * 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 __AGI_H
+#define __AGI_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+
+#include "base/engine.h"
+
+namespace Agi {
+
+typedef signed int Err;
+
+/*
+ * Version and other definitions
+ */
+#define INLINE __inline
+#define VERSION __DATE__ " " __TIME__
+
+/* Default features -- can be overriden in portdefs.h */
+#define USE_CONSOLE
+#define USE_PCM_SOUND
+#define USE_IIGS_SOUND
+#define USE_HIRES
+#define USE_MOUSE
+#define AGDS_SUPPORT
+
+#define	TITLE		"AGI engine"
+
+#define DIR_		"dir"
+#define LOGDIR		"logdir"
+#define PICDIR		"picdir"
+#define VIEWDIR		"viewdir"
+#define	SNDDIR		"snddir"
+#define OBJECTS		"object"
+#define WORDS		"words.tok"
+
+#define	MAX_DIRS	256
+#define	MAX_VARS	256
+#define	MAX_FLAGS	(256 >> 3)
+#define MAX_VIEWTABLE	255	/* KQ3 uses o255! */
+#define MAX_WORDS	20
+#define	MAX_STRINGS	24	/* MAX_STRINGS + 1 used for get.num */
+#define MAX_STRINGLEN	40
+#ifndef MAX_PATH
+#define MAX_PATH	260
+#endif
+
+#define	_EMPTY		0xfffff
+#define	EGO_OWNED	0xff
+
+#define	CRYPT_KEY_SIERRA	"Avis Durgan"
+#define CRYPT_KEY_AGDS		"Alex Simkin"
+
+#ifndef INLINE
+#define INLINE
+#endif
+
+#ifndef USE_PCM_SOUND
+#undef USE_IIGS_SOUND
+#endif
+
+#define	MSG_BOX_COLOUR	0x0f	/* White */
+#define MSG_BOX_TEXT	0x00	/* Black */
+#define MSG_BOX_LINE	0x04	/* Red */
+#define STATUS_FG	0x00	/* Black */
+#define	STATUS_BG	0x0f	/* White */
+#define PATCH_LOGIC		/* disable copy protection on some games */
+
+}                             // End of namespace Agi
+
+/* AGI resources */
+#include "agi/console.h"
+#include "agi/view.h"
+#include "agi/picture.h"
+#include "agi/logic.h"
+#include "agi/sound.h"
+
+namespace Agi {
+
+int getflag(int);
+void setflag(int, int);
+void flipflag(int);
+int getvar(int);
+void setvar(int, int);
+void decrypt(uint8 * mem, int len);
+void release_sprites(void);
+int main_cycle(void);
+int view_pictures(void);
+int parse_cli(int, char **);
+int run_game(void);
+int init_machine(void);
+int deinit_machine(void);
+int get_direction(int x, int y, int x0, int y0, int s);
+void inventory(void);
+void list_games(void);
+uint32 match_crc(uint32, char *, int);
+int v2id_game(void);
+int v3id_game(void);
+int v4id_game(uint32 ver);
+void update_timer(void);
+int get_app_dir(char *app_dir, unsigned int size);
+
+enum {
+	NO_GAMEDIR = 0,
+	GAMEDIR
+};
+
+enum AGIErrors {
+	err_OK = 0,
+	err_DoNothing,
+	err_BadCLISwitch,
+	err_InvalidAGIFile,
+	err_BadFileOpen,
+	err_NotEnoughMemory,
+	err_BadResource,
+	err_UnknownAGIVersion,
+	err_RestartGame,
+	err_NoLoopsInView,
+	err_ViewDataError,
+	err_NoGameList,
+
+	err_Unk = 127
+};
+
+enum kDebugLevels {
+	kDebugLevelMain =      1 << 0,
+	kDebugLevelResources = 1 << 1,
+	kDebugLevelSprites =   1 << 2,
+	kDebugLevelInventory = 1 << 3,
+	kDebugLevelInput =     1 << 4,
+	kDebugLevelMenu =      1 << 5,
+	kDebugLevelScripts =   1 << 6,
+	kDebugLevelSound =     1 << 7,
+	kDebugLevelText =      1 << 8
+};
+
+/**
+ * AGI resources.
+ */
+enum {
+	rLOGIC = 1,
+	rSOUND,
+	rVIEW,
+	rPICTURE
+};
+
+enum {
+	RES_LOADED = 1,
+	RES_COMPRESSED = 0x40
+};
+
+enum {
+	lCOMMAND_MODE = 1,
+	lTEST_MODE
+};
+
+struct game_id_list {
+	struct game_id_list *next;
+	uint32 version;
+	uint32 crc;
+	char *gName;
+	char *switches;
+};
+
+#ifdef USE_MOUSE
+struct mouse {
+	int button;
+	unsigned int x;
+	unsigned int y;
+};
+#endif
+
+/**
+ * Command-line options.
+ */
+struct agi_options {
+#define GAMERUN_RUNGAME 0
+#define GAMERUN_PICVIEW 1
+#define GAMERUN_WORDS	2
+#define GAMERUN_OBJECTS	3
+#define GAMERUN_GAMES	4
+#define GAMERUN_CRC	5
+	int gamerun;		/**< game run mode*/
+	int emuversion;		/**< AGI version to emulate */
+	int agds;		/**< enable AGDS mode */
+	int amiga;		/**< enable Amiga mode */
+	int fullscreen;		/**< use full screen mode if available */
+	int nosound;		/**< disable sound */
+	int egapal;		/**< use PC EGA palette */
+	int cgaemu;		/**< use PC CGA emulation */
+#ifdef USE_HIRES
+	int hires;		/**< use hi-res pictures */
+#endif
+	int soundemu;		/**< sound emulation mode */
+#ifdef USE_MOUSE
+	int agimouse;		/**< AGI Mouse 1.0 emulation */
+#endif
+};
+
+extern struct agi_options opt;
+extern uint8 *exec_name;
+
+extern volatile uint32 clock_ticks;
+extern volatile uint32 clock_count;
+extern volatile uint32 msg_box_secs2;
+
+#ifdef USE_CONSOLE
+extern struct agi_debug debug_;
+#endif
+
+#ifdef USE_MOUSE
+extern struct mouse mouse;
+#endif
+
+int console_keyhandler(int);
+int console_init(void);
+void console_cycle(void);
+void console_lock(void);
+void console_prompt(void);
+#define report printf
+
+enum GameId {
+	GID_AGI = 1
+};
+
+extern Common::RandomSource * rnd;
+extern const char *_savePath;
+
+class AgiEngine:public::Engine {
+	int _gameId;
+
+	void errorString(const char *buf_input, char *buf_output);
+
+protected:
+	int init();
+	int go();
+	void shutdown();
+	void initialize();
+
+
+public:
+	AgiEngine(OSystem * syst);
+	virtual ~ AgiEngine();
+	int getGameId() {
+		return _gameId;
+}};
+
+#define WIN_TO_PIC_X(x) ((x) / 2)
+#define WIN_TO_PIC_Y(y) ((y) < 8 ? 999 : (y) >= (8 + _HEIGHT) ? 999 : (y) - 8)
+
+/**
+ * AGI variables.
+ */
+enum {
+	V_cur_room = 0,		/* 0 */
+	V_prev_room,
+	V_border_touch_ego,
+	V_score,
+	V_border_code,
+	V_border_touch_obj,	/* 5 */
+	V_ego_dir,
+	V_max_score,
+	V_free_pages,
+	V_word_not_found,
+	V_time_delay,		/* 10 */
+	V_seconds,
+	V_minutes,
+	V_hours,
+	V_days,
+	V_joystick_sensitivity,	/* 15 */
+	V_ego_view_resource,
+	V_agi_err_code,
+	V_agi_err_code_info,
+	V_key,
+	V_computer,		/* 20 */
+	V_window_reset,
+	V_soundgen,
+	V_volume,
+	V_max_input_chars,
+	V_sel_item,		/* 25 */
+	V_monitor
+};
+
+/**
+ * AGI flags
+ */
+enum {
+	F_ego_water = 0,	/* 0 */
+	F_ego_invisible,
+	F_entered_cli,
+	F_ego_touched_p2,
+	F_said_accepted_input,
+	F_new_room_exec,	/* 5 */
+	F_restart_game,
+	F_script_blocked,
+	F_joy_sensitivity,
+	F_sound_on,
+	F_debugger_on,		/* 10 */
+	F_logic_zero_firsttime,
+	F_restore_just_ran,
+	F_status_selects_items,
+	F_menus_work,
+	F_output_mode,		/* 15 */
+	F_auto_restart
+};
+
+struct agi_event {
+	uint16 data;
+	uint8 occured;
+};
+
+struct agi_object {
+	int location;
+	char *name;
+};
+
+struct agi_word {
+	int id;
+	char *word;
+};
+
+struct agi_dir {
+	uint8 volume;
+	uint32 offset;
+	uint32 len;
+	uint32 clen;
+	uint8 flags;
+	/* 0 = not in mem, can be freed
+	 * 1 = in mem, can be released
+	 * 2 = not in mem, cant be released
+	 * 3 = in mem, cant be released
+	 * 0x40 = was compressed
+	 */
+};
+
+struct agi_block {
+	int active;
+	int x1, y1;
+	int x2, y2;
+	uint8 *buffer;		/* used for window background */
+};
+
+#define EGO_VIEW_TABLE	0
+#define	HORIZON		36
+#define _WIDTH		160
+#define _HEIGHT		168
+
+/**
+ * AGI game structure.
+ * This structure contains all global data of an AGI game executed
+ * by the interpreter.
+ */
+struct agi_game {
+#define STATE_INIT	0x00
+#define STATE_LOADED	0x01
+#define STATE_RUNNING	0x02
+	int state;		/**< state of the interpreter */
+
+	char name[8];		/**< lead in id (e.g. `GR' for goldrush) */
+	char id[8];		/**< game id */
+	uint32 crc;		/**< game CRC */
+
+	/* game flags and variables */
+	uint8 flags[MAX_FLAGS];
+				/**< 256 1-bit flags */
+	uint8 vars[MAX_VARS];
+				/**< 256 variables */
+
+	/* internal variables */
+	int horizon;		/**< horizon y coordinate */
+	int line_status;	/**< line number to put status on */
+	int line_user_input;
+				/**< line to put user input on */
+	int line_min_print;
+				/**< num lines to print on */
+	int cursor_pos;		/**< column where the input cursor is */
+	uint8 input_buffer[40];
+				/**< buffer for user input */
+	uint8 echo_buffer[40];
+				/**< buffer for echo.line */
+	int keypress;
+#define INPUT_NORMAL	0x01
+#define INPUT_GETSTRING	0x02
+#define INPUT_MENU	0x03
+#define INPUT_NONE	0x04
+	int input_mode;		/**< keyboard input mode */
+	int input_enabled;
+				/**< keyboard input enabled */
+	int lognum;		/**< current logic number */
+
+	/* internal flags */
+	int player_control;
+				/**< player is in control */
+	int quit_prog_now;
+				/**< quit now */
+	int status_line;	/**< status line on/off */
+	int clock_enabled;
+				/**< clock is on/off */
+	int exit_all_logics;
+				/**< break cycle after new.room */
+	int picture_shown;
+				/**< show.pic has been issued */
+	int has_prompt;		/**< input prompt has been printed */
+#define ID_AGDS		0x00000001
+#define ID_AMIGA	0x00000002
+	int game_flags;		/**< agi options flags */
+
+	uint8 pri_table[_HEIGHT];
+					/**< priority table */
+
+	/* windows */
+	uint32 msg_box_ticks;
+				/**< timed message box tick counter */
+	struct agi_block block;
+	struct agi_block window;
+	int has_window;
+
+	/* graphics & text */
+	int gfx_mode;
+	char cursor_char;
+	unsigned int color_fg;
+	unsigned int color_bg;
+	uint8 *sbuf;			/**< 160x168 AGI screen buffer */
+#ifdef USE_HIRES
+	uint8 *hires;			/**< 320x168 hi-res buffer */
+#endif
+
+	/* player command line */
+	struct agi_word ego_words[MAX_WORDS];
+	int num_ego_words;
+
+	unsigned int num_objects;
+
+	struct agi_event ev_keyp[MAX_DIRS];
+						/**< keyboard keypress events */
+	char strings[MAX_STRINGS + 1][MAX_STRINGLEN];
+							/**< strings */
+
+	/* directory entries for resources */
+	struct agi_dir dir_logic[MAX_DIRS];
+	struct agi_dir dir_pic[MAX_DIRS];
+	struct agi_dir dir_view[MAX_DIRS];
+	struct agi_dir dir_sound[MAX_DIRS];
+
+	/* resources */
+	struct agi_picture pictures[MAX_DIRS];
+						/**< AGI picture resources */
+	struct agi_logic logics[MAX_DIRS];
+						/**< AGI logic resources */
+	struct agi_view views[MAX_DIRS];	/**< AGI view resources */
+	struct agi_sound sounds[MAX_DIRS];
+						/**< AGI sound resources */
+
+	/* view table */
+	struct vt_entry view_table[MAX_VIEWTABLE];
+
+	int32 ver;				/**< detected game version */
+
+	int simple_save;			/**< select simple savegames */
+};
+
+/**
+ *
+ */
+struct agi_loader {
+	int version;
+	int int_version;
+	int (*init) (void);
+	int (*deinit) (void);
+	int (*detect_game) ();
+	int (*load_resource) (int, int);
+	int (*unload_resource) (int, int);
+	int (*load_objects) (char *);
+	int (*load_words) (char *);
+};
+
+extern struct agi_game game;
+
+int agi_init(void);
+int agi_deinit(void);
+int agi_version(void);
+int agi_get_release(void);
+void agi_set_release(int);
+int agi_detect_game();
+int agi_load_resource(int, int);
+int agi_unload_resource(int, int);
+void agi_unload_resources(void);
+
+/* words */
+int show_words(void);
+int load_words(char *);
+void unload_words(void);
+int find_word(char *word, int *flen);
+void dictionary_words(char *);
+
+/* objects */
+int show_objects(void);
+int load_objects(char *fname);
+int alloc_objects(int);
+void unload_objects(void);
+char *object_name(unsigned int);
+int object_get_location(unsigned int);
+void object_set_location(unsigned int, int);
+
+void new_input_mode(int);
+void old_input_mode(void);
+
+int run_logic(int);
+
+void agi_timer_low();
+int agi_get_keypress_low();
+int agi_is_keypress_low();
+
+}                             // End of namespace Agi
+
+#endif				/* __AGI_H */


Property changes on: scummvm/trunk/engines/agi/agi.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/agi_v2.cpp
===================================================================
--- scummvm/trunk/engines/agi/agi_v2.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/agi_v2.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,309 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2001 Sarien Team
+ *
+ * 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/stdafx.h"
+#include "common/file.h"
+
+#include "agi/agi.h"
+
+namespace Agi {
+
+static int agi_v2_init(void);
+static int agi_v2_deinit(void);
+static int agi_v2_detect_game();
+static int agi_v2_load_resource(int, int);
+static int agi_v2_unload_resource(int, int);
+static int agi_v2_load_objects(char *);
+static int agi_v2_load_words(char *);
+
+struct agi_loader agi_v2 = {
+	2,
+	0,
+	agi_v2_init,
+	agi_v2_deinit,
+	agi_v2_detect_game,
+	agi_v2_load_resource,
+	agi_v2_unload_resource,
+	agi_v2_load_objects,
+	agi_v2_load_words
+};
+
+static int agi_v2_detect_game() {
+	if (!Common::File::exists(LOGDIR) ||
+			!Common::File::exists(PICDIR) ||
+			!Common::File::exists(SNDDIR) ||
+			!Common::File::exists(VIEWDIR))
+		return err_InvalidAGIFile;
+
+	agi_v2.int_version = 0x2917;	/* setup for 2.917 */
+	return v2id_game();
+}
+
+static int agi_v2_load_dir(struct agi_dir *agid, char *fname) {
+	Common::File fp;
+	uint8 *mem;
+	uint32 flen;
+	unsigned int i;
+	char *path;
+
+	path = fname;
+	report("Loading directory: %s\n", path);
+
+	if ((!fp.open(path))) {
+		return err_BadFileOpen;
+	}
+
+	fp.seek(0, SEEK_END);
+	flen = fp.pos();
+	fp.seek(0, SEEK_SET);
+
+	if ((mem = (uint8 *) malloc(flen + 32)) == NULL) {
+		fp.close();
+		return err_NotEnoughMemory;
+	}
+
+	fp.read(mem, flen);
+
+	/* set all directory resources to gone */
+	for (i = 0; i < MAX_DIRS; i++) {
+		agid[i].volume = 0xff;
+		agid[i].offset = _EMPTY;
+	}
+
+	/* build directory entries */
+	for (i = 0; i < flen; i += 3) {
+		agid[i / 3].volume = *(mem + i) >> 4;
+		agid[i / 3].offset = READ_BE_UINT24(mem + i) & (uint32) _EMPTY;
+		debugC(3, kDebugLevelResources, "%d: volume %d, offset 0x%05x", i / 3, agid[i / 3].volume, agid[i / 3].offset);
+	}
+
+	free(mem);
+	fp.close();
+
+	return err_OK;
+}
+
+static int agi_v2_init() {
+	int ec = err_OK;
+
+	/* load directory files */
+	ec = agi_v2_load_dir(game.dir_logic, LOGDIR);
+	if (ec == err_OK)
+		ec = agi_v2_load_dir(game.dir_pic, PICDIR);
+	if (ec == err_OK)
+		ec = agi_v2_load_dir(game.dir_view, VIEWDIR);
+	if (ec == err_OK)
+		ec = agi_v2_load_dir(game.dir_sound, SNDDIR);
+
+	return ec;
+}
+
+static int agi_v2_deinit() {
+	int ec = err_OK;
+
+#if 0
+	/* unload words */
+	agi_v2_unload_words();
+
+	/* unload objects */
+	agi_v2_unload_objects();
+#endif
+
+	return ec;
+}
+
+static int agi_v2_unload_resource(int t, int n) {
+	debugC(3, kDebugLevelResources, "unload resource");
+
+	switch (t) {
+	case rLOGIC:
+		unload_logic(n);
+		break;
+	case rPICTURE:
+		unload_picture(n);
+		break;
+	case rVIEW:
+		unload_view(n);
+		break;
+	case rSOUND:
+		unload_sound(n);
+		break;
+	}
+
+	return err_OK;
+}
+
+/*
+ * This function does noting but load a raw resource into memory,
+ * if further decoding is required, it must be done by another
+ * routine. NULL is returned if unsucsessfull.
+ */
+static uint8 *agi_v2_load_vol_res(struct agi_dir *agid) {
+	uint8 *data = NULL;
+	char x[MAX_PATH], *path;
+	Common::File fp;
+	unsigned int sig;
+
+	sprintf(x, "vol.%i", agid->volume);
+	path = x;
+	debugC(3, kDebugLevelResources, "Vol res: path = %s", path);
+
+	if (agid->offset != _EMPTY && fp.open(path)) {
+		debugC(3, kDebugLevelResources, "loading resource at offset %d", agid->offset);
+		fp.seek(agid->offset, SEEK_SET);
+		fp.read(&x, 5);
+		if ((sig = READ_BE_UINT16((uint8 *) x)) == 0x1234) {
+			agid->len = READ_LE_UINT16((uint8 *) x + 3);
+			data = (uint8 *) calloc(1, agid->len + 32);
+			if (data != NULL) {
+				fp.read(data, agid->len);
+			} else {
+				abort();
+			}
+		} else {
+#if 0
+			/* FIXME: call some panic handler instead of
+			 *        deiniting directly
+			 */
+			deinit_video_mode();
+#endif
+			report("Error: bad signature %04x\n", sig);
+			// fprintf (stderr, "ACK! BAD RESOURCE!!!\n");
+			return 0;
+		}
+		fp.close();
+	} else {
+		/* we have a bad volume resource */
+		/* set that resource to NA */
+		agid->offset = _EMPTY;
+	}
+
+	return data;
+}
+
+/*
+ * Loads a resource into memory, a raw resource is loaded in
+ * with above routine, then further decoded here.
+ */
+int agi_v2_load_resource(int t, int n) {
+	int ec = err_OK;
+	uint8 *data = NULL;
+
+	debugC(3, kDebugLevelResources, "(t = %d, n = %d)", t, n);
+	if (n > MAX_DIRS)
+		return err_BadResource;
+
+	switch (t) {
+	case rLOGIC:
+		if (~game.dir_logic[n].flags & RES_LOADED) {
+			debugC(3, kDebugLevelResources, "loading logic resource %d", n);
+			agi_v2.unload_resource(rLOGIC, n);
+
+			/* load raw resource into data */
+			data = agi_v2_load_vol_res(&game.dir_logic[n]);
+
+			game.logics[n].data = data;
+			ec = data ? decode_logic(n) : err_BadResource;
+
+			game.logics[n].sIP = 2;
+		}
+
+		/* if logic was cached, we get here */
+		/* reset code pointers incase it was cached */
+
+		game.logics[n].cIP = game.logics[n].sIP;
+		break;
+	case rPICTURE:
+		/* if picture is currently NOT loaded *OR* cacheing is off,
+		 * unload the resource (caching == off) and reload it
+		 */
+
+		debugC(3, kDebugLevelResources, "loading picture resource %d", n);
+		if (game.dir_pic[n].flags & RES_LOADED)
+			break;
+
+		/* if loaded but not cached, unload it */
+		/* if cached but not loaded, etc */
+		agi_v2.unload_resource(rPICTURE, n);
+		data = agi_v2_load_vol_res(&game.dir_pic[n]);
+
+		if (data != NULL) {
+			game.pictures[n].rdata = data;
+			game.dir_pic[n].flags |= RES_LOADED;
+		} else {
+			ec = err_BadResource;
+		}
+		break;
+	case rSOUND:
+		debugC(3, kDebugLevelResources, "loading sound resource %d", n);
+		if (game.dir_sound[n].flags & RES_LOADED)
+			break;
+
+		data = agi_v2_load_vol_res(&game.dir_sound[n]);
+
+		if (data != NULL) {
+			game.sounds[n].rdata = data;
+			game.dir_sound[n].flags |= RES_LOADED;
+			decode_sound(n);
+		} else {
+			ec = err_BadResource;
+		}
+		break;
+	case rVIEW:
+		/* Load a VIEW resource into memory...
+		 * Since VIEWS alter the view table ALL the time
+		 * can we cache the view? or must we reload it all
+		 * the time?
+		 */
+		if (game.dir_view[n].flags & RES_LOADED)
+			break;
+
+		debugC(3, kDebugLevelResources, "loading view resource %d", n);
+		agi_v2.unload_resource(rVIEW, n);
+		data = agi_v2_load_vol_res(&game.dir_view[n]);
+		if (data) {
+			game.views[n].rdata = data;
+			game.dir_view[n].flags |= RES_LOADED;
+			ec = decode_view(n);
+		} else {
+			ec = err_BadResource;
+		}
+		break;
+	default:
+		ec = err_BadResource;
+		break;
+	}
+
+	return ec;
+}
+
+static int agi_v2_load_objects(char *fname) {
+	return load_objects(fname);
+}
+
+static int agi_v2_load_words(char *fname) {
+	return load_words(fname);
+}
+
+}                             // End of namespace Agi


Property changes on: scummvm/trunk/engines/agi/agi_v2.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/agi_v3.cpp
===================================================================
--- scummvm/trunk/engines/agi/agi_v3.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/agi_v3.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,389 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2003 Sarien Team
+ *
+ * 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/stdafx.h"
+
+#include "agi/agi.h"
+#include "agi/lzw.h"
+
+#include "backends/fs/fs.h"
+
+#include "common/config-manager.h"
+
+namespace Agi {
+
+static int agi_v3_init(void);
+static int agi_v3_deinit(void);
+static int agi_v3_detect_game();
+static int agi_v3_load_resource(int, int);
+static int agi_v3_unload_resource(int, int);
+static int agi_v3_load_objects(char *);
+static int agi_v3_load_words(char *);
+
+struct agi_loader agi_v3 = {
+	3,
+	0,
+	agi_v3_init,
+	agi_v3_deinit,
+	agi_v3_detect_game,
+	agi_v3_load_resource,
+	agi_v3_unload_resource,
+	agi_v3_load_objects,
+	agi_v3_load_words
+};
+
+int agi_v3_detect_game() {
+	int ec = err_Unk;
+	bool found = false;
+
+	FSList fslist;
+	FilesystemNode dir(ConfMan.get("path"));
+
+	if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) {
+		warning("AgiEngine: invalid game path '%s'",
+		    dir.path().c_str());
+		return err_InvalidAGIFile;
+	}
+
+	for (FSList::const_iterator file = fslist.begin();
+	    file != fslist.end() && !found; ++file) {
+		Common::String f = file->displayName();
+		f.toLowercase();
+
+		if (f.hasSuffix("vol.0")) {
+			strncpy(game.name, f.c_str(), f.size() > 5 ? f.size() - 5 : f.size());
+			debugC(3, kDebugLevelMain, "game.name = %s", game.name);
+			agi_v3.int_version = 0x3149;	// setup for 3.002.149
+			ec = v3id_game();
+
+			found = true;
+		}
+	}
+
+	if (!found) {
+		debugC(3, kDebugLevelMain, "not found");
+		ec = err_InvalidAGIFile;
+	}
+
+	return ec;
+}
+
+static int agi_v3_load_dir(struct agi_dir *agid, Common::File *fp,
+						   uint32 offs, uint32 len) {
+	int ec = err_OK;
+	uint8 *mem;
+	unsigned int i;
+
+	fp->seek(offs, SEEK_SET);
+	if ((mem = (uint8 *) malloc(len + 32)) != NULL) {
+		fp->read(mem, len);
+
+		/* set all directory resources to gone */
+		for (i = 0; i < MAX_DIRS; i++) {
+			agid[i].volume = 0xff;
+			agid[i].offset = _EMPTY;
+		}
+
+		/* build directory entries */
+		for (i = 0; i < len; i += 3) {
+			agid[i / 3].volume = *(mem + i) >> 4;
+			agid[i / 3].offset = READ_BE_UINT24(mem + i) & (uint32) _EMPTY;
+		}
+
+		free(mem);
+	} else {
+		ec = err_NotEnoughMemory;
+	}
+
+	return ec;
+}
+
+struct agi3vol {
+	uint32 sddr;
+	uint32 len;
+};
+
+int agi_v3_init(void) {
+	int ec = err_OK;
+	struct agi3vol agi_vol3[4];
+	int i;
+	uint16 xd[4];
+	Common::File fp;
+	Common::String path;
+
+	path = Common::String(game.name) + DIR_;
+
+	if (!fp.open(path)) {
+		printf("Failed to open \"%s\"\n", path.c_str());
+		return err_BadFileOpen;
+	}
+	/* build offset table for v3 directory format */
+	fp.read(&xd, 8);
+	fp.seek(0, SEEK_END);
+
+	for (i = 0; i < 4; i++)
+		agi_vol3[i].sddr = READ_LE_UINT16((uint8 *) & xd[i]);
+
+	agi_vol3[0].len = agi_vol3[1].sddr - agi_vol3[0].sddr;
+	agi_vol3[1].len = agi_vol3[2].sddr - agi_vol3[1].sddr;
+	agi_vol3[2].len = agi_vol3[3].sddr - agi_vol3[2].sddr;
+	agi_vol3[3].len = fp.pos() - agi_vol3[3].sddr;
+
+	if (agi_vol3[3].len > 256 * 3)
+		agi_vol3[3].len = 256 * 3;
+
+	fp.seek(0, SEEK_SET);
+
+	/* read in directory files */
+	ec = agi_v3_load_dir(game.dir_logic, &fp, agi_vol3[0].sddr,
+	    agi_vol3[0].len);
+
+	if (ec == err_OK) {
+		ec = agi_v3_load_dir(game.dir_pic, &fp, agi_vol3[1].sddr, agi_vol3[1].len);
+	}
+
+	if (ec == err_OK) {
+		ec = agi_v3_load_dir(game.dir_view, &fp, agi_vol3[2].sddr, agi_vol3[2].len);
+	}
+
+	if (ec == err_OK) {
+		ec = agi_v3_load_dir(game.dir_sound, &fp, agi_vol3[3].sddr, agi_vol3[3].len);
+	}
+
+	return ec;
+}
+
+int agi_v3_deinit() {
+	int ec = err_OK;
+
+#if 0
+	/* unload words */
+	agi_v3_unload_words();
+
+	/* unload objects */
+	agi_v3_unload_objects();
+#endif
+
+	return ec;
+}
+
+int agi_v3_unload_resource(int t, int n) {
+	switch (t) {
+	case rLOGIC:
+		unload_logic(n);
+		break;
+	case rPICTURE:
+		unload_picture(n);
+		break;
+	case rVIEW:
+		unload_view(n);
+		break;
+	case rSOUND:
+		unload_sound(n);
+		break;
+	}
+
+	return err_OK;
+}
+
+/*
+ * This function does noting but load a raw resource into memory.
+ * If further decoding is required, it must be done by another
+ * routine.
+ *
+ * NULL is returned if unsucsessful.
+ */
+uint8 *agi_v3_load_vol_res(struct agi_dir *agid) {
+	char x[MAX_PATH];
+	uint8 *data = NULL, *comp_buffer;
+	Common::File fp;
+	Common::String path;
+
+	debugC(3, kDebugLevelResources, "(%p)", agid);
+	sprintf(x, "vol.%i", agid->volume);
+	path = Common::String(game.name) + x;
+
+	if (agid->offset != _EMPTY && fp.open(path)) {
+		fp.seek(agid->offset, SEEK_SET);
+		fp.read(&x, 7);
+
+		if (READ_BE_UINT16((uint8 *) x) != 0x1234) {
+#if 0
+			/* FIXME */
+			deinit_video_mode();
+#endif
+			debugC(3, kDebugLevelResources, "path = %s", path.c_str());
+			debugC(3, kDebugLevelResources, "offset = %d", agid->offset);
+			debugC(3, kDebugLevelResources, "x = %x %x", x[0], x[1]);
+			error("ACK! BAD RESOURCE");
+
+			g_system->quit();
+		}
+
+		agid->len = READ_LE_UINT16((uint8 *) x + 3);	/* uncompressed size */
+		agid->clen = READ_LE_UINT16((uint8 *) x + 5);	/* compressed len */
+
+		comp_buffer = (uint8 *)calloc(1, agid->clen + 32);
+		fp.read(comp_buffer, agid->clen);
+
+		if (x[2] & 0x80 || agid->len == agid->clen) {
+			/* do not decompress */
+			data = comp_buffer;
+
+#if 0
+			/* CM: added to avoid problems in
+			 *     convert_v2_v3_pic() when clen > len
+			 *     e.g. Sierra demo 4, first picture
+			 *     (Tue Mar 16 13:13:43 EST 1999)
+			 */
+			agid->len = agid->clen;
+
+			/* Now removed to fix Gold Rush! in demo4 */
+#endif
+		} else {
+			/* it is compressed */
+			data = (uint8 *)calloc(1, agid->len + 32);
+			LZW_expand(comp_buffer, data, agid->len);
+			free(comp_buffer);
+			agid->flags |= RES_COMPRESSED;
+		}
+
+		fp.close();
+	} else {
+		/* we have a bad volume resource */
+		/* set that resource to NA */
+		agid->offset = _EMPTY;
+	}
+
+	return data;
+}
+
+/*
+ * Loads a resource into memory, a raw resource is loaded in
+ * with above routine, then further decoded here.
+ */
+int agi_v3_load_resource(int t, int n) {
+	int ec = err_OK;
+	uint8 *data = NULL;
+
+	if (n > MAX_DIRS)
+		return err_BadResource;
+
+	switch (t) {
+	case rLOGIC:
+		/* load resource into memory, decrypt messages at the end
+		 * and build the message list (if logic is in memory)
+		 */
+		if (~game.dir_logic[n].flags & RES_LOADED) {
+			/* if logic is already in memory, unload it */
+			agi_v3.unload_resource(rLOGIC, n);
+
+			/* load raw resource into data */
+			data = agi_v3_load_vol_res(&game.dir_logic[n]);
+			game.logics[n].data = data;
+
+			/* uncompressed logic files need to be decrypted */
+			if (data != NULL) {
+				/* resloaded flag gets set by decode logic */
+				/* needed to build string table */
+				ec = decode_logic(n);
+				game.logics[n].sIP = 2;
+			} else {
+				ec = err_BadResource;
+			}
+
+			/*logics[n].sIP=2; *//* saved IP = 2 */
+			/*logics[n].cIP=2; *//* current IP = 2 */
+
+			game.logics[n].cIP = game.logics[n].sIP;
+		}
+
+		/* if logic was cached, we get here */
+		/* reset code pointers incase it was cached */
+
+		game.logics[n].cIP = game.logics[n].sIP;
+		break;
+	case rPICTURE:
+		/* if picture is currently NOT loaded *OR* cacheing is off,
+		 * unload the resource (caching==off) and reload it
+		 */
+		if (~game.dir_pic[n].flags & RES_LOADED) {
+			agi_v3.unload_resource(rPICTURE, n);
+			data = agi_v3_load_vol_res(&game.dir_pic[n]);
+			if (data != NULL) {
+				data = convert_v3_pic(data, game.dir_pic[n].len);
+				game.pictures[n].rdata = data;
+				game.dir_pic[n].flags |= RES_LOADED;
+			} else {
+				ec = err_BadResource;
+			}
+		}
+		break;
+	case rSOUND:
+		if (game.dir_sound[n].flags & RES_LOADED)
+			break;
+
+		if ((data = agi_v3_load_vol_res(&game.dir_sound[n])) != NULL) {
+			game.sounds[n].rdata = data;
+			game.dir_sound[n].flags |= RES_LOADED;
+			decode_sound(n);
+		} else {
+			ec = err_BadResource;
+		}
+		break;
+	case rVIEW:
+		/* Load a VIEW resource into memory...
+		 * Since VIEWS alter the view table ALL the time can we
+		 * cache the view? or must we reload it all the time?
+		 */
+		/* load a raw view from a VOL file into data */
+		if (game.dir_view[n].flags & RES_LOADED)
+			break;
+
+		agi_v3.unload_resource(rVIEW, n);
+		if ((data = agi_v3_load_vol_res(&game.dir_view[n])) != NULL) {
+			game.views[n].rdata = data;
+			game.dir_view[n].flags |= RES_LOADED;
+			ec = decode_view(n);
+		} else {
+			ec = err_BadResource;
+		}
+		break;
+	default:
+		ec = err_BadResource;
+		break;
+	}
+
+	return ec;
+}
+
+static int agi_v3_load_objects(char *fname) {
+	return load_objects(fname);
+}
+
+static int agi_v3_load_words(char *fname) {
+	return load_words(fname);
+}
+
+}                             // End of namespace Agi


Property changes on: scummvm/trunk/engines/agi/agi_v3.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/checks.cpp
===================================================================
--- scummvm/trunk/engines/agi/checks.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/checks.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,320 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2001 Sarien Team
+ *
+ * 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/stdafx.h"
+#include "agi/agi.h"
+
+namespace Agi {
+
+static int check_position(struct vt_entry *v) {
+	debugC(4, kDebugLevelSprites, "check position @ %d, %d", v->x_pos, v->y_pos);
+
+	if (v->x_pos < 0 ||
+			v->x_pos + v->x_size > _WIDTH ||
+			v->y_pos - v->y_size + 1 < 0 ||
+			v->y_pos >= _HEIGHT ||
+			((~v->flags & IGNORE_HORIZON) && v->y_pos <= game.horizon)) {
+		debugC(4, kDebugLevelSprites, "check position failed: x=%d, y=%d, h=%d, w=%d",
+				v->x_pos, v->y_pos, v->x_size, v->y_size);
+		return 0;
+	}
+
+	/* MH1 needs this, but it breaks LSL1 */
+	if (agi_get_release() >= 0x3000) {
+		if (v->y_pos < v->y_size)
+			return 0;
+	}
+
+	return 1;
+}
+
+/**
+ * Check if there's another object on the way
+ */
+static int check_collision(struct vt_entry *v) {
+	struct vt_entry *u;
+
+	if (v->flags & IGNORE_OBJECTS)
+		return 0;
+
+	for (u = game.view_table; u < &game.view_table[MAX_VIEWTABLE]; u++) {
+		if ((u->flags & (ANIMATED | DRAWN)) != (ANIMATED | DRAWN))
+			continue;
+
+		if (u->flags & IGNORE_OBJECTS)
+			continue;
+
+		/* Same object, check next */
+		if (v->entry == u->entry)
+			continue;
+
+		/* No horizontal overlap, check next */
+		if (v->x_pos + v->x_size < u->x_pos ||
+				v->x_pos > u->x_pos + u->x_size)
+			continue;
+
+		/* Same y, return error! */
+		if (v->y_pos == u->y_pos)
+			goto return_1;
+
+		/* Crossed the baseline, return error! */
+		if ((v->y_pos > u->y_pos && v->y_pos2 < u->y_pos2) ||
+				(v->y_pos < u->y_pos && v->y_pos2 > u->y_pos2)) {
+			goto return_1;
+		}
+	}
+
+	return 0;
+
+ return_1:
+	debugC(4, kDebugLevelSprites, "check returns 1 (object %d)", v->entry);
+	return 1;
+}
+
+static int check_priority(struct vt_entry *v) {
+	int i, trigger, water, pass, pri;
+	uint8 *p0;
+
+	if (~v->flags & FIXED_PRIORITY) {
+		/* Priority bands */
+		v->priority = game.pri_table[v->y_pos];
+	}
+
+	trigger = 0;
+	water = 0;
+	pass = 1;
+
+	if (v->priority == 0x0f)
+		goto _check_ego;
+
+	water = 1;
+
+	p0 = &game.sbuf[v->x_pos + v->y_pos * _WIDTH];
+
+	for (i = 0; i < v->x_size; i++, p0++) {
+		pri = *p0 >> 4;
+
+		if (pri == 0) {	/* unconditional black. no go at all! */
+			pass = 0;
+			break;
+		}
+
+		if (pri == 3)	/* water surface */
+			continue;
+
+		water = 0;
+
+		if (pri == 1) {	/* conditional blue */
+			if (v->flags & IGNORE_BLOCKS)
+				continue;
+
+			debugC(4, kDebugLevelSprites, "Blocks observed!");
+			pass = 0;
+			break;
+		}
+
+		if (pri == 2) {	/* trigger */
+			debugC(4, kDebugLevelSprites, "stepped on trigger");
+#ifdef USE_CONSOLE
+			if (!debug_.ignoretriggers)
+#endif
+				trigger = 1;
+		}
+	}
+
+	if (pass) {
+		if (!water && v->flags & ON_WATER)
+			pass = 0;
+		if (water && v->flags & ON_LAND)
+			pass = 0;
+	}
+
+      _check_ego:
+	if (v->entry == 0) {
+		setflag(F_ego_touched_p2, trigger ? true : false);
+		setflag(F_ego_water, water ? true : false);
+	}
+
+	return pass;
+}
+
+/*
+ * Public functions
+ */
+
+/**
+ * Update position of objects
+ * This function updates the position of all animated, updating view
+ * table entries according to its motion type, step size, etc. The
+ * new position must be valid according to the sprite positioning
+ * rules, otherwise the previous position will be kept.
+ */
+void update_position() {
+	struct vt_entry *v;
+	int x, y, old_x, old_y, border;
+
+	game.vars[V_border_code] = 0;
+	game.vars[V_border_touch_ego] = 0;
+	game.vars[V_border_touch_obj] = 0;
+
+	for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) {
+		if ((v->flags & (ANIMATED | UPDATE | DRAWN)) != (ANIMATED | UPDATE | DRAWN)) {
+			continue;
+		}
+
+		if (v->step_time_count != 0) {
+			if (--v->step_time_count != 0)
+				continue;
+		}
+
+		v->step_time_count = v->step_time;
+
+		x = old_x = v->x_pos;
+		y = old_y = v->y_pos;
+
+		/* If object has moved, update its position */
+		if (~v->flags & UPDATE_POS) {
+			int dx[9] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 };
+			int dy[9] = { 0, -1, -1, 0, 1, 1, 1, 0, -1 };
+			x += v->step_size * dx[v->direction];
+			y += v->step_size * dy[v->direction];
+		}
+
+		/* Now check if it touched the borders */
+		border = 0;
+
+		/* Check left/right borders */
+		if (x < 0) {
+			x = 0;
+			border = 4;
+		} else if (x <= 0 && agi_get_release() == 0x3086) {	/* KQ4 */
+			x = 0;	/* See bug #590462 */
+			border = 4;
+		} else if (v->entry == 0 && x == 0 && v->flags & ADJ_EGO_XY) {
+			/* Extra test to walk west clicking the mouse */
+			x = 0;
+			border = 4;
+		} else if (x + v->x_size > _WIDTH) {
+			x = _WIDTH - v->x_size;
+			border = 2;
+		}
+
+		/* Check top/bottom borders. */
+		if (y - v->y_size + 1 < 0) {
+			y = v->y_size - 1;
+			border = 1;
+		} else if (y > _HEIGHT - 1) {
+			y = _HEIGHT - 1;
+			border = 3;
+		} else if ((~v->flags & IGNORE_HORIZON) && y <= game.horizon) {
+			debugC(4, kDebugLevelSprites, "y = %d, horizon = %d", y, game.horizon);
+			y = game.horizon + 1;
+			border = 1;
+		}
+
+		/* Test new position. rollback if test fails */
+		v->x_pos = x;
+		v->y_pos = y;
+		if (check_collision(v) || !check_priority(v)) {
+			v->x_pos = old_x;
+			v->y_pos = old_y;
+			border = 0;
+			fix_position(v->entry);
+		}
+
+		if (border != 0) {
+			if (v == game.view_table) {
+				game.vars[V_border_touch_ego] = border;
+			} else {
+				game.vars[V_border_code] = v->entry;
+				game.vars[V_border_touch_obj] = border;
+			}
+			if (v->motion == MOTION_MOVE_OBJ) {
+				in_destination(v);
+			}
+		}
+
+		v->flags &= ~UPDATE_POS;
+	}
+}
+
+/**
+ * Adjust position of a sprite
+ * This function adjusts the position of a sprite moving it until
+ * certain criteria is matched. According to priority and control line
+ * data, a sprite may not always appear at the location we specified.
+ * This behaviour is also known as the "Budin-Sonneveld effect".
+ *
+ * @param n view table entry number
+ */
+void fix_position(int n) {
+	struct vt_entry *v = &game.view_table[n];
+	int count, dir, size;
+
+	debugC(4, kDebugLevelSprites, "adjusting view table entry #%d (%d,%d)", n, v->x_pos, v->y_pos);
+
+	/* test horizon */
+	if ((~v->flags & IGNORE_HORIZON) && v->y_pos <= game.horizon)
+		v->y_pos = game.horizon + 1;
+
+	dir = 0;
+	count = size = 1;
+
+	while (!check_position(v) || check_collision(v) || !check_priority(v)) {
+		switch (dir) {
+		case 0:	/* west */
+			v->x_pos--;
+			if (--count)
+				continue;
+			dir = 1;
+			break;
+		case 1:	/* south */
+			v->y_pos++;
+			if (--count)
+				continue;
+			dir = 2;
+			size++;
+			break;
+		case 2:	/* east */
+			v->x_pos++;
+			if (--count)
+				continue;
+			dir = 3;
+			break;
+		case 3:	/* north */
+			v->y_pos--;
+			if (--count)
+				continue;
+			dir = 0;
+			size++;
+			break;
+		}
+
+		count = size;
+	}
+
+	debugC(4, kDebugLevelSprites, "view table entry #%d position adjusted to (%d,%d)", n, v->x_pos, v->y_pos);
+}
+
+} // End of namespace Agi


Property changes on: scummvm/trunk/engines/agi/checks.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/console.cpp
===================================================================
--- scummvm/trunk/engines/agi/console.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/console.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,873 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2002 Sarien Team
+ *
+ * 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/stdafx.h"
+
+#include "agi/agi.h"
+#include "agi/graphics.h"
+#include "agi/sprite.h"
+#include "agi/text.h"
+#include "agi/keyboard.h"
+#include "agi/opcodes.h"
+#include "agi/console.h"
+
+namespace Agi {
+
+#ifdef USE_CONSOLE
+
+/*
+ * The main interpreter engine has not been designed to have a console, and a few
+ * kludges were needed to make the console work. First of all, the main
+ * interpreter loop works at cycle level, not instruction level. To keep
+ * the illusion that the console is threaded, a console updating function
+ * is called from loops inside instructions such as get.string().
+ */
+
+#define CONSOLE_LINES_ONSCREEN	20
+#define CONSOLE_PROMPT		"$"
+#define CONSOLE_CURSOR_HOLLOW	1
+#define CONSOLE_CURSOR_SOLID	2
+#define CONSOLE_CURSOR_EMPTY	3
+#define CONSOLE_COLOR		14
+#define CONSOLE_SCROLLUP_KEY	KEY_PGUP
+#define CONSOLE_SCROLLDN_KEY	KEY_PGDN
+#define CONSOLE_START_KEY	KEY_HOME
+#define CONSOLE_END_KEY		KEY_END
+#define CONSOLE_INPUT_SIZE	39
+
+struct console_command {
+	char cmd[8];
+	char dsc[40];
+	void (*handler) (void);
+};
+
+struct agi_console console;
+struct agi_debug debug_;
+
+/* This used to be a linked list, but we reduce total memory footprint
+ * by implementing it as a statically allocated array.
+ */
+#define MAX_CCMD 16
+static struct console_command ccmd_list[MAX_CCMD];
+static int num_ccmd = 0;
+
+static uint8 has_console = 0;
+static uint8 console_input = 0;
+
+static char *_p0, *_p1, *_p2, *_p3, *_p4, *_p5;	/* FIXME: array */
+static char _p[80];
+static int _pn;
+
+/*
+ * Console line management
+ */
+
+static int first_line = 0;
+
+static void add_console_line(char *s) {
+	int last_line;
+
+	last_line = (CONSOLE_LINES_BUFFER - 1 + first_line) % CONSOLE_LINES_BUFFER;
+
+	strncpy(console.line[last_line], s, CONSOLE_LINE_SIZE);
+	first_line %= CONSOLE_LINES_BUFFER;
+}
+
+static char *get_console_line(int n) {
+	return console.line[(n + first_line) % CONSOLE_LINES_BUFFER];
+}
+
+static char *get_last_console_line() {
+	int last_line = (CONSOLE_LINES_BUFFER - 1 + first_line) % CONSOLE_LINES_BUFFER;
+
+	return console.line[last_line];
+}
+
+/*
+ * Console command parsing
+ * 'o' commands added by Shaun Jackman <sjackman at shaw.ca>, 11 Apr 2002
+ */
+
+static int console_parse(char *b) {
+	struct console_command *d;
+	int i;
+
+	for (; *b && *b == ' '; b++) {
+	}			/* eat spaces */
+	for (; *b && b[strlen(b) - 1] == ' '; b[strlen(b) - 1] = 0) {
+	}
+	if (!*b)
+		return 0;
+
+	/* get or set flag/var/obj values */
+	if ((b[0] == 'f' || b[0] == 'v' || b[0] == 'o') && isdigit(b[1])) {
+		char *e;
+		int f = (int)strtoul(&b[1], &e, 10);
+		if (*e == 0) {
+			if (f >= 0 && f <= 255) {
+				switch (b[0]) {
+				case 'f':
+					report(getflag(f) ? "true\n" : "false\n");
+					break;
+				case 'v':
+					report("%3d\n", getvar(f));
+					break;
+				case 'o':
+					report("%3d]%-24s(%3d)\n", f, object_name(f), object_get_location(f));
+					break;
+				}
+				return 0;
+			}
+			return -1;
+		} else if (*e == '=') {
+			int n = (int)strtoul(e + 1, NULL, 0);
+			switch (b[0]) {
+			case 'f':
+				setflag(f, !!n);
+				break;
+			case 'v':
+				setvar(f, n);
+				break;
+			case 'o':
+				object_set_location(f, n);
+				break;
+			}
+			return 0;
+		}
+	}
+
+	/* tokenize the input line */
+	if (strchr(b, ' '))
+		strcpy(_p, strchr(b, ' ') + 1);
+	_p0 = strtok(b, " ");
+	_p1 = strtok(NULL, " ");
+	_p2 = strtok(NULL, " ");
+	_p3 = strtok(NULL, " ");
+	_p4 = strtok(NULL, " ");
+	_p5 = strtok(NULL, " ");
+
+	/* set number of parameters. ugh, must rewrite this later */
+	_pn = 5;
+	if (!_p5)
+		_pn = 4;
+	if (!_p4)
+		_pn = 3;
+	if (!_p3)
+		_pn = 2;
+	if (!_p2)
+		_pn = 1;
+	if (!_p1)
+		_pn = 0;
+
+	debugC(5, kDebugLevelMain, "number of parameters: %d", _pn);
+
+	for (i = 0; i < num_ccmd; i++) {
+		d = &ccmd_list[i];
+		if (!strcmp(_p0, d->cmd) && d->handler) {
+			d->handler();
+			return 0;
+		}
+	}
+
+	for (i = 0; logic_names_cmd[i].name; i++) {
+		if (!strcmp(_p0, logic_names_cmd[i].name)) {
+			uint8 p[16];
+			if (_pn != logic_names_cmd[i].num_args) {
+				report("AGI command wants %d arguments\n", logic_names_cmd[i].num_args);
+				return 0;
+			}
+			p[0] = _p1 ? (char)strtoul(_p1, NULL, 0) : 0;
+			p[1] = _p2 ? (char)strtoul(_p2, NULL, 0) : 0;
+			p[2] = _p3 ? (char)strtoul(_p3, NULL, 0) : 0;
+			p[3] = _p4 ? (char)strtoul(_p4, NULL, 0) : 0;
+			p[4] = _p5 ? (char)strtoul(_p5, NULL, 0) : 0;
+
+			debugC(5, kDebugLevelMain, "ccmd: %s %d %d %d", logic_names_cmd[i].name, p[0], p[1], p[2]);
+
+			execute_agi_command(i, p);
+
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+/*
+ * Console commands
+ */
+
+static void ccmd_help() {
+	int i;
+
+	if (!_p1) {
+		report("Command Description\n");
+		report("------- --------------------------------\n");
+		for (i = 0; i < num_ccmd; i++)
+			report("%-8s%s\n", ccmd_list[i].cmd, ccmd_list[i].dsc);
+		return;
+	}
+
+	for (i = 0; i < num_ccmd; i++) {
+		if (!strcmp(ccmd_list[i].cmd, _p1) && ccmd_list[i].handler) {
+			report("%s\n", ccmd_list[i].dsc);
+			return;
+		}
+	}
+
+	report("Unknown command or no help available\n");
+
+	return;
+}
+
+static void ccmd_ver() {
+	report(VERSION "\n");
+	return;
+}
+
+static void ccmd_crc() {
+	char name[80];
+	report("0x%05x\n", game.crc);
+	if (match_crc(game.crc, name, 80))
+		report("%s\n", name);
+	else
+		report("Unknown game\n");
+	return;
+}
+
+static void ccmd_quit() {
+	deinit_video();
+	/* deinit_machine (); */
+	exit(0);
+}
+
+#if 0
+static void ccmd_exec() {
+	if (game.state < STATE_LOADED) {
+		report("No game loaded.\n");
+		return;
+	}
+
+	if (game.state >= STATE_RUNNING) {
+		report("Game already running.\n");
+		return;
+	}
+
+	report("Executing AGI game.\n");
+	game.state = STATE_RUNNING;
+}
+#endif
+
+#ifdef USE_HIRES
+
+static void ccmd_hires() {
+	if (_pn != 1 || (strcmp(_p1, "on") && strcmp(_p1, "off"))) {
+		report("Usage: hires on|off\n");
+		return;
+	}
+
+	opt.hires = !strcmp(_p1, "on");
+	erase_both();
+	show_pic();
+	blit_both();
+	return;
+}
+
+#endif
+
+static void ccmd_agiver() {
+	int ver, maj, min;
+
+	ver = agi_get_release();
+	maj = (ver >> 12) & 0xf;
+	min = ver & 0xfff;
+
+	report(maj <= 2 ? "%x.%03x\n" : "%x.002.%03x\n", maj, min);
+	return;
+}
+
+static void ccmd_flags() {
+	int i, j;
+
+	report("    ");
+	for (j = 0; j < 10; j++)
+		report("%d ", j);
+	report("\n");
+
+	for (i = 0; i < 255;) {
+		report("%3d ", i);
+		for (j = 0; j < 10; j++, i++) {
+			report("%c ", getflag(i) ? 'T' : 'F');
+		}
+		report("\n");
+	}
+	return;
+}
+
+static void ccmd_vars() {
+	int i, j;
+
+	for (i = 0; i < 255;) {
+		for (j = 0; j < 5; j++, i++) {
+			report("%03d:%3d ", i, getvar(i));
+		}
+		report("\n");
+	}
+	return;
+}
+
+#if 0
+
+static void ccmd_say() {
+	setflag(F_entered_cli, true);
+	dictionary_words(_p);
+}
+
+static void ccmd_inv() {
+	unsigned int i, j;
+
+	for (j = i = 0; i < game.num_objects; i++) {
+		if (object_get_location(i) == EGO_OWNED) {
+			report("%3d]%-16.16s", i, object_name(i));
+			if (j % 2)
+				report("\n");
+			j++;
+		}
+	}
+	if (j == 0) {
+		report("none\n");
+		return;
+	}
+	if (j % 2)
+		report("\n");
+}
+
+#endif
+
+static void ccmd_objs() {
+	unsigned int i;
+
+	for (i = 0; i < game.num_objects; i++) {
+		report("%3d]%-24s(%3d)\n", i, object_name(i), object_get_location(i));
+	}
+	return;
+}
+
+static void ccmd_opcode() {
+	if (_pn != 1 || (strcmp(_p1, "on") && strcmp(_p1, "off"))) {
+		report("Usage: opcode on|off\n");
+		return;
+	}
+
+	debug_.opcodes = !strcmp(_p1, "on");
+	return;
+}
+
+static void ccmd_logic0() {
+	if (_pn != 1 || (strcmp(_p1, "on") && strcmp(_p1, "off"))) {
+		report("Usage: logic0 on|off\n");
+		return;
+	}
+
+	debug_.logic0 = !strcmp(_p1, "on");
+	return;
+}
+
+static void ccmd_trigger() {
+	if (_pn != 1 || (strcmp(_p1, "on") && strcmp(_p1, "off"))) {
+		report("Usage: trigger on|off\n");
+		return;
+	}
+
+	debug_.ignoretriggers = strcmp(_p1, "on");
+	return;
+}
+
+static void ccmd_step() {
+	debug_.enabled = 1;
+
+	if (_pn == 0) {
+		debug_.steps = 1;
+		return;
+	}
+
+	debug_.steps = strtoul(_p1, NULL, 0);
+	return;
+}
+
+static void ccmd_debug() {
+	debug_.enabled = 1;
+	debug_.steps = 0;
+	return;
+}
+
+static void ccmd_cont() {
+	debug_.enabled = 0;
+	debug_.steps = 0;
+	return;
+}
+
+/*
+ * Register console commands
+ */
+static void console_cmd(char *cmd, char *dsc, void (*handler) (void)) {
+	assert(num_ccmd < MAX_CCMD);
+
+	strcpy(ccmd_list[num_ccmd].cmd, cmd);
+	strcpy(ccmd_list[num_ccmd].dsc, dsc);
+	ccmd_list[num_ccmd].handler = handler;
+
+	num_ccmd++;
+}
+
+/* Console reporting */
+
+/* A slightly modified strtok() for report() */
+static char *get_token(char *s, char d) {
+	static char *x;
+	char *n, *m;
+
+	if (s)
+		x = s;
+
+	m = x;
+	n = strchr(x, d);
+
+	if (n) {
+		*n = 0;
+		x = n + 1;
+	} else {
+		x = strchr(x, 0);
+	}
+
+	return m;
+}
+
+static void build_console_lines(int n) {
+	int j, y1;
+	char *line;
+
+	clear_console_screen(GFX_HEIGHT - n * 10);
+
+	for (j = CONSOLE_LINES_ONSCREEN - n; j < CONSOLE_LINES_ONSCREEN; j++) {
+		line = get_console_line(console.first_line + j);
+		print_text_console(line, 0, j, strlen(line) + 1, CONSOLE_COLOR, 0);
+	}
+
+	y1 = console.y - n * 10;
+	if (y1 < 0)
+		y1 = 0;
+
+	/* CM:
+	 * This will cause blinking when using menus+console, but this
+	 * function is called by report() which can be called from any
+	 * point with or without sprites placed. If we protect the
+	 * flush_block() call with redraw/release sprites cloning will
+	 * happen when activating the console. This could be fixed by
+	 * keeping a control flag in redraw/release to not do the
+	 * actions twice, but I don't want to do that -- not yet.
+	 */
+	flush_block(0, y1, GFX_WIDTH - 1, console.y);
+}
+
+/*
+ * Public functions
+ */
+
+int console_init() {
+	console_cmd("agiver", "Show emulated Sierra AGI version", ccmd_agiver);
+	console_cmd("cont", "Resume interpreter execution", ccmd_cont);
+	console_cmd("debug", "Stop interpreter execution", ccmd_debug);
+	console_cmd("crc", "Show AGI game CRC", ccmd_crc);
+#if 0
+	console_cmd("exec", "Execute loaded AGI game", ccmd_exec);
+#endif
+	console_cmd("flags", "Dump all AGI flags", ccmd_flags);
+	console_cmd("help", "List available commands", ccmd_help);
+#ifdef USE_HIRES
+	console_cmd("hires", "Turn hi-res mode on/off", ccmd_hires);
+#endif
+	console_cmd("logic0", "Turn logic 0 debugging on/off", ccmd_logic0);
+	console_cmd("objs", "List all objects and locations", ccmd_objs);
+	console_cmd("opcode", "Turn opcodes on/off in debug", ccmd_opcode);
+	console_cmd("quit", "Quit the interpreter", ccmd_quit);
+#if 0
+	console_cmd("inv", "List current inventory", ccmd_inv);
+	console_cmd("say", "Pass argument to the AGI parser", ccmd_say);
+#endif
+	console_cmd("step", "Execute the next AGI instruction", ccmd_step);
+	console_cmd("trigger", "Turn trigger lines on/off", ccmd_trigger);
+	console_cmd("vars", "Dump all AGI variables", ccmd_vars);
+	console_cmd("ver", "Show interpreter version", ccmd_ver);
+
+	console.active = 1;
+	console.input_active = 1;
+	console.index = 0;
+	console.max_y = 150;
+	console.y = console.max_y;
+	console.first_line = CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN;
+
+	debug_.enabled = 0;
+	debug_.opcodes = 0;
+	debug_.logic0 = 1;
+	debug_.priority = 0;
+
+	has_console = 1;
+	clear_screen(0);
+
+	return err_OK;
+}
+
+static void build_console_layer() {
+	build_console_lines(console.max_y / 10);
+}
+
+void report(char *message, ...) {
+	char x[512], y[512], z[64], *msg, *n;
+	va_list args;
+	int i, s, len;
+
+	if (!has_console)
+		return;
+
+	va_start(args, message);
+#ifdef HAVE_VSNPRINTF
+	vsnprintf(y, 510, (char *)message, args);
+#else
+	vsprintf(y, (char *)message, args);
+#endif
+	va_end(args);
+
+	if (console_input) {
+		strcpy(z, get_last_console_line());
+		strcpy(x, ">");
+	} else {
+		strcpy(x, get_last_console_line());
+	}
+
+	strcat(x, y);
+
+	len = 40;
+	msg = n = word_wrap_string(x, &len);
+
+	for (s = 1; *n; n++)
+		if (*n == '\n')
+			s++;
+
+	add_console_line(get_token(msg, '\n'));
+	for (i = 1; i < s; i++) {
+		first_line++;
+		n = get_token(NULL, '\n');
+		add_console_line(n);
+	}
+
+	console.first_line = CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN;
+
+	if (console_input) {
+		add_console_line(z);
+	}
+
+	/* Build layer */
+	if (console.y) {
+		if (s > 1)
+			build_console_layer();
+		else
+			build_console_lines(1);
+	}
+
+	free(msg);
+
+	do_update();
+}
+
+void console_cycle() {
+	static int old_y = 0;
+	static int blink = 0;
+	static char cursor[] = "  ";
+
+	/* If no game has been loaded, keep the console visible! */
+	if (game.state < STATE_RUNNING) {
+		console.active = 1;
+		console.count = 10;
+	}
+
+	/* Initial console auto-hide timer */
+	if (console.count > 0)
+		console.count--;
+	if (console.count == 0) {
+		console.active = 0;
+		console.count = -1;
+	}
+
+	if (console.active) {
+		if (console.y < console.max_y)
+			console.y += 15;
+		else
+			console.y = console.max_y;
+	} else {
+		console.count = -1;
+
+		if (console.y > 0)
+			console.y -= 15;
+		else
+			console.y = 0;
+	}
+
+	/* console shading animation */
+	if (old_y != console.y) {
+		int y = console.y;
+		if (old_y > console.y) {
+			/* going up */
+			y = old_y;
+		}
+		flush_block(0, 0, GFX_WIDTH - 1, y);
+		old_y = console.y;
+	}
+
+	blink++;
+	blink %= 16;
+	if (console.input_active) {
+		*cursor = blink < 8 ?
+		    CONSOLE_CURSOR_SOLID : CONSOLE_CURSOR_EMPTY;
+	} else {
+		*cursor = CONSOLE_CURSOR_HOLLOW;
+	}
+	if (console.y > 0
+	    && console.first_line ==
+	    CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN) {
+		int16 y1 = console.y - 10, y2 = console.y - 1;
+		if (y1 < 0)
+			y1 = 0;
+		if (y2 < 0)
+			y2 = 0;
+		print_text_console(cursor, (1 + console.index), 19, 2, CONSOLE_COLOR, 0);
+		flush_block((1 + console.index) * 8, y1, (1 + console.index) * 8 + 7, y2 - 1);
+	}
+
+	do_update();
+}
+
+/* Return true if key was handled */
+int console_keyhandler(int k) {
+	static char buffer[CONSOLE_INPUT_SIZE];
+	int16 y1, y2;
+	char m[2];
+
+#ifdef USE_MOUSE
+	/* Right button switches console on/off */
+	if (!opt.agimouse)	/* AGI Mouse uses right button */
+		if (k == BUTTON_RIGHT)
+			k = CONSOLE_ACTIVATE_KEY;
+#endif
+
+	if (!console.active) {
+		if (k == CONSOLE_ACTIVATE_KEY) {
+			console.active = 1;
+			return true;
+		}
+		return false;
+	}
+
+	if (!console.input_active) {
+		if (k == CONSOLE_SWITCH_KEY) {
+			console.input_active = 1;
+			return true;
+		}
+		if (k == CONSOLE_ACTIVATE_KEY) {
+			console.active = 0;
+			return true;
+		}
+		return false;
+	}
+
+	y1 = console.y - 10;
+	y2 = console.y - 1;
+
+	if (y1 < 0)
+		y1 = 0;
+	if (y2 < 0)
+		y2 = 0;
+
+#ifdef USE_MOUSE
+	/* Ignore left button in console */
+	if (k == BUTTON_LEFT)
+		return true;
+#endif
+
+	/* this code breaks scrolling up, maybe it shoud only be executed
+	 * in the default case?
+	 */
+	if (k) {
+		/* make sure it's not enter or a scroll key */
+		if ((k != KEY_ENTER) && (k != CONSOLE_SCROLLUP_KEY) && (k != CONSOLE_SCROLLDN_KEY)
+				&& (k != CONSOLE_START_KEY)) {
+			/* on any other input reset the console to the bottom */
+			if (console.first_line != CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN) {
+				console.first_line = CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN;
+				build_console_layer();
+			}
+			console.count = -1;
+		}
+	}
+
+	switch (k) {
+	case KEY_ENTER:
+		console_lock();
+		console.index = 0;
+		report("\n");
+
+		if (console_parse(buffer) != 0)
+			report("What? Where?\n");
+
+		buffer[0] = 0;
+		console_prompt();
+		break;
+	case KEY_BACKSPACE:{
+			char *x;
+			if (!console.index)
+				break;
+			x = get_last_console_line();
+			x[console.index] = 0;
+			*m = CONSOLE_CURSOR_EMPTY;
+			print_text_console(m, (console.index + 1), 19, 2, CONSOLE_COLOR, 0);
+			flush_block((console.index + 1) * CHAR_COLS, y1, (console.index + 1 + 1) * CHAR_COLS - 1, y2);
+			console.index--;
+			buffer[console.index] = 0;
+		}
+		break;
+	case CONSOLE_ACTIVATE_KEY:
+		console.active = !console.active;
+		if (console.active)
+			build_console_layer();
+		break;
+	case CONSOLE_SWITCH_KEY:
+		console.count = -1;
+		if (console.y)
+			console.input_active = !console.input_active;
+		break;
+	case CONSOLE_SCROLLUP_KEY:
+		console.count = -1;
+		if (!console.y)
+			break;
+		if (console.first_line > (CONSOLE_LINES_ONSCREEN / 2))
+			console.first_line -= CONSOLE_LINES_ONSCREEN / 2;
+		else
+			console.first_line = 0;
+		build_console_layer();
+		break;
+	case CONSOLE_SCROLLDN_KEY:
+		console.count = -1;
+		if (!console.y)
+			break;
+		if (console.first_line < (CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN - CONSOLE_LINES_ONSCREEN / 2))
+			console.first_line += CONSOLE_LINES_ONSCREEN / 2;
+		else
+			console.first_line = CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN;
+		build_console_layer();
+		break;
+	case CONSOLE_START_KEY:
+		console.count = -1;
+		if (console.y)
+			console.first_line = 0;
+		break;
+	case CONSOLE_END_KEY:
+		console.count = -1;
+		if (console.y)
+			console.first_line = CONSOLE_LINES_BUFFER - CONSOLE_LINES_ONSCREEN;
+		break;
+	default:
+		if (k >= 0x20 && k <= 0x7f && (console.index < CONSOLE_INPUT_SIZE - 2)) {
+			char l[42];
+			buffer[console.index] = k;
+			*m = k;
+			m[1] = 0;
+			console.index++;
+
+			sprintf(l, "%s%c", get_last_console_line(), k);
+			strncpy(get_last_console_line(), l, CONSOLE_LINE_SIZE);
+
+			buffer[console.index] = 0;
+			print_text_console(m, console.index, 19, 2, CONSOLE_COLOR, 0);
+			flush_block(console.index * 8, y1, console.index * 8 + 7, y2);
+		}
+		break;
+	}
+
+	do_update();
+
+	return true;
+}
+
+void console_prompt() {
+	report(CONSOLE_PROMPT);
+	console_input = 1;
+}
+
+void console_lock() {
+	console_input = 0;
+}
+
+#else
+
+void *debug;
+
+void report(char *message, ...) {
+	/* dummy */
+}
+
+int console_init() {
+	return 0;
+}
+
+/* Date: Sun, 14 Oct 2001 23:02:02 -0700
+ * From: Vasyl Tsvirkunov <vasyl at pacbell.net>
+ * 
+ * This one was rather harmless and affected only builds without console.
+ * In SQ1&2 (and likely some others) name entry screen did not update
+ * properly. The bug caused by implicit assumption in cycle.c that
+ * console_cycle() updates the screen. Well, it does, if console is enabled.
+ * The fix is simple. In the second version of console_cycle() in console.c
+ * (the "dummy" one) add call to do_update(). The thing raises some
+ * questions about overall architecture of main cycle, but otherwise the fix
+ * works just fine.
+ */
+void console_cycle() {
+	do_update();
+}
+
+void console_lock() {
+	/* dummy */
+}
+
+void console_prompt() {
+	/* dummy */
+}
+
+int console_keyhandler(int i) {
+	return false;
+}
+
+#endif				/* USE_CONSOLE */
+
+}                             // End of namespace Agi


Property changes on: scummvm/trunk/engines/agi/console.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/console.h
===================================================================
--- scummvm/trunk/engines/agi/console.h	                        (rev 0)
+++ scummvm/trunk/engines/agi/console.h	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,71 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2001 Sarien Team
+ *
+ * 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 __AGI_CONSOLE_H
+#define __AGI_CONSOLE_H
+
+namespace Agi {
+
+#ifdef USE_CONSOLE
+
+#define CONSOLE_LINES_BUFFER    80
+#define CONSOLE_LINE_SIZE	(GFX_WIDTH / 8)
+#define	CONSOLE_ACTIVATE_KEY	'`'
+#define CONSOLE_SWITCH_KEY	'~'
+
+struct agi_console {
+	int active;
+	int input_active;
+	int index;
+	int y;
+	int max_y;
+	int first_line;
+	int count;
+	char *line[CONSOLE_LINES_BUFFER];
+};
+
+struct agi_debug {
+	int enabled;
+	int opcodes;
+	int logic0;
+	int steps;
+	int priority;
+	int statusline;
+	int ignoretriggers;
+};
+
+extern struct agi_console console;
+
+#endif				/* USE_CONSOLE */
+
+int console_keyhandler(int);
+int console_init(void);
+void console_cycle(void);
+void console_lock(void);
+void console_prompt(void);
+void report(char *, ...);
+
+}                             // End of namespace Agi
+
+#endif				/* __AGI_CONSOLE_H */


Property changes on: scummvm/trunk/engines/agi/console.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/cycle.cpp
===================================================================
--- scummvm/trunk/engines/agi/cycle.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/cycle.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,423 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2003 Sarien Team
+ *
+ * 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/stdafx.h"
+
+#include "agi/agi.h"
+#include "agi/text.h"
+#include "agi/sprite.h"
+#include "agi/graphics.h"
+#include "agi/keyboard.h"
+#include "agi/menu.h"
+#include "agi/savegame.h"
+
+namespace Agi {
+
+#define TICK_SECONDS	20
+
+#ifdef USE_MOUSE
+struct mouse mouse;
+#endif
+
+volatile uint32 clock_ticks;
+volatile uint32 clock_count;
+
+/**
+ * Set up new room.
+ * This function is called when ego enters a new room.
+ * @param n room number
+ */
+void new_room(int n) {
+	struct vt_entry *v;
+	int i;
+
+	debugC(4, kDebugLevelMain, "*** room %d ***", n);
+	stop_sound();
+
+	i = 0;
+	for (v = game.view_table; v < &game.view_table[MAX_VIEWTABLE]; v++) {
+		v->entry = i++;
+		v->flags &= ~(ANIMATED | DRAWN);
+		v->flags |= UPDATE;
+		v->step_time = 1;
+		v->step_time_count = 1;
+		v->cycle_time = 1;
+		v->cycle_time_count = 1;
+		v->step_size = 1;
+	}
+	agi_unload_resources();
+
+	game.player_control = true;
+	game.block.active = false;
+	game.horizon = 36;
+	game.vars[V_prev_room] = game.vars[V_cur_room];
+	game.vars[V_cur_room] = n;
+	game.vars[V_border_touch_obj] = 0;
+	game.vars[V_border_code] = 0;
+	game.vars[V_ego_view_resource] = game.view_table[0].current_view;
+
+	agi_load_resource(rLOGIC, n);
+
+	/* Reposition ego in the new room */
+	switch (game.vars[V_border_touch_ego]) {
+	case 1:
+		game.view_table[0].y_pos = _HEIGHT - 1;
+		break;
+	case 2:
+		game.view_table[0].x_pos = 0;
+		break;
+	case 3:
+		game.view_table[0].y_pos = HORIZON + 1;
+		break;
+	case 4:
+		game.view_table[0].x_pos = _WIDTH - game.view_table[0].x_size;
+		break;
+	}
+
+	game.vars[V_border_touch_ego] = 0;
+	setflag(F_new_room_exec, true);
+
+	game.exit_all_logics = true;
+
+	write_status();
+	write_prompt();
+}
+
+static void reset_controllers() {
+	int i;
+
+	for (i = 0; i < MAX_DIRS; i++) {
+		game.ev_keyp[i].occured = false;
+	}
+}
+
+static void interpret_cycle() {
+	int old_sound, old_score;
+
+	if (game.player_control)
+		game.vars[V_ego_dir] = game.view_table[0].direction;
+	else
+		game.view_table[0].direction = game.vars[V_ego_dir];
+
+	check_all_motions();
+
+	old_score = game.vars[V_score];
+	old_sound = getflag(F_sound_on);
+
+	game.exit_all_logics = false;
+	while (run_logic(0) == 0 && !game.quit_prog_now) {
+		game.vars[V_word_not_found] = 0;
+		game.vars[V_border_touch_obj] = 0;
+		game.vars[V_border_code] = 0;
+		old_score = game.vars[V_score];
+		setflag(F_entered_cli, false);
+		game.exit_all_logics = false;
+		reset_controllers();
+	}
+	reset_controllers();
+
+	game.view_table[0].direction = game.vars[V_ego_dir];
+
+	if (game.vars[V_score] != old_score || getflag(F_sound_on) != old_sound)
+		write_status();
+
+	game.vars[V_border_touch_obj] = 0;
+	game.vars[V_border_code] = 0;
+	setflag(F_new_room_exec, false);
+	setflag(F_restart_game, false);
+	setflag(F_restore_just_ran, false);
+
+	if (game.gfx_mode) {
+		update_viewtable();
+		do_update();
+	}
+}
+
+/**
+ * Update AGI interpreter timer.
+ */
+void update_timer() {
+	clock_count++;
+	if (clock_count <= TICK_SECONDS)
+		return;
+
+	clock_count -= TICK_SECONDS;
+
+	if (!game.clock_enabled)
+		return;
+
+	setvar(V_seconds, getvar(V_seconds) + 1);
+	if (getvar(V_seconds) < 60)
+		return;
+
+	setvar(V_seconds, 0);
+	setvar(V_minutes, getvar(V_minutes) + 1);
+	if (getvar(V_minutes) < 60)
+		return;
+
+	setvar(V_minutes, 0);
+	setvar(V_hours, getvar(V_hours) + 1);
+	if (getvar(V_hours) < 24)
+		return;
+
+	setvar(V_hours, 0);
+	setvar(V_days, getvar(V_days) + 1);
+}
+
+static int old_mode = -1;
+
+void new_input_mode(int i) {
+	old_mode = game.input_mode;
+	game.input_mode = i;
+}
+
+void old_input_mode() {
+	game.input_mode = old_mode;
+}
+
+/* If main_cycle returns false, don't process more events! */
+int main_cycle() {
+	unsigned int key, kascii;
+	struct vt_entry *v = &game.view_table[0];
+
+	poll_timer();		/* msdos driver -> does nothing */
+	update_timer();
+
+	if (game.ver == 0) {
+		message_box("Warning: game CRC not listed, assuming AGI version 2.917.");
+		game.ver = -1;
+	}
+
+	key = do_poll_keyboard();
+
+#ifdef USE_MOUSE
+	/* In AGI Mouse emulation mode we must update the mouse-related
+	 * vars in every interpreter cycle.
+	 */
+	if (opt.agimouse) {
+		game.vars[28] = mouse.x / 2;
+		game.vars[29] = mouse.y;
+	}
+#endif
+
+#ifdef USE_CONSOLE
+	if (key == KEY_PRIORITY) {
+		erase_both();
+		debug_.priority = !debug_.priority;
+		show_pic();
+		blit_both();
+		commit_both();
+		key = 0;
+	}
+
+	if (key == KEY_STATUSLN) {
+		debug_.statusline = !debug_.statusline;
+		write_status();
+		key = 0;
+	}
+#endif
+
+	/* Click-to-walk mouse interface */
+	if (game.player_control && v->flags & ADJ_EGO_XY) {
+		v->direction = get_direction(v->x_pos, v->y_pos, v->parm1, v->parm2, v->step_size);
+
+		if (v->direction == 0)
+			in_destination(v);
+	}
+
+	kascii = KEY_ASCII(key);
+
+	if (!console_keyhandler(key)) {
+		if (kascii)
+			setvar(V_key, kascii);
+		process_key:
+		switch (game.input_mode) {
+		case INPUT_NORMAL:
+			if (!handle_controller(key)) {
+				if (key == 0 || !game.input_enabled)
+					break;
+				handle_keys(key);
+
+				/* if ESC pressed, activate menu before
+				 * accept.input from the interpreter cycle
+				 * sets the input mode to normal again
+				 * (closes: #540856)
+				 */
+				if (key == KEY_ESCAPE) {
+					key = 0;
+					goto process_key;
+				}
+
+				/* commented out to close bug #438872
+				 * if (key) game.keypress = key;
+				 */
+			}
+			break;
+		case INPUT_GETSTRING:
+			handle_controller(key);
+			handle_getstring(key);
+			setvar(V_key, 0);	/* clear ENTER key */
+			break;
+		case INPUT_MENU:
+			menu_keyhandler(key);
+			console_cycle();
+			return false;
+		case INPUT_NONE:
+			handle_controller(key);
+			if (key)
+				game.keypress = key;
+			break;
+		}
+	} else {
+		if (game.input_mode == INPUT_MENU) {
+			console_cycle();
+			return false;
+		}
+	}
+
+	console_cycle();
+
+	if (game.msg_box_ticks > 0)
+		game.msg_box_ticks--;
+
+	return true;
+}
+
+static int play_game() {
+	int ec = err_OK;
+
+	debugC(2, kDebugLevelMain, "initializing...");
+	debugC(2, kDebugLevelMain, "game.ver = 0x%x", game.ver);
+
+	stop_sound();
+	clear_screen(0);
+
+	game.horizon = HORIZON;
+	game.player_control = false;
+
+	setflag(F_logic_zero_firsttime, true);	/* not in 2.917 */
+	setflag(F_new_room_exec, true);	/* needed for MUMG and SQ2! */
+	setflag(F_sound_on, true);	/* enable sound */
+	setvar(V_time_delay, 2);	/* "normal" speed */
+
+	game.gfx_mode = true;
+	game.quit_prog_now = false;
+	game.clock_enabled = true;
+	game.line_user_input = 22;
+
+#ifdef USE_MOUSE
+	if (opt.agimouse)
+		report("Using AGI Mouse 1.0 protocol\n");
+#endif
+
+	report("Running AGI script.\n");
+
+#ifdef USE_CONSOLE
+	console.count = 5;
+	console_prompt();
+#endif
+
+	setflag(F_entered_cli, false);
+	setflag(F_said_accepted_input, false);
+	game.vars[V_word_not_found] = 0;
+	game.vars[V_key] = 0;
+
+	debugC(2, kDebugLevelMain, "Entering main loop");
+	do {
+
+		if (!main_cycle())
+			continue;
+
+		if (getvar(V_time_delay) == 0 ||
+		    (1 + clock_count) % getvar(V_time_delay) == 0) {
+			if (!game.has_prompt && game.input_mode == INPUT_NORMAL) {
+				write_prompt();
+				game.has_prompt = 1;
+			} else
+			    if (game.has_prompt && game.input_mode == INPUT_NONE) {
+				write_prompt();
+				game.has_prompt = 0;
+			}
+
+			interpret_cycle();
+
+			setflag(F_entered_cli, false);
+			setflag(F_said_accepted_input, false);
+			game.vars[V_word_not_found] = 0;
+			game.vars[V_key] = 0;
+		}
+
+		if (game.quit_prog_now == 0xff)
+			ec = err_RestartGame;
+
+	} while (game.quit_prog_now == 0);
+
+	stop_sound();
+
+	return ec;
+}
+
+int run_game() {
+	int i, ec = err_OK;
+
+#ifdef USE_HIRES
+	if (opt.cgaemu)
+		opt.hires = 0;
+#endif
+
+	for (i = 0; i < MAX_DIRS; i++)
+		memset(&game.ev_keyp[i], 0, sizeof(struct agi_event));
+
+	/* Execute the game */
+	do {
+		debugC(2, kDebugLevelMain, "game loop");
+		debugC(2, kDebugLevelMain, "game.ver = 0x%x", game.ver);
+
+		if (agi_init() != err_OK)
+			break;
+		if (ec == err_RestartGame)
+			setflag(F_restart_game, true);
+
+		setvar(V_computer, 0);	/* IBM PC (4 = Atari ST) */
+		setvar(V_soundgen, 1);	/* IBM PC SOUND */
+		setvar(V_monitor, 0x3);	/* EGA monitor */
+		setvar(V_max_input_chars, 38);
+		game.input_mode = INPUT_NONE;
+		game.input_enabled = 0;
+		game.has_prompt = 0;
+
+		game.state = STATE_RUNNING;
+		ec = play_game();
+		game.state = STATE_LOADED;
+		agi_deinit();
+	} while (ec == err_RestartGame);
+
+	menu_deinit();
+
+	release_image_stack();
+
+	return ec;
+}
+
+}                             // End of namespace Agi


Property changes on: scummvm/trunk/engines/agi/cycle.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Added: scummvm/trunk/engines/agi/font.cpp
===================================================================
--- scummvm/trunk/engines/agi/font.cpp	                        (rev 0)
+++ scummvm/trunk/engines/agi/font.cpp	2006-05-23 23:43:52 UTC (rev 22588)
@@ -0,0 +1,295 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * Copyright (C) 1999-2001 Sarien Team
+ *
+ * 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/stdafx.h"
+
+#include "agi/agi.h"
+
+namespace Agi {
+
+/* 8x8 font patterns */
+uint8 cur_font[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7E,	/* cursor hollow */
+	0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E,	/* cursor solid */

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list