PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/Scumm.Engine/Resources/Scripts/ScriptManager.cs

http://xnascumm.codeplex.com
C# | 284 lines | 226 code | 47 blank | 11 comment | 43 complexity | 2f0dd2116a29b88319f9674b70ddb213 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. namespace Scumm.Engine.Resources.Scripts
  7. {
  8. public class ScriptManager
  9. {
  10. ResourceManager resourceManager;
  11. public ScriptManager(ResourceManager manager)
  12. {
  13. this.VirtualMachineStack = new Stack<int>();
  14. this.Variables = new Dictionary<uint, object>();
  15. this.BitVariables = new Dictionary<uint, uint>();
  16. this.ActiveScripts = new List<Script>();
  17. resourceManager = manager;
  18. // Initialize variables
  19. WriteVariable((uint)VariableV5.VAR_VERSION, 21);
  20. WriteVariable((uint)VariableV5.VAR_DEBUGMODE, 1);
  21. WriteVariable((uint)VariableV5.VAR_CURRENTDRIVE, 0);
  22. WriteVariable((uint)VariableV5.VAR_FIXEDDISK, true);
  23. WriteVariable((uint)VariableV5.VAR_SOUNDCARD, 0);
  24. WriteVariable((uint)VariableV5.VAR_VIDEOMODE, 19);
  25. WriteVariable((uint)VariableV5.VAR_HEAPSPACE, 0);
  26. WriteVariable((uint)VariableV5.VAR_INPUTMODE, 0);
  27. WriteVariable((uint)VariableV5.VAR_SOUNDPARAM, 0);
  28. WriteVariable((uint)VariableV5.VAR_SOUNDPARAM2, 0);
  29. WriteVariable((uint)VariableV5.VAR_SOUNDPARAM3, 0);
  30. }
  31. public IList<Script> ActiveScripts
  32. {
  33. get;
  34. private set;
  35. }
  36. public IDictionary<uint, uint> BitVariables
  37. {
  38. get;
  39. private set;
  40. }
  41. public IDictionary<uint, object> Variables
  42. {
  43. get;
  44. private set;
  45. }
  46. public Stack<int> VirtualMachineStack
  47. {
  48. get;
  49. private set;
  50. }
  51. public void Run(int? bootParameter)
  52. {
  53. // Run the boot script
  54. var script = resourceManager.Load<Script>("SCRP", (byte)1);
  55. if (bootParameter.HasValue)
  56. {
  57. script.Run(new int[] { bootParameter.Value });
  58. }
  59. else
  60. {
  61. script.Run();
  62. }
  63. }
  64. public void RunActiveScripts(GameTime gameTime)
  65. {
  66. for (int i = 0; i < this.ActiveScripts.Count; i++)
  67. {
  68. var script = this.ActiveScripts[i];
  69. if (script.Status == ScriptStatus.Paused)
  70. {
  71. if(script.Delay > 0)
  72. script.Delay -= gameTime.ElapsedGameTime.TotalSeconds * 60;
  73. else
  74. script.Continue();
  75. }
  76. }
  77. }
  78. public void RunScript(int scriptId, int[] arguments)
  79. {
  80. // TODO: Implement slot system for multi threaded script execution at each frame
  81. var script = resourceManager.Load<Script>("SCRP", (byte)scriptId);
  82. this.ActiveScripts.Add(script);
  83. script.Run(arguments);
  84. }
  85. public void FreezeScripts(byte flag, string currentScript)
  86. {
  87. for (int i = 0; i < ActiveScripts.Count; ++i)
  88. {
  89. if(String.Format("SCRP_{0}", i) == currentScript)
  90. continue;
  91. if (ActiveScripts[i].Status != ScriptStatus.Running)// && (ActiveScripts[i].unk1 || flag >= 0x80))
  92. ActiveScripts[i].Status |= ScriptStatus.Frozen;
  93. }
  94. }
  95. public void UnfreezeScripts()
  96. {
  97. for (int i = 0; i < ActiveScripts.Count; ++i)
  98. {
  99. ActiveScripts[i].Status &= ~ScriptStatus.Frozen;
  100. }
  101. }
  102. public object ReadVariable(uint variableAddress, Script script)
  103. {
  104. // Check to see if the variable is global
  105. if ((variableAddress & 0xF000) == 0)
  106. {
  107. if(!(this.Variables.ContainsKey(variableAddress)))
  108. this.Variables[variableAddress] = 0;
  109. return this.Variables[variableAddress];
  110. }
  111. // Check to see if the variable is a bit variable
  112. if ((variableAddress & 0x8000) != 0)
  113. {
  114. if(!(this.BitVariables.ContainsKey(variableAddress & 0x7FFF)))
  115. this.BitVariables[variableAddress & 0x7FFF] = 0;
  116. var offset = (byte)variableAddress & 0x7FFF;
  117. if(this.BitVariables.ContainsKey((uint)(offset >> 3)))
  118. {
  119. return ((int)this.BitVariables[(uint)(offset >> 3)] & (1 << (offset & 7))) != 0 ? 1 : 0;
  120. }
  121. }
  122. // Check to see if the variable is local
  123. if ((variableAddress & 0x4000) != 0)
  124. {
  125. return script.ReadLocalVariable(variableAddress & 0xFFF);
  126. }
  127. // Should never happen
  128. return 0;
  129. }
  130. public void WriteVariable(uint variableAddress, object value)
  131. {
  132. this.WriteVariable(variableAddress, value, null);
  133. }
  134. public void WriteVariable(uint variableAddress, object value, Script script)
  135. {
  136. // Check to see if the variable is global
  137. if ((variableAddress & 0xF000) == 0)
  138. {
  139. this.Variables[variableAddress] = value;
  140. }
  141. // Check to see if the variable is a bit variable
  142. else if ((variableAddress & 0x8000) != 0)
  143. {
  144. var offset = (byte)variableAddress & 0x7FFF;
  145. this.BitVariables[(uint)(offset >> 3)] = 0;
  146. if (Convert.ToInt32(value) != 0)
  147. {
  148. this.BitVariables[(uint)(offset >> 3)] = this.BitVariables[(uint)(offset >> 3)] | (uint)(1 << (offset & 7));
  149. }
  150. else
  151. {
  152. this.BitVariables[(uint)(offset >> 3)] = this.BitVariables[(uint)(offset >> 3)] & (uint)~(1 << (offset & 7));
  153. }
  154. }
  155. // Check to see if the variable is local
  156. else if ((variableAddress & 0x4000) != 0)
  157. {
  158. script.WriteLocalVariable(variableAddress & 0xFFF, Convert.ToInt32(value));
  159. }
  160. }
  161. public void DeleteVariable(uint variableAddress)
  162. {
  163. if (this.Variables.ContainsKey(variableAddress))
  164. {
  165. this.Variables.Remove(variableAddress);
  166. }
  167. }
  168. public int ReadArrayValue(uint arrayAddress, int index, int baseOffset)
  169. {
  170. if (!this.Variables.ContainsKey(arrayAddress))
  171. {
  172. return 0;
  173. }
  174. if (this.Variables[arrayAddress] is int[,])
  175. {
  176. return ((int[,])this.Variables[arrayAddress])[baseOffset, index];
  177. }
  178. else if (this.Variables[arrayAddress] is byte[,])
  179. {
  180. return ((byte[,])this.Variables[arrayAddress])[baseOffset, index];
  181. }
  182. else
  183. {
  184. throw new InvalidOperationException("Invalid array type.");
  185. }
  186. }
  187. public void WriteArrayValue(uint arrayAddress, int index, int baseOffset, int value)
  188. {
  189. if (!this.Variables.ContainsKey(arrayAddress))
  190. {
  191. return;
  192. }
  193. if (this.Variables[arrayAddress] is string)
  194. {
  195. var charArray = ((string)this.Variables[arrayAddress]).ToCharArray();
  196. charArray[baseOffset + index] = (char)value;
  197. this.Variables[arrayAddress] = new string(charArray);
  198. }
  199. else
  200. {
  201. var array = (Array)this.Variables[arrayAddress];
  202. if (this.Variables[arrayAddress] is int[,])
  203. {
  204. ((int[,])this.Variables[arrayAddress])[baseOffset, index] = value;
  205. }
  206. else if (this.Variables[arrayAddress] is byte[,])
  207. {
  208. ((byte[,])this.Variables[arrayAddress])[baseOffset, index] = (byte)value;
  209. }
  210. else
  211. {
  212. throw new InvalidOperationException("Invalid array type.");
  213. }
  214. }
  215. }
  216. public void DefineArray(uint arrayAddress, ArrayType type, int dimension2, int dimension1)
  217. {
  218. if (type == ArrayType.IntArray)
  219. {
  220. this.WriteVariable(arrayAddress, new int[dimension1 + 1, dimension2 + 1]);
  221. }
  222. else
  223. {
  224. this.WriteVariable(arrayAddress, new byte[dimension1 + 1, dimension2 + 1]);
  225. }
  226. }
  227. // Aliasing for methods
  228. public int Pop()
  229. {
  230. return VirtualMachineStack.Pop();
  231. }
  232. public void Push(int value)
  233. {
  234. VirtualMachineStack.Push(value);
  235. }
  236. }
  237. }