PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/NES EMU 7/NES EMU 7/NES EMU 7/SharpNES.cs

#
C# | 427 lines | 326 code | 65 blank | 36 comment | 43 complexity | 4b39904d31cd88bdc95417b49cdc7105 MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Audio;
  7. using Microsoft.Xna.Framework.Content;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using Microsoft.Xna.Framework.Input;
  10. using Microsoft.Xna.Framework.GamerServices;
  11. using TouchThumbsticks;
  12. //using XNAExtras;
  13. namespace XNASharpNES
  14. {
  15. public class SharpNES : Microsoft.Xna.Framework.Game
  16. {
  17. #region Entry Point
  18. /// <summary>
  19. /// The main entry point for the application.
  20. /// </summary>
  21. static void Main()
  22. {
  23. using (SharpNES game = new SharpNES())
  24. {
  25. game.Run();
  26. }
  27. }
  28. #endregion
  29. #region Menu Constants
  30. private static readonly Color BackgroundColor = Color.White;
  31. private static readonly Color TitleColor = Color.White;
  32. private static readonly Color MenuItemColor = Color.Black;
  33. private static readonly Color SelectedItemColor = Color.DarkGreen;
  34. private const int NumMenuItems = 24;
  35. private Vector2 MenuPosition;
  36. private int MenuItemHeight;
  37. #endregion
  38. private SpriteFont MenuSpriteFont;
  39. private GraphicsDeviceManager graphics;
  40. private ContentManager content;
  41. private SpriteBatch spriteBatch;
  42. private Texture2D targetTexture;
  43. private Texture2D backgroundTexture;
  44. private Texture2D helpBackgroundTexture;
  45. private GamePadHelper menuPad;
  46. private Rectangle screenRectangle;
  47. private NesEngine myEngine = new NesEngine();
  48. private IGameComponent s;
  49. private static FpsCounter FPS = null;
  50. //public static TitleContainer saveDevice = null;
  51. private string[] roms;
  52. private bool waitForBackRelease = false;
  53. private bool running = false;
  54. private int topMenuRom;
  55. private int selectedRom;
  56. // a texture used to draw the virtual thumbsticks on the screen
  57. private Texture2D thumbstick;
  58. private Texture2D controllerTex;
  59. Object stateobj;
  60. public static FpsCounter FpsCounter
  61. {
  62. get
  63. {
  64. return FPS;
  65. }
  66. }
  67. public SharpNES()
  68. {
  69. graphics = new GraphicsDeviceManager(this);
  70. graphics.SynchronizeWithVerticalRetrace = false;
  71. TargetElapsedTime = TimeSpan.FromSeconds(1 / 30f);
  72. content = new ContentManager(Services, "Content");
  73. IsFixedTimeStep = false;
  74. FPS = new FpsCounter(this);
  75. menuPad = new GamePadHelper(20);
  76. Components.Add(FPS);
  77. #if WINDOWS_PHONE
  78. graphics.IsFullScreen = true;
  79. #endif
  80. LoadCart("smb3.nes");
  81. }
  82. void GetDevice(IAsyncResult result)
  83. {
  84. //saveDevice = Guide.EndShowStorageDeviceSelector(result);
  85. //if (saveDevice.IsConnected)
  86. {
  87. List<string> files = new List<string>();
  88. //files.AddRange(Directory.GetFiles());
  89. int i = 0;
  90. while (i < files.Count)
  91. {
  92. if (files[i].ToString().ToLower().EndsWith(".nes"))
  93. i++;
  94. else
  95. files.RemoveAt(i);
  96. }
  97. roms = (string[])files.ToArray();
  98. Array.Sort(roms);
  99. string lastRom = LoadRomName();
  100. selectedRom = Array.IndexOf(roms, lastRom);
  101. if (selectedRom < 0)
  102. {
  103. selectedRom = 0;
  104. }
  105. topMenuRom = 0;
  106. }
  107. }
  108. protected override void Initialize()
  109. {
  110. //For some reason LoadContent() Won't do the job :/
  111. spriteBatch = new SpriteBatch(graphics.GraphicsDevice); ;
  112. screenRectangle = new Rectangle(
  113. 0, 0,
  114. graphics.PreferredBackBufferWidth,
  115. graphics.PreferredBackBufferHeight
  116. );
  117. targetTexture = new Texture2D(
  118. graphics.GraphicsDevice,
  119. 256, 224, false,
  120. SurfaceFormat.Bgr565
  121. );
  122. //Menu Stuff
  123. backgroundTexture = content.Load<Texture2D>("bg") as Texture2D;
  124. helpBackgroundTexture = content.Load<Texture2D>("help") as Texture2D;
  125. thumbstick = content.Load<Texture2D>("thumbstick");
  126. controllerTex = content.Load<Texture2D>("nescontroller4ad");
  127. LoadFonts();
  128. }
  129. protected override void LoadContent()
  130. {
  131. }
  132. private void LoadFonts()
  133. {
  134. MenuItemHeight = 16 * 4 / 3;
  135. MenuPosition = new Vector2(graphics.PreferredBackBufferWidth / 8, 100 + MenuItemHeight);
  136. MenuSpriteFont = content.Load<SpriteFont>("Verdana");
  137. }
  138. protected override void UnloadContent() { }
  139. protected override void Update(GameTime gameTime)
  140. {
  141. if (running)
  142. {
  143. UpdateGame();
  144. }
  145. else
  146. {
  147. UpdateMenu();
  148. }
  149. base.Update(gameTime);
  150. }
  151. protected override void Draw(GameTime gameTime)
  152. {
  153. if (running)
  154. {
  155. DrawGame();
  156. }
  157. else
  158. {
  159. DrawMenu();
  160. }
  161. base.Draw(gameTime);
  162. }
  163. private void UpdateGame()
  164. {
  165. GamePadState pad = GamePad.GetState(PlayerIndex.One);
  166. if (((pad.Buttons.Back == ButtonState.Pressed) &&
  167. (pad.Buttons.RightShoulder == ButtonState.Pressed)) || Keyboard.GetState().IsKeyDown(Keys.Escape))
  168. {
  169. StopCart();
  170. waitForBackRelease = true;
  171. return;
  172. }
  173. // Allows the game to exit
  174. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  175. this.Exit();
  176. myEngine.RunCart();
  177. myEngine.RunCart();
  178. }
  179. private void DrawGame()
  180. {
  181. GraphicsDevice.Textures[0] = null;
  182. targetTexture.SetData<short>(
  183. myEngine.myPPU.offscreenBuffer,
  184. 256 * 8,
  185. targetTexture.Width * targetTexture.Height
  186. );
  187. spriteBatch.Begin(0, BlendState.Opaque);
  188. spriteBatch.Draw(targetTexture, screenRectangle, Color.White);
  189. DrawDebug();
  190. // begin a new batch without the camera transformation for our UI
  191. // if the user is touching the screen and the thumbsticks have positions,
  192. // draw our thumbstick sprite so the user knows where the centers are
  193. if (VirtualThumbsticks.LeftThumbstickCenter.HasValue)
  194. {
  195. spriteBatch.Draw(
  196. thumbstick,
  197. VirtualThumbsticks.LeftThumbstickCenter.Value - new Vector2(thumbstick.Width / 2f, thumbstick.Height / 2f),
  198. Color.Green);
  199. }
  200. if (VirtualThumbsticks.RightThumbstickCenter.HasValue)
  201. {
  202. //spriteBatch.Draw(
  203. // thumbstick,
  204. // VirtualThumbsticks.RightThumbstickCenter.Value - new Vector2(thumbstick.Width / 2f, thumbstick.Height / 2f),
  205. // Color.Blue);
  206. }
  207. spriteBatch.Draw(controllerTex, Joypad.aButtonRect, new Rectangle(625, 200, 85, 85), Color.White);
  208. spriteBatch.Draw(controllerTex, Joypad.bButtonRect, new Rectangle(520, 200, 85, 85), Color.White);
  209. spriteBatch.Draw(controllerTex, Joypad.startButtonRect, new Rectangle(385, 226, 75, 35), Color.White);
  210. spriteBatch.Draw(controllerTex, Joypad.selectButtonRect, new Rectangle(385, 226, 75, 35), Color.White);
  211. spriteBatch.End();
  212. }
  213. private void UpdateMenu()
  214. {
  215. menuPad.Update();
  216. GamePadState pad = GamePad.GetState(PlayerIndex.One);
  217. if (waitForBackRelease)
  218. {
  219. // Since the back button is used to leave the game,
  220. // we need to wait here for it to be released.
  221. if (menuPad.BackIsPressed)
  222. {
  223. return;
  224. }
  225. menuPad.Reset();
  226. waitForBackRelease = false;
  227. }
  228. if (menuPad.BackIsPressed)
  229. {
  230. Quit();
  231. }
  232. if (roms != null && roms.Length > 0)
  233. {
  234. if (menuPad.StartIsPressed || menuPad.AIsPressed || Keyboard.GetState().IsKeyDown(Keys.A))
  235. {
  236. LoadCart(roms[selectedRom]);
  237. }
  238. else if (menuPad.UpWasPressed || menuPad.LeftWasPressed || Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.Up))
  239. {
  240. selectedRom = Math.Max(selectedRom - 1, 0);
  241. if (selectedRom < topMenuRom)
  242. {
  243. topMenuRom--;
  244. }
  245. }
  246. else if (menuPad.DownWasPressed || menuPad.RightWasPressed || Keyboard.GetState().IsKeyDown(Keys.Down) || Keyboard.GetState().IsKeyDown(Keys.Right))
  247. {
  248. selectedRom = Math.Min(selectedRom + 1, roms.Length - 1);
  249. if (selectedRom >= topMenuRom + NumMenuItems)
  250. {
  251. topMenuRom++;
  252. }
  253. }
  254. }
  255. }
  256. private void DrawDebug()
  257. {
  258. //#if DEBUG
  259. spriteBatch.DrawString( MenuSpriteFont,
  260. FpsCounter.FPS.ToString() + "fps" + "\n",
  261. //"Real Resolution: " + graphics.PreferredBackBufferWidth + " x " + graphics.PreferredBackBufferHeight + "\n" +
  262. //"Rendered Resolution: " + Window.ClientBounds.Width + " x " + Window.ClientBounds.Height + "\n" +
  263. //"ROM Loaded: " + roms[selectedRom],
  264. new Vector2( 50, 50 ), Color.Black );
  265. //#endif
  266. }
  267. private void DrawMenu()
  268. {
  269. GamePadState pad = GamePad.GetState(PlayerIndex.One);
  270. graphics.GraphicsDevice.Clear(BackgroundColor);
  271. spriteBatch.Begin();
  272. spriteBatch.Draw(backgroundTexture, new Vector2(0, 0), Color.White);
  273. DrawDebug();
  274. if (roms != null)
  275. {
  276. if (roms.Length == 0)
  277. {
  278. spriteBatch.DrawString(MenuSpriteFont, "No ROMs Available.", MenuPosition, Color.Black);
  279. }
  280. else
  281. {
  282. DrawRomNames();
  283. }
  284. if (pad.Buttons.LeftShoulder == ButtonState.Pressed)
  285. {
  286. DrawHelp();
  287. }
  288. }
  289. spriteBatch.End();
  290. }
  291. private void DrawHelp()
  292. {
  293. spriteBatch.Draw(helpBackgroundTexture, new Vector2(0, 0), Color.White);
  294. }
  295. private void DrawRomNames()
  296. {
  297. for (int index = 0; index < NumMenuItems; index++)
  298. {
  299. int currentMenuRom = topMenuRom + index;
  300. Color itemColor = (currentMenuRom == selectedRom) ? SelectedItemColor : MenuItemColor;
  301. if (roms.Length > currentMenuRom)
  302. {
  303. spriteBatch.DrawString(
  304. MenuSpriteFont,
  305. Path.GetFileNameWithoutExtension(roms[currentMenuRom]),
  306. new Vector2(
  307. MenuPosition.X,
  308. MenuPosition.Y + index * MenuItemHeight
  309. ),
  310. itemColor
  311. );
  312. }
  313. }
  314. }
  315. private void SaveRomName(string rom)
  316. {
  317. //using (TitleContainer.OpenStream("SharpNES"))
  318. {
  319. //using (StreamWriter writer = File.CreateText(Path.Combine(container.Path, "LastRom.txt")))
  320. {
  321. // writer.Write(rom);
  322. }
  323. }
  324. }
  325. private string LoadRomName()
  326. {
  327. string result = String.Empty;
  328. //using (StorageContainer container = saveDevice.OpenContainer("SharpNES"))
  329. {
  330. //string filename = Path.Combine(container.Path, "LastRom.txt");
  331. //if (File.Exists(filename))
  332. {
  333. // using (StreamReader reader = File.OpenText(filename))
  334. // result = reader.ReadLine();
  335. }
  336. }
  337. return result;
  338. }
  339. private void LoadCart(string filename)
  340. {
  341. SaveRomName(filename);
  342. myEngine.LoadCart(filename);
  343. myEngine.LoadRam();
  344. myEngine.StartCart();
  345. running = true;
  346. }
  347. private void StopCart()
  348. {
  349. //using (StorageContainer container = saveDevice.OpenContainer("SharpNES"))
  350. {
  351. //myEngine.SaveRamDirectory = container.Path;
  352. myEngine.StopCart(); // Writes SaveRam
  353. }
  354. running = false;
  355. }
  356. private void Quit()
  357. {
  358. StopCart();
  359. this.Exit();
  360. }
  361. }
  362. }