From cdb205e696ea3fb717d06c986d29a328e1009128 Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 31 Aug 2018 21:21:34 -0700 Subject: [PATCH 01/22] Initial API Work --- .../BizHawk.Client.Common.csproj | 11 + .../lua/EmuLuaLibrary.SQL.cs | 3 +- BizHawk.Client.Common/plugins/PluginBase.cs | 58 ++ .../plugins/PluginLibrary.Emu.cs | 353 +++++++++++++ .../plugins/PluginLibrary.GUIDraw.cs | 498 ++++++++++++++++++ .../plugins/PluginLibrary.Gameinfo.cs | 86 +++ .../plugins/PluginLibrary.Joypad.cs | 186 +++++++ .../plugins/PluginLibrary.Memory.cs | 284 ++++++++++ .../plugins/PluginLibrary.MemorySavestate.cs | 60 +++ .../plugins/PluginLibrary.Movie.cs | 263 +++++++++ .../plugins/PluginLibrary.UserData.cs | 52 ++ .../plugins/PluginMemoryBase.cs | 242 +++++++++ .../BizHawk.Client.EmuHawk.csproj | 2 + .../Plugins/Libraries/GUIDrawLibrary.cs | 167 ++++++ 14 files changed, 2263 insertions(+), 2 deletions(-) create mode 100644 BizHawk.Client.Common/plugins/PluginBase.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs create mode 100644 BizHawk.Client.Common/plugins/PluginMemoryBase.cs create mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 9816bf2bfb..18110a72f2 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -64,6 +64,7 @@ + @@ -131,6 +132,16 @@ + + + + + + + + + + diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.SQL.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.SQL.cs index 5738e975db..5cbc8d2df2 100644 --- a/BizHawk.Client.Common/lua/EmuLuaLibrary.SQL.cs +++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.SQL.cs @@ -1,9 +1,8 @@ using System; -using System.Collections; +using System.Collections.Generic; using System.ComponentModel; using System.Data.SQLite; using NLua; -using System.Collections.Generic; namespace BizHawk.Client.Common { diff --git a/BizHawk.Client.Common/plugins/PluginBase.cs b/BizHawk.Client.Common/plugins/PluginBase.cs new file mode 100644 index 0000000000..44f88da68c --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginBase.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; + +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; + +namespace BizHawk.Client.Common +{ + public abstract class PluginBase + { + [RequiredService] + private IEmulator Emulator { get; set; } + + [RequiredService] + private IMemoryDomains Domains { get; set; } + + [OptionalService] + private IInputPollable InputPollableCore { get; set; } + + [OptionalService] + private IDebuggable DebuggableCore { get; set; } + + public abstract void PreFrameCallback(); + public abstract void PostFrameCallback(); + public abstract void SaveStateCallback(string name); + public abstract void LoadStateCallback(string name); + public abstract void InputPollCallback(); + + protected virtual void AddReadCallback(Action cb, uint address, string domain) + { + if (DebuggableCore.MemoryCallbacksAvailable()) + { + DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Read, "Lua Hook", cb, address, null)); + } + } + protected virtual void AddWriteCallback(Action cb, uint address, string domain) + { + if (DebuggableCore.MemoryCallbacksAvailable()) + { + DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Write, "Lua Hook", cb, address, null)); + } + } + protected virtual void AddExecCallback(Action cb, uint address, string domain) + { + if (DebuggableCore.MemoryCallbacksAvailable() && DebuggableCore.MemoryCallbacks.ExecuteCallbacksAvailable) + { + DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Execute, "Lua Hook", cb, address, null)); + } + } + protected virtual void RemoveMemoryCallback(Action cb) + { + if (DebuggableCore.MemoryCallbacksAvailable()) + { + DebuggableCore.MemoryCallbacks.Remove(cb); + } + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs new file mode 100644 index 0000000000..eb3dd485b9 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs @@ -0,0 +1,353 @@ +using System; +using System.ComponentModel; +using System.Collections.Generic; + +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; +using BizHawk.Emulation.Cores.Nintendo.NES; +using BizHawk.Emulation.Cores.Nintendo.SNES; +using BizHawk.Emulation.Cores.PCEngine; +using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; +using BizHawk.Emulation.Cores.Sega.MasterSystem; +using BizHawk.Emulation.Cores.WonderSwan; +using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES; + +namespace BizHawk.Client.Common +{ + [Description("A library for interacting with the currently loaded emulator core")] + public sealed class EmulatorPluginLibrary + { + [RequiredService] + private IEmulator Emulator { get; set; } + + [OptionalService] + private IDebuggable DebuggableCore { get; set; } + + [OptionalService] + private IDisassemblable DisassemblableCore { get; set; } + + [OptionalService] + private IMemoryDomains MemoryDomains { get; set; } + + [OptionalService] + private IInputPollable InputPollableCore { get; set; } + + [OptionalService] + private IRegionable RegionableCore { get; set; } + + [OptionalService] + private IBoardInfo BoardInfo { get; set; } + + public Action FrameAdvanceCallback { get; set; } + public Action YieldCallback { get; set; } + + public EmulatorPluginLibrary() + { } + + public static void DisplayVsync(bool enabled) + { + Global.Config.VSync = enabled; + } + + public void FrameAdvance() + { + FrameAdvanceCallback(); + } + + public int FrameCount() + { + return Emulator.Frame; + } + + public object Disassemble(uint pc, string name = "") + { + try + { + if (DisassemblableCore == null) + { + throw new NotImplementedException(); + } + + MemoryDomain domain = MemoryDomains.SystemBus; + + if (!string.IsNullOrEmpty(name)) + { + domain = MemoryDomains[name]; + } + + var d = DisassemblableCore.Disassemble(domain, pc, out int l); + return new { disasm = d, length = l }; + } + catch (NotImplementedException) + { + Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement disassemble()"); + return null; + } + } + + public ulong? GetRegister(string name) + { + try + { + if (DebuggableCore == null) + { + throw new NotImplementedException(); + } + + var registers = DebuggableCore.GetCpuFlagsAndRegisters(); + ulong? value = null; + if (registers.ContainsKey(name)) value = registers[name].Value; + return value; + } + catch (NotImplementedException) + { + Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement getregister()"); + return null; + } + } + + public Dictionary GetRegisters() + { + var table = new Dictionary(); + + try + { + if (DebuggableCore == null) + { + throw new NotImplementedException(); + } + + foreach (var kvp in DebuggableCore.GetCpuFlagsAndRegisters()) + { + table[kvp.Key] = kvp.Value.Value; + } + } + catch (NotImplementedException) + { + Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement getregisters()"); + } + + return table; + } + + public void SetRegister(string register, int value) + { + try + { + if (DebuggableCore == null) + { + throw new NotImplementedException(); + } + + DebuggableCore.SetCpuRegister(register, value); + } + catch (NotImplementedException) + { + Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement setregister()"); + } + } + + public long TotalExecutedycles() + { + try + { + if (DebuggableCore == null) + { + throw new NotImplementedException(); + } + + return DebuggableCore.TotalExecutedCycles; + } + catch (NotImplementedException) + { + Console.WriteLine($"Error: {Emulator.Attributes().CoreName} does not yet implement totalexecutedcycles()"); + + return 0; + } + } + + public static string GetSystemId() + { + return Global.Game.System; + } + + public bool IsLagged() + { + if (InputPollableCore != null) + { + return InputPollableCore.IsLagFrame; + } + + Console.WriteLine($"Can not get lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable"); + return false; + } + + public void SetIsLagged(bool value = true) + { + if (InputPollableCore != null) + { + InputPollableCore.IsLagFrame = value; + } + else + { + Console.WriteLine($"Can not set lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable"); + } + } + + public int LagCount() + { + if (InputPollableCore != null) + { + return InputPollableCore.LagCount; + } + + Console.WriteLine($"Can not get lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable"); + return 0; + } + + public void SetLagCount(int count) + { + if (InputPollableCore != null) + { + InputPollableCore.LagCount = count; + } + else + { + Console.WriteLine($"Can not set lag information, {Emulator.Attributes().CoreName} does not implement IInputPollable"); + } + } + + public static void LimitFramerate(bool enabled) + { + Global.Config.ClockThrottle = enabled; + } + + public static void MinimizeFrameskip(bool enabled) + { + Global.Config.AutoMinimizeSkipping = enabled; + } + + public void SetRenderPlanes(params bool[] luaParam) + { + if (Emulator is GPGX) + { + var gpgx = Emulator as GPGX; + var s = gpgx.GetSettings(); + s.DrawBGA = luaParam[0]; + s.DrawBGB = luaParam[1]; + s.DrawBGW = luaParam[2]; + s.DrawObj = luaParam[3]; + gpgx.PutSettings(s); + + } + else if (Emulator is LibsnesCore) + { + var snes = Emulator as LibsnesCore; + var s = snes.GetSettings(); + s.ShowBG1_0 = s.ShowBG1_1 = luaParam[0]; + s.ShowBG2_0 = s.ShowBG2_1 = luaParam[1]; + s.ShowBG3_0 = s.ShowBG3_1 = luaParam[2]; + s.ShowBG4_0 = s.ShowBG4_1 = luaParam[3]; + s.ShowOBJ_0 = luaParam[4]; + s.ShowOBJ_1 = luaParam[5]; + s.ShowOBJ_2 = luaParam[6]; + s.ShowOBJ_3 = luaParam[7]; + snes.PutSettings(s); + } + else if (Emulator is NES) + { + // in the future, we could do something more arbitrary here. + // but this isn't any worse than the old system + var nes = Emulator as NES; + var s = nes.GetSettings(); + s.DispSprites = luaParam[0]; + s.DispBackground = luaParam[1]; + nes.PutSettings(s); + } + else if (Emulator is QuickNES) + { + var quicknes = Emulator as QuickNES; + var s = quicknes.GetSettings(); + + // this core doesn't support disabling BG + bool showsp = GetSetting(0, luaParam); + if (showsp && s.NumSprites == 0) + { + s.NumSprites = 8; + } + else if (!showsp && s.NumSprites > 0) + { + s.NumSprites = 0; + } + + quicknes.PutSettings(s); + } + else if (Emulator is PCEngine) + { + var pce = Emulator as PCEngine; + var s = pce.GetSettings(); + s.ShowOBJ1 = GetSetting(0, luaParam); + s.ShowBG1 = GetSetting(1, luaParam); + if (luaParam.Length > 2) + { + s.ShowOBJ2 = GetSetting(2, luaParam); + s.ShowBG2 = GetSetting(3, luaParam); + } + + pce.PutSettings(s); + } + else if (Emulator is SMS) + { + var sms = Emulator as SMS; + var s = sms.GetSettings(); + s.DispOBJ = GetSetting(0, luaParam); + s.DispBG = GetSetting(1, luaParam); + sms.PutSettings(s); + } + else if (Emulator is WonderSwan) + { + var ws = Emulator as WonderSwan; + var s = ws.GetSettings(); + s.EnableSprites = GetSetting(0, luaParam); + s.EnableFG = GetSetting(1, luaParam); + s.EnableBG = GetSetting(2, luaParam); + ws.PutSettings(s); + } + } + + private static bool GetSetting(int index, bool[] settings) + { + if (index < settings.Length) + { + return settings[index]; + } + + return true; + } + + public void Yield() + { + YieldCallback(); + } + + public string GetDisplayType() + { + if (RegionableCore != null) + { + return RegionableCore.Region.ToString(); + } + + return ""; + } + + public string GetBoardName() + { + if (BoardInfo != null) + { + return BoardInfo.BoardName; + } + + return ""; + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs b/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs new file mode 100644 index 0000000000..46081390d2 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs @@ -0,0 +1,498 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using System.IO; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.Common +{ + public abstract class GUIDrawPluginLibrary + { + [RequiredService] + protected IEmulator Emulator { get; set; } + + public GUIDrawPluginLibrary() + { + + } + + public bool HasGUISurface = false; + + protected Color _defaultForeground = Color.White; + protected Color? _defaultBackground; + protected Color? _defaultTextBackground = Color.FromArgb(128, 0, 0, 0); + protected int _defaultPixelFont = 1; // gens + protected Padding _padding = new Padding(0); + + #region Gui API + public virtual void Dispose() + { + foreach (var brush in _solidBrushes.Values) + { + brush.Dispose(); + } + + foreach (var brush in _pens.Values) + { + brush.Dispose(); + } + } + + public abstract void DrawNew(string name, bool? clear = true); + public abstract void DrawFinish(); + #endregion + + #region Helpers + protected readonly Dictionary _imageCache = new Dictionary(); + + protected readonly Dictionary _solidBrushes = new Dictionary(); + protected readonly Dictionary _pens = new Dictionary(); + protected SolidBrush GetBrush(Color color) + { + SolidBrush b; + if (!_solidBrushes.TryGetValue(color, out b)) + { + b = new SolidBrush(color); + _solidBrushes[color] = b; + } + + return b; + } + + protected Pen GetPen(Color color) + { + Pen p; + if (!_pens.TryGetValue(color, out p)) + { + p = new Pen(color); + _pens[color] = p; + } + + return p; + } + + protected abstract Graphics GetGraphics(); + public void SetPadding(int all) + { + _padding = new Padding(all); + } + public void SetPadding(int x, int y) + { + _padding = new Padding(x / 2, y / 2, x / 2 + x & 1, y / 2 + y & 1); + } + public void SetPadding(int l,int t,int r, int b) + { + _padding = new Padding(l, t, r, b); + } + public Padding GetPadding() + { + return _padding; + } + #endregion + + public abstract void AddMessage(string message); + + public abstract void ClearGraphics(); + + public abstract void ClearText(); + + public void SetDefaultForegroundColor(Color color) + { + _defaultForeground = color; + } + + public void SetDefaultBackgroundColor(Color color) + { + _defaultBackground = color; + } + + public void SetDefaultTextBackground(Color color) + { + _defaultTextBackground = color; + } + + public void SetDefaultPixelFont(string fontfamily) + { + switch (fontfamily) + { + case "fceux": + case "0": + _defaultPixelFont = 0; + break; + case "gens": + case "1": + _defaultPixelFont = 1; + break; + default: + Console.WriteLine($"Unable to find font family: {fontfamily}"); + return; + } + } + + public void DrawBezier(Point p1, Point p2, Point p3, Point p4, Color? color = null) + { + using (var g = GetGraphics()) + { + try + { + g.DrawBezier(GetPen(color ?? _defaultForeground), p1, p2, p3, p4); + } + catch (Exception) + { + return; + } + } + } + + public void DrawBeziers(Point[] points, Color? color = null) + { + using (var g = GetGraphics()) + { + try + { + g.DrawBeziers(GetPen(color ?? _defaultForeground), points); + } + catch (Exception) + { + return; + } + } + } + public void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? background = null) + { + using (var g = GetGraphics()) + { + try + { + if (x < x2) + { + x2 = Math.Abs(x - x2); + } + else + { + x2 = x - x2; + x -= x2; + } + + if (y < y2) + { + y2 = Math.Abs(y - y2); + } + else + { + y2 = y - y2; + y -= y2; + } + + g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, x2, y2); + + var bg = background ?? _defaultBackground; + if (bg.HasValue) + { + g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, x2 - 1, y2 - 1); + } + } + catch (Exception) + { + // need to stop the script from here + return; + } + } + } + + public void DrawEllipse(int x, int y, int width, int height, Color? line = null, Color? background = null) + { + using (var g = GetGraphics()) + { + try + { + var bg = background ?? _defaultBackground; + if (bg.HasValue) + { + var brush = GetBrush(bg.Value); + g.FillEllipse(brush, x, y, width, height); + } + + g.DrawEllipse(GetPen(line ?? _defaultForeground), x, y, width, height); + } + catch (Exception) + { + // need to stop the script from here + return; + } + } + } + + public void DrawIcon(string path, int x, int y, int? width = null, int? height = null) + { + using (var g = GetGraphics()) + { + try + { + if (!File.Exists(path)) + { + AddMessage("File not found: " + path); + return; + } + + Icon icon; + if (width.HasValue && height.HasValue) + { + icon = new Icon(path, width.Value, height.Value); + } + else + { + icon = new Icon(path); + } + + g.DrawIcon(icon, x, y); + } + catch (Exception) + { + return; + } + } + } + + public void DrawImage(string path, int x, int y, int? width = null, int? height = null, bool cache = true) + { + if (!File.Exists(path)) + { + Console.WriteLine("File not found: " + path); + return; + } + + using (var g = GetGraphics()) + { + Image img; + if (_imageCache.ContainsKey(path)) + { + img = _imageCache[path]; + } + else + { + img = Image.FromFile(path); + if (cache) + { + _imageCache.Add(path, img); + } + } + + g.DrawImage(img, x, y, width ?? img.Width, height ?? img.Height); + } + } + + public void ClearImageCache() + { + foreach (var image in _imageCache) + { + image.Value.Dispose(); + } + + _imageCache.Clear(); + } + + public void DrawImageRegion(string path, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int? dest_width = null, int? dest_height = null) + { + if (!File.Exists(path)) + { + Console.WriteLine("File not found: " + path); + return; + } + + using (var g = GetGraphics()) + { + Image img; + if (_imageCache.ContainsKey(path)) + { + img = _imageCache[path]; + } + else + { + img = Image.FromFile(path); + _imageCache.Add(path, img); + } + + var destRect = new Rectangle(dest_x, dest_y, dest_width ?? source_width, dest_height ?? source_height); + + g.DrawImage(img, destRect, source_x, source_y, source_width, source_height, GraphicsUnit.Pixel); + } + } + + public void DrawLine(int x1, int y1, int x2, int y2, Color? color = null) + { + using (var g = GetGraphics()) + { + g.DrawLine(GetPen(color ?? _defaultForeground), x1, y1, x2, y2); + } + } + + public void DrawAxis(int x, int y, int size, Color? color = null) + { + DrawLine(x + size, y, x - size, y, color ?? _defaultForeground); + DrawLine(x, y + size, x, y - size, color ?? _defaultForeground); + } + + public void DrawPie(int x, int y, int width, int height, int startangle, int sweepangle, Color? line = null, Color? background = null) + { + using (var g = GetGraphics()) + { + var bg = background ?? _defaultBackground; + if (bg.HasValue) + { + var brush = GetBrush(bg.Value); + g.FillPie(brush, x, y, width, height, startangle, sweepangle); + } + + g.DrawPie(GetPen(line ?? _defaultForeground), x + 1, y + 1, width - 1, height - 1, startangle, sweepangle); + } + } + + public void DrawPixel(int x, int y, Color? color = null) + { + using (var g = GetGraphics()) + { + try + { + g.DrawLine(GetPen(color ?? _defaultForeground), x, y, x + 0.1F, y); + } + catch (Exception) + { + return; + } + } + } + + public void DrawPolygon(Point[] points, Color? line = null, Color? background = null) + { + using (var g = GetGraphics()) + { + try + { + g.DrawPolygon(GetPen(line ?? _defaultForeground), points); + var bg = background ?? _defaultBackground; + if (bg.HasValue) + { + g.FillPolygon(GetBrush(bg.Value), points); + } + } + catch (Exception) + { + return; + } + } + } + + public void DrawRectangle(int x, int y, int width, int height, Color? line = null, Color? background = null) + { + using (var g = GetGraphics()) + { + g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, width, height); + var bg = background ?? _defaultBackground; + if (bg.HasValue) + { + g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, width - 1, height - 1); + } + } + } + + public void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null, + string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null) + { + using (var g = GetGraphics()) + { + try + { + var family = FontFamily.GenericMonospace; + if (fontfamily != null) + { + family = new FontFamily(fontfamily); + } + + var fstyle = FontStyle.Regular; + if (fontstyle != null) + { + switch (fontstyle.ToLower()) + { + default: + case "regular": + break; + case "bold": + fstyle = FontStyle.Bold; + break; + case "italic": + fstyle = FontStyle.Italic; + break; + case "strikethrough": + fstyle = FontStyle.Strikeout; + break; + case "underline": + fstyle = FontStyle.Underline; + break; + } + } + + // The text isn't written out using GenericTypographic, so measuring it using GenericTypographic seemed to make it worse. + // And writing it out with GenericTypographic just made it uglier. :p + var f = new StringFormat(StringFormat.GenericDefault); + var font = new Font(family, fontsize ?? 12, fstyle, GraphicsUnit.Pixel); + Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize(); + if (horizalign != null) + { + switch (horizalign.ToLower()) + { + default: + case "left": + break; + case "center": + x -= sizeOfText.Width / 2; + break; + case "right": + x -= sizeOfText.Width; + break; + } + } + + if (vertalign != null) + { + switch (vertalign.ToLower()) + { + default: + case "bottom": + break; + case "middle": + y -= sizeOfText.Height / 2; + break; + case "top": + y -= sizeOfText.Height; + break; + } + } + + var bg = backcolor ?? _defaultBackground; + if (bg.HasValue) + { + for (var xd = -1; xd <= 1; xd++) + { + for (var yd = -1; yd <= 1; yd++) + { + g.DrawString(message, font, GetBrush(bg.Value), x+xd, y+yd); + } + } + } + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; + g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y); + } + catch (Exception) + { + return; + } + } + } + + public abstract void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null); + public abstract void Text(int x, int y, string message, Color? forecolor = null, string anchor = null); + } +} \ No newline at end of file diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs new file mode 100644 index 0000000000..6c9c21b070 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.Common +{ + public sealed class GameInfoPluginLibrary + { + [OptionalService] + private IBoardInfo BoardInfo { get; set; } + + public GameInfoPluginLibrary() + { } + + public string GetRomName() + { + if (Global.Game != null) + { + return Global.Game.Name ?? ""; + } + + return ""; + } + + public string GetRomHash() + { + if (Global.Game != null) + { + return Global.Game.Hash ?? ""; + } + + return ""; + } + + public bool InDatabase() + { + if (Global.Game != null) + { + return !Global.Game.NotInDatabase; + } + + return false; + } + + public string GetStatus() + { + if (Global.Game != null) + { + return Global.Game.Status.ToString(); + } + + return ""; + } + + public bool IsStatusBad() + { + if (Global.Game != null) + { + return Global.Game.IsRomStatusBad(); + } + + return true; + } + + public string GetBoardType() + { + return BoardInfo?.BoardName ?? ""; + } + + public Dictionary GetOptions() + { + var options = new Dictionary(); + + if (Global.Game != null) + { + foreach (var option in Global.Game.GetOptionsDict()) + { + options[option.Key] = option.Value; + } + } + + return options; + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs new file mode 100644 index 0000000000..e981b0ef31 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; + +namespace BizHawk.Client.Common +{ + public sealed class JoypadPluginLibrary + { + public JoypadPluginLibrary() { } + + public Dictionary Get(int? controller = null) + { + var buttons = new Dictionary(); + var adaptor = Global.AutofireStickyXORAdapter; + foreach (var button in adaptor.Source.Definition.BoolButtons) + { + if (!controller.HasValue) + { + buttons[button] = adaptor.IsPressed(button); + } + else if (button.Length >= 3 && button.Substring(0, 2) == "P" + controller) + { + buttons[button.Substring(3)] = adaptor.IsPressed("P" + controller + " " + button.Substring(3)); + } + } + + foreach (var button in adaptor.Source.Definition.FloatControls) + { + if (controller == null) + { + buttons[button] = adaptor.GetFloat(button); + } + else if (button.Length >= 3 && button.Substring(0, 2) == "P" + controller) + { + buttons[button.Substring(3)] = adaptor.GetFloat("P" + controller + " " + button.Substring(3)); + } + } + + buttons["clear"] = null; + buttons["getluafunctionslist"] = null; + buttons["output"] = null; + + return buttons; + } + + // TODO: what about float controls? + public Dictionary GetImmediate() + { + var buttons = new Dictionary(); + var adaptor = Global.ActiveController; + foreach (var button in adaptor.Definition.BoolButtons) + { + buttons[button] = adaptor.IsPressed(button); + } + foreach (var button in adaptor.Definition.FloatControls) + { + buttons[button] = adaptor.GetFloat(button); + } + + return buttons; + } + + public void SetFromMnemonicStr(string inputLogEntry) + { + try + { + var lg = Global.MovieSession.MovieControllerInstance(); + lg.SetControllersAsMnemonic(inputLogEntry); + + foreach (var button in lg.Definition.BoolButtons) + { + Global.LuaAndAdaptor.SetButton(button, lg.IsPressed(button)); + } + + foreach (var floatButton in lg.Definition.FloatControls) + { + Global.LuaAndAdaptor.SetFloat(floatButton, lg.GetFloat(floatButton)); + } + } + catch (Exception) + { + Console.WriteLine("invalid mnemonic string: " + inputLogEntry); + } + } + + [LuaMethodExample("joypad.set( { [\"Left\"] = true, [ \"A\" ] = true, [ \"B\" ] = true } );")] + [LuaMethod("set", "sets the given buttons to their provided values for the current frame")] + public void Set(Dictionary buttons, int? controller = null) + { + try + { + foreach (var button in buttons.Keys) + { + var invert = false; + bool? theValue; + var theValueStr = buttons[button].ToString(); + + if (!string.IsNullOrWhiteSpace(theValueStr)) + { + if (theValueStr.ToLower() == "false") + { + theValue = false; + } + else if (theValueStr.ToLower() == "true") + { + theValue = true; + } + else + { + invert = true; + theValue = null; + } + } + else + { + theValue = null; + } + + var toPress = button.ToString(); + if (controller.HasValue) + { + toPress = "P" + controller + " " + button; + } + + if (!invert) + { + if (theValue.HasValue) // Force + { + Global.LuaAndAdaptor.SetButton(toPress, theValue.Value); + Global.ActiveController.Overrides(Global.LuaAndAdaptor); + } + else // Unset + { + Global.LuaAndAdaptor.UnSet(toPress); + Global.ActiveController.Overrides(Global.LuaAndAdaptor); + } + } + else // Inverse + { + Global.LuaAndAdaptor.SetInverse(toPress); + Global.ActiveController.Overrides(Global.LuaAndAdaptor); + } + } + } + catch + { + /*Eat it*/ + } + } + + [LuaMethodExample("joypad.setanalog( { [ \"Tilt X\" ] = true, [ \"Tilt Y\" ] = false } );")] + [LuaMethod("setanalog", "sets the given analog controls to their provided values for the current frame. Note that unlike set() there is only the logic of overriding with the given value.")] + public void SetAnalog(Dictionary controls, object controller = null) + { + try + { + foreach (var name in controls.Keys) + { + var theValueStr = controls[name].ToString(); + float? theValue = null; + + if (!string.IsNullOrWhiteSpace(theValueStr)) + { + float f; + if (float.TryParse(theValueStr, out f)) + { + theValue = f; + } + } + + if (controller == null) + { + Global.StickyXORAdapter.SetFloat(name.ToString(), theValue); + } + else + { + Global.StickyXORAdapter.SetFloat("P" + controller + " " + name, theValue); + } + } + } + catch + { + /*Eat it*/ + } + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs new file mode 100644 index 0000000000..aa9daf90d3 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; + +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; +using BizHawk.Common.BufferExtensions; + +namespace BizHawk.Client.Common +{ + public sealed class MemoryPluginLibrary : PluginMemoryBase + { + private MemoryDomain _currentMemoryDomain; + private bool _isBigEndian; + public MemoryPluginLibrary(bool Big = false) + : base() + { + _isBigEndian = Big; + } + + protected override MemoryDomain Domain + { + get + { + if (MemoryDomainCore != null) + { + if (_currentMemoryDomain == null) + { + _currentMemoryDomain = MemoryDomainCore.HasSystemBus + ? MemoryDomainCore.SystemBus + : MemoryDomainCore.MainMemory; + } + + return _currentMemoryDomain; + } + + var error = $"Error: {Emulator.Attributes().CoreName} does not implement memory domains"; + Console.WriteLine(error); + throw new NotImplementedException(error); + } + } + + #region Unique Library Methods + + public List GetMemoryDomainList() + { + var list = new List(); + + foreach (var domain in DomainList) + { + list.Add(domain.Name); + } + + return list; + } + + public uint GetMemoryDomainSize(string name = "") + { + if (string.IsNullOrEmpty(name)) + { + return (uint)Domain.Size; + } + + return (uint)DomainList[VerifyMemoryDomain(name)].Size; + } + + public string GetCurrentMemoryDomain() + { + return Domain.Name; + } + + public uint GetCurrentMemoryDomainSize() + { + return (uint)Domain.Size; + } + + public bool UseMemoryDomain(string domain) + { + try + { + if (DomainList[domain] != null) + { + _currentMemoryDomain = DomainList[domain]; + return true; + } + + Console.WriteLine($"Unable to find domain: {domain}"); + return false; + } + catch // Just in case + { + Console.WriteLine($"Unable to find domain: {domain}"); + } + + return false; + } + + public string HashRegion(int addr, int count, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + + // checks + if (addr < 0 || addr >= d.Size) + { + string error = $"Address {addr} is outside the bounds of domain {d.Name}"; + Console.WriteLine(error); + throw new ArgumentOutOfRangeException(error); + } + if (addr + count > d.Size) + { + string error = $"Address {addr} + count {count} is outside the bounds of domain {d.Name}"; + Console.WriteLine(error); + throw new ArgumentOutOfRangeException(error); + } + + byte[] data = new byte[count]; + for (int i = 0; i < count; i++) + { + data[i] = d.PeekByte(addr + i); + } + + using (var hasher = System.Security.Cryptography.SHA256.Create()) + { + return hasher.ComputeHash(data).BytesToHexString(); + } + } + + #endregion + + #region Endian Handling + + private int ReadSigned(int addr, int size, string domain = null) + { + if (_isBigEndian) return ReadSignedBig(addr, size, domain); + else return ReadSignedLittle(addr, size, domain); + } + + private uint ReadUnsigned(int addr, int size, string domain = null) + { + if (_isBigEndian) return ReadUnsignedBig(addr, size, domain); + else return ReadUnsignedLittle(addr, size, domain); + } + + private void WriteSigned(int addr, int value, int size, string domain = null) + { + if (_isBigEndian) WriteSignedBig(addr, value, size, domain); + else WriteSignedLittle(addr, value, size, domain); + } + + private void WriteUnsigned(int addr, uint value, int size, string domain = null) + { + if (_isBigEndian) WriteUnsignedBig(addr, value, size, domain); + else WriteUnsignedLittle(addr, value, size, domain); + } + + #endregion + + #region Common Special and Legacy Methods + + public uint ReadByte(int addr, string domain = null) + { + return ReadUnsignedByte(addr, domain); + } + + public void WriteByte(int addr, uint value, string domain = null) + { + WriteUnsignedByte(addr, value, domain); + } + + public new List ReadByteRange(int addr, int length, string domain = null) + { + return base.ReadByteRange(addr, length, domain); + } + + public new void WriteByteRange(int addr, List memoryblock, string domain = null) + { + base.WriteByteRange(addr, memoryblock, domain); + } + + public float ReadFloat(int addr, string domain = null) + { + return base.ReadFloat(addr, _isBigEndian, domain); + } + + public void WriteFloat(int addr, double value, string domain = null) + { + base.WriteFloat(addr, value, _isBigEndian, domain); + } + + #endregion + + #region 1 Byte + + public int ReadS8(int addr, string domain = null) + { + return (sbyte)ReadUnsignedByte(addr, domain); + } + + public void WriteS8(int addr, uint value, string domain = null) + { + WriteUnsignedByte(addr, value, domain); + } + + public uint ReadU8(int addr, string domain = null) + { + return ReadUnsignedByte(addr, domain); + } + + public void WriteU8(int addr, uint value, string domain = null) + { + WriteUnsignedByte(addr, value, domain); + } + + #endregion + + #region 2 Byte + public int ReadS16(int addr, string domain = null) + { + return ReadSigned(addr, 2, domain); + } + + public void WriteS16(int addr, int value, string domain = null) + { + WriteSigned(addr, value, 2, domain); + } + + public uint ReadU16(int addr, string domain = null) + { + return ReadUnsigned(addr, 2, domain); + } + + public void WriteU16(int addr, uint value, string domain = null) + { + WriteUnsigned(addr, value, 2, domain); + } + #endregion + + #region 3 Byte + + public int ReadS24(int addr, string domain = null) + { + return ReadSigned(addr, 3, domain); + } + public void WriteS24(int addr, int value, string domain = null) + { + WriteSigned(addr, value, 3, domain); + } + + public uint ReadU24(int addr, string domain = null) + { + return ReadUnsigned(addr, 3, domain); + } + + public void WriteU24(int addr, uint value, string domain = null) + { + WriteUnsigned(addr, value, 3, domain); + } + + #endregion + + #region 4 Byte + + public int ReadS32(int addr, string domain = null) + { + return ReadSigned(addr, 4, domain); + } + + public void WriteS32(int addr, int value, string domain = null) + { + WriteSigned(addr, value, 4, domain); + } + + public uint ReadU32(int addr, string domain = null) + { + return ReadUnsigned(addr, 4, domain); + } + + public void WriteU32(int addr, uint value, string domain = null) + { + WriteUnsigned(addr, value, 4, domain); + } + + #endregion + } +} \ No newline at end of file diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs b/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs new file mode 100644 index 0000000000..f0916a518a --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.IO; + +using BizHawk.Emulation.Common; + +namespace BizHawk.Client.Common +{ + public sealed class MemorySavestatePluginLibrary + { + public MemorySavestatePluginLibrary() + { } + + [RequiredService] + private IStatable StatableCore { get; set; } + + private readonly Dictionary _memorySavestates = new Dictionary(); + + public string SaveCoreStateToMemory() + { + var guid = Guid.NewGuid(); + var bytes = (byte[])StatableCore.SaveStateBinary().Clone(); + + _memorySavestates.Add(guid, bytes); + + return guid.ToString(); + } + + public void LoadCoreStateFromMemory(string identifier) + { + var guid = new Guid(identifier); + + try + { + var state = _memorySavestates[guid]; + + using (var ms = new MemoryStream(state)) + using (var br = new BinaryReader(ms)) + { + StatableCore.LoadStateBinary(br); + } + } + catch + { + Console.WriteLine("Unable to find the given savestate in memory"); + } + } + + public void DeleteState(string identifier) + { + var guid = new Guid(identifier); + _memorySavestates.Remove(guid); + } + + public void ClearInMemoryStates() + { + _memorySavestates.Clear(); + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs new file mode 100644 index 0000000000..6673f561ff --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace BizHawk.Client.Common +{ + public sealed class MoviePluginLibrary + { + public MoviePluginLibrary() + { } + + [LuaMethodExample("if ( movie.startsfromsavestate( ) ) then\r\n\tconsole.log( \"Returns whether or not the movie is a savestate-anchored movie\" );\r\nend;")] + [LuaMethod("startsfromsavestate", "Returns whether or not the movie is a savestate-anchored movie")] + public bool StartsFromSavestate() + { + return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSavestate; + } + + [LuaMethodExample("if ( movie.startsfromsaveram( ) ) then\r\n\tconsole.log( \"Returns whether or not the movie is a saveram-anchored movie\" );\r\nend;")] + [LuaMethod("startsfromsaveram", "Returns whether or not the movie is a saveram-anchored movie")] + public bool StartsFromSaveram() + { + return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSaveRam; + } + + [LuaMethodExample("local stmovfil = movie.filename( );")] + [LuaMethod("filename", "Returns the file name including path of the currently loaded movie")] + public static string Filename() + { + return Global.MovieSession.Movie.Filename; + } + + [LuaMethodExample("local nlmovget = movie.getinput( 500 );")] + [LuaMethod("getinput", "Returns a table of buttons pressed on a given frame of the loaded movie")] + public Dictionary GetInput(int frame) + { + if (!Global.MovieSession.Movie.IsActive) + { + Console.WriteLine("No movie loaded"); + return null; + } + + var input = new Dictionary(); + var adapter = Global.MovieSession.Movie.GetInputState(frame); + + if (adapter == null) + { + Console.WriteLine("Can't get input of the last frame of the movie. Use the previous frame"); + return null; + } + + foreach (var button in adapter.Definition.BoolButtons) + { + input[button] = adapter.IsPressed(button); + } + + foreach (var button in adapter.Definition.FloatControls) + { + input[button] = adapter.GetFloat(button); + } + + return input; + } + + [LuaMethodExample("local stmovget = movie.getinputasmnemonic( 500 );")] + [LuaMethod("getinputasmnemonic", "Returns the input of a given frame of the loaded movie in a raw inputlog string")] + public string GetInputAsMnemonic(int frame) + { + if (Global.MovieSession.Movie.IsActive && frame < Global.MovieSession.Movie.InputLogLength) + { + var lg = Global.MovieSession.LogGeneratorInstance(); + lg.SetSource(Global.MovieSession.Movie.GetInputState(frame)); + return lg.GenerateLogEntry(); + } + + return ""; + } + + [LuaMethodExample("if ( movie.getreadonly( ) ) then\r\n\tconsole.log( \"Returns true if the movie is in read-only mode, false if in read+write\" );\r\nend;")] + [LuaMethod("getreadonly", "Returns true if the movie is in read-only mode, false if in read+write")] + public static bool GetReadOnly() + { + return Global.MovieSession.ReadOnly; + } + + [LuaMethodExample("local ulmovget = movie.getrerecordcount();")] + [LuaMethod("getrerecordcount", "Gets the rerecord count of the current movie.")] + public static ulong GetRerecordCount() + { + return Global.MovieSession.Movie.Rerecords; + } + + [LuaMethodExample("if ( movie.getrerecordcounting( ) ) then\r\n\tconsole.log( \"Returns whether or not the current movie is incrementing rerecords on loadstate\" );\r\nend;")] + [LuaMethod("getrerecordcounting", "Returns whether or not the current movie is incrementing rerecords on loadstate")] + public static bool GetRerecordCounting() + { + return Global.MovieSession.Movie.IsCountingRerecords; + } + + [LuaMethodExample("if ( movie.isloaded( ) ) then\r\n\tconsole.log( \"Returns true if a movie is loaded in memory ( play, record, or finished modes ), false if not ( inactive mode )\" );\r\nend;")] + [LuaMethod("isloaded", "Returns true if a movie is loaded in memory (play, record, or finished modes), false if not (inactive mode)")] + public static bool IsLoaded() + { + return Global.MovieSession.Movie.IsActive; + } + + [LuaMethodExample("local domovlen = movie.length( );")] + [LuaMethod("length", "Returns the total number of frames of the loaded movie")] + public static double Length() + { + return Global.MovieSession.Movie.FrameCount; + } + + [LuaMethodExample("local stmovmod = movie.mode( );")] + [LuaMethod("mode", "Returns the mode of the current movie. Possible modes: \"PLAY\", \"RECORD\", \"FINISHED\", \"INACTIVE\"")] + public static string Mode() + { + if (Global.MovieSession.Movie.IsFinished) + { + return "FINISHED"; + } + + if (Global.MovieSession.Movie.IsPlaying) + { + return "PLAY"; + } + + if (Global.MovieSession.Movie.IsRecording) + { + return "RECORD"; + } + + return "INACTIVE"; + } + + [LuaMethodExample("movie.save( \"C:\\moviename.ext\" );")] + [LuaMethod("save", "Saves the current movie to the disc. If the filename is provided (no extension or path needed), the movie is saved under the specified name to the current movie directory. The filename may contain a subdirectory, it will be created if it doesn't exist. Existing files won't get overwritten.")] + public void Save(string filename = "") + { + if (!Global.MovieSession.Movie.IsActive) + { + return; + } + + if (!string.IsNullOrEmpty(filename)) + { + filename += "." + Global.MovieSession.Movie.PreferredExtension; + var test = new FileInfo(filename); + if (test.Exists) + { + Console.WriteLine($"File {filename} already exists, will not overwrite"); + return; + } + + Global.MovieSession.Movie.Filename = filename; + } + + Global.MovieSession.Movie.Save(); + } + + [LuaMethodExample("movie.setreadonly( false );")] + [LuaMethod("setreadonly", "Sets the read-only state to the given value. true for read only, false for read+write")] + public static void SetReadOnly(bool readOnly) + { + Global.MovieSession.ReadOnly = readOnly; + } + + [LuaMethodExample("movie.setrerecordcount( 20.0 );")] + [LuaMethod("setrerecordcount", "Sets the rerecord count of the current movie.")] + public static void SetRerecordCount(double count) + { + // Lua numbers are always double, integer precision holds up + // to 53 bits, so throw an error if it's bigger than that. + const double PrecisionLimit = 9007199254740992d; + + if (count > PrecisionLimit) + { + throw new Exception("Rerecord count exceeds Lua integer precision."); + } + + Global.MovieSession.Movie.Rerecords = (ulong)count; + } + + [LuaMethodExample("movie.setrerecordcounting( true );")] + [LuaMethod("setrerecordcounting", "Sets whether or not the current movie will increment the rerecord counter on loadstate")] + public static void SetRerecordCounting(bool counting) + { + Global.MovieSession.Movie.IsCountingRerecords = counting; + } + + [LuaMethodExample("movie.stop( );")] + [LuaMethod("stop", "Stops the current movie")] + public static void Stop() + { + Global.MovieSession.Movie.Stop(); + } + + [LuaMethodExample("local domovget = movie.getfps( );")] + [LuaMethod("getfps", "If a movie is loaded, gets the frames per second used by the movie to determine the movie length time")] + public static double GetFps() + { + if (Global.MovieSession.Movie.IsActive) + { + var movie = Global.MovieSession.Movie; + var system = movie.HeaderEntries[HeaderKeys.PLATFORM]; + var pal = movie.HeaderEntries.ContainsKey(HeaderKeys.PAL) && + movie.HeaderEntries[HeaderKeys.PAL] == "1"; + + return new PlatformFrameRates()[system, pal]; + } + + return 0.0; + } + + [LuaMethodExample("local nlmovget = movie.getheader( );")] + [LuaMethod("getheader", "If a movie is active, will return the movie header as a lua table")] + public Dictionary GetHeader() + { + var table = new Dictionary(); + if (Global.MovieSession.Movie.IsActive) + { + foreach (var kvp in Global.MovieSession.Movie.HeaderEntries) + { + table[kvp.Key] = kvp.Value; + } + } + + return table; + } + + [LuaMethodExample("local nlmovget = movie.getcomments( );")] + [LuaMethod("getcomments", "If a movie is active, will return the movie comments as a lua table")] + public List GetComments() + { + var list = new List(Global.MovieSession.Movie.Comments.Count); + if (Global.MovieSession.Movie.IsActive) + { + for (int i = 0; i < Global.MovieSession.Movie.Comments.Count; i++) + { + list[i] = Global.MovieSession.Movie.Comments[i]; + } + } + + return list; + } + + [LuaMethodExample("local nlmovget = movie.getsubtitles( );")] + [LuaMethod("getsubtitles", "If a movie is active, will return the movie subtitles as a lua table")] + public List GetSubtitles() + { + var list = new List(Global.MovieSession.Movie.Subtitles.Count); + if (Global.MovieSession.Movie.IsActive) + { + for (int i = 0; i < Global.MovieSession.Movie.Subtitles.Count; i++) + { + list[i] = Global.MovieSession.Movie.Subtitles[i].ToString(); + } + } + + return list; + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs b/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs new file mode 100644 index 0000000000..1613ac46ce --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs @@ -0,0 +1,52 @@ +using System; +using System.ComponentModel; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class UserDataPluginLibrary + { + public UserDataPluginLibrary() + { } + + public void Set(string name, object value) + { + if (value != null) + { + var t = value.GetType(); + if (!t.IsPrimitive && t != typeof(string)) + { + throw new InvalidOperationException("Invalid type for userdata"); + } + } + + Global.UserBag[name] = value; + } + + public object Get(string key) + { + if (Global.UserBag.ContainsKey(key)) + { + return Global.UserBag[key]; + } + + return null; + } + + public void Clear() + { + Global.UserBag.Clear(); + } + + public bool Remove(string key) + { + return Global.UserBag.Remove(key); + } + + public bool ContainsKey(string key) + { + return Global.UserBag.ContainsKey(key); + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginMemoryBase.cs b/BizHawk.Client.Common/plugins/PluginMemoryBase.cs new file mode 100644 index 0000000000..92bfad1a81 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginMemoryBase.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; + +namespace BizHawk.Client.Common +{ + /// + /// Base class for the Memory and MainMemory plugin libraries + /// + public abstract class PluginMemoryBase + { + [RequiredService] + protected IEmulator Emulator { get; set; } + + [OptionalService] + protected IMemoryDomains MemoryDomainCore { get; set; } + + protected abstract MemoryDomain Domain { get; } + + protected PluginMemoryBase() + { + + } + + protected IMemoryDomains DomainList + { + get + { + if (MemoryDomainCore != null) + { + return MemoryDomainCore; + } + + var error = $"Error: {Emulator.Attributes().CoreName} does not implement memory domains"; + Console.WriteLine(error); + throw new NotImplementedException(error); + } + } + + public string VerifyMemoryDomain(string domain) + { + try + { + if (DomainList[domain] == null) + { + Console.WriteLine($"Unable to find domain: {domain}, falling back to current"); + return Domain.Name; + } + + return domain; + } + catch // Just in case + { + Console.WriteLine($"Unable to find domain: {domain}, falling back to current"); + } + + return Domain.Name; + } + + protected uint ReadUnsignedByte(int addr, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + if (addr < d.Size) + { + return d.PeekByte(addr); + } + + Console.WriteLine("Warning: attempted read of " + addr + " outside the memory size of " + d.Size); + return 0; + } + + protected void WriteUnsignedByte(int addr, uint v, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + if (d.CanPoke()) + { + if (addr < d.Size) + { + d.PokeByte(addr, (byte)v); + } + else + { + Console.WriteLine("Warning: attempted write to " + addr + " outside the memory size of " + d.Size); + } + } + else + { + Console.WriteLine($"Error: the domain {d.Name} is not writable"); + } + } + + protected static int U2S(uint u, int size) + { + var s = (int)u; + s <<= 8 * (4 - size); + s >>= 8 * (4 - size); + return s; + } + + protected int ReadSignedLittle(int addr, int size, string domain = null) + { + return U2S(ReadUnsignedLittle(addr, size, domain), size); + } + + protected uint ReadUnsignedLittle(int addr, int size, string domain = null) + { + uint v = 0; + for (var i = 0; i < size; ++i) + { + v |= ReadUnsignedByte(addr + i, domain) << (8 * i); + } + + return v; + } + + protected int ReadSignedBig(int addr, int size, string domain = null) + { + return U2S(ReadUnsignedBig(addr, size, domain), size); + } + + protected uint ReadUnsignedBig(int addr, int size, string domain = null) + { + uint v = 0; + for (var i = 0; i < size; ++i) + { + v |= ReadUnsignedByte(addr + i, domain) << (8 * (size - 1 - i)); + } + + return v; + } + + protected void WriteSignedLittle(int addr, int v, int size, string domain = null) + { + WriteUnsignedLittle(addr, (uint)v, size, domain); + } + + protected void WriteUnsignedLittle(int addr, uint v, int size, string domain = null) + { + for (var i = 0; i < size; ++i) + { + WriteUnsignedByte(addr + i, (v >> (8 * i)) & 0xFF, domain); + } + } + + protected void WriteSignedBig(int addr, int v, int size, string domain = null) + { + WriteUnsignedBig(addr, (uint)v, size, domain); + } + + protected void WriteUnsignedBig(int addr, uint v, int size, string domain = null) + { + for (var i = 0; i < size; ++i) + { + WriteUnsignedByte(addr + i, (v >> (8 * (size - 1 - i))) & 0xFF, domain); + } + } + + #region public Library implementations + + protected List ReadByteRange(int addr, int length, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + var lastAddr = length + addr; + var list = new List(); + for (; addr <= lastAddr; addr++) + { + if (addr < d.Size) + list.Add(d.PeekByte(addr)); + else { + Console.WriteLine("Warning: Attempted read " + addr + " outside memory domain size of " + d.Size + " in readbyterange()"); + list.Add(0); + } + } + + return list; + } + + protected void WriteByteRange(int addr, List memoryblock, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + if (d.CanPoke()) + { + for (var i = 0; i < memoryblock.Count; i++) + { + if (addr < d.Size) + { + d.PokeByte(addr++, memoryblock[i]); + } + else + { + Console.WriteLine("Warning: Attempted write " + addr + " outside memory domain size of " + d.Size + " in writebyterange()"); + } + } + } + else + { + Console.WriteLine($"Error: the domain {d.Name} is not writable"); + } + } + + protected float ReadFloat(int addr, bool bigendian, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + if (addr < d.Size) + { + var val = d.PeekUint(addr, bigendian); + var bytes = BitConverter.GetBytes(val); + return BitConverter.ToSingle(bytes, 0); + } + + Console.WriteLine("Warning: Attempted read " + addr + " outside memory size of " + d.Size); + + return 0; + } + + protected void WriteFloat(int addr, double value, bool bigendian, string domain = null) + { + var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; + if (d.CanPoke()) + { + if (addr < d.Size) + { + var dv = (float)value; + var bytes = BitConverter.GetBytes(dv); + var v = BitConverter.ToUInt32(bytes, 0); + d.PokeUint(addr, v, bigendian); + } + else + { + Console.WriteLine("Warning: Attempted write " + addr + " outside memory size of " + d.Size); + } + } + else + { + Console.WriteLine($"Error: the domain {Domain.Name} is not writable"); + } + } + + #endregion + } +} diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index a5b9eaf9d6..9161107c04 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -634,6 +634,8 @@ + + diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs new file mode 100644 index 0000000000..71e0d1ec6f --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using System.IO; + +using BizHawk.Emulation.Common; +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class GUIDrawLibrary : GUIDrawPluginLibrary + { + public GUIDrawLibrary() + { + } + + private DisplaySurface _GUISurface = null; + + #region Gui API + + public override void DrawNew(string name, bool? clear = true) + { + try + { + DrawFinish(); + _GUISurface = GlobalWin.DisplayManager.LockLuaSurface(name, clear ?? true); + HasGUISurface = (_GUISurface != null); + + } + catch (InvalidOperationException ex) + { + Console.WriteLine(ex.ToString()); + } + } + + public override void DrawFinish() + { + if (_GUISurface != null) + { + GlobalWin.DisplayManager.UnlockLuaSurface(_GUISurface); + } + + _GUISurface = null; + HasGUISurface = false; + + } + #endregion + + #region Helpers + protected override Graphics GetGraphics() + { + var g = _GUISurface == null ? Graphics.FromImage(new Bitmap(1,1)) : _GUISurface.GetGraphics(); + + // we don't like CoreComm, right? Someone should find a different way to do this then. + var tx = Emulator.CoreComm.ScreenLogicalOffsetX; + var ty = Emulator.CoreComm.ScreenLogicalOffsetY; + if (tx != 0 || ty != 0) + { + var transform = g.Transform; + transform.Translate(-tx, -ty); + g.Transform = transform; + } + + return g; + } + #endregion + + public override void AddMessage(string message) + { + GlobalWin.OSD.AddMessage(message); + } + + public override void ClearGraphics() + { + _GUISurface.Clear(); + DrawFinish(); + } + + public override void ClearText() + { + GlobalWin.OSD.ClearGUIText(); + } + + public override void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null) + { + using (var g = GetGraphics()) + { + try + { + var index = 0; + if (string.IsNullOrEmpty(fontfamily)) + { + index = _defaultPixelFont; + } + else + { + switch (fontfamily) + { + case "fceux": + case "0": + index = 0; + break; + case "gens": + case "1": + index = 1; + break; + default: + Console.WriteLine($"Unable to find font family: {fontfamily}"); + return; + } + } + + var f = new StringFormat(StringFormat.GenericTypographic) + { + FormatFlags = StringFormatFlags.MeasureTrailingSpaces + }; + var font = new Font(GlobalWin.DisplayManager.CustomFonts.Families[index], 8, FontStyle.Regular, GraphicsUnit.Pixel); + Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize(); + var rect = new Rectangle(new Point(x, y), sizeOfText + new Size(1, 0)); + g.FillRectangle(GetBrush(backcolor ?? _defaultTextBackground.Value), rect); + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; + g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y); + } + catch (Exception) + { + return; + } + } + } + + public override void Text(int x, int y, string message, Color? forecolor = null, string anchor = null) + { + var a = 0; + + if (!string.IsNullOrEmpty(anchor)) + { + switch (anchor) + { + case "0": + case "topleft": + a = 0; + break; + case "1": + case "topright": + a = 1; + break; + case "2": + case "bottomleft": + a = 2; + break; + case "3": + case "bottomright": + a = 3; + break; + } + } + else + { + x -= Emulator.CoreComm.ScreenLogicalOffsetX; + y -= Emulator.CoreComm.ScreenLogicalOffsetY; + } + + GlobalWin.OSD.AddGUIText(message, x, y, Color.Black, forecolor ?? Color.White, a); + } + } +} \ No newline at end of file From bb020540eb9dd207f0998104bae11977446b9d60 Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 31 Aug 2018 21:26:38 -0700 Subject: [PATCH 02/22] Remove extraneous non-existent file/folders from project. --- BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj | 1 - BizHawk.sln | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 9161107c04..e4d50eb1de 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -635,7 +635,6 @@ - diff --git a/BizHawk.sln b/BizHawk.sln index 63b4c5be18..2b1a0659ef 100644 --- a/BizHawk.sln +++ b/BizHawk.sln @@ -1,7 +1,6 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2047 MinimumVisualStudioVersion = 12.0.31101.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Version", "Version\Version.csproj", "{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}" EndProject @@ -145,6 +144,9 @@ Global {B95649F5-A0AE-41EB-B62B-578A2AFF5E18} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1A77376C-2741-489C-90E1-03E415910B65} + EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = BizHawk.Client.EmuHawk\BizHawk.Client.EmuHawk.csproj EndGlobalSection From 0a6aa912cfa1891176b8316ba5dd91cbd4f66a90 Mon Sep 17 00:00:00 2001 From: upthorn Date: Sat, 1 Sep 2018 03:19:05 -0700 Subject: [PATCH 03/22] Further plugin interface design/development work --- .../BizHawk.Client.Common.csproj | 2 + BizHawk.Client.Common/plugins/IPlugin.cs | 12 ++ BizHawk.Client.Common/plugins/IPluginAPI.cs | 23 ++++ BizHawk.Client.Common/plugins/PluginBase.cs | 43 +----- .../plugins/PluginLibrary.MemoryEvents.cs | 45 ++++++ .../plugins/PluginLibrary.SQL.cs | 130 ++++++++++++++++++ .../plugins/PluginLibrary.UserData.cs | 2 +- .../plugins/PluginLibraryBase.cs | 30 ++++ ...GUIDrawLibrary.cs => Plugin.GUILibrary.cs} | 8 +- 9 files changed, 247 insertions(+), 48 deletions(-) create mode 100644 BizHawk.Client.Common/plugins/IPlugin.cs create mode 100644 BizHawk.Client.Common/plugins/IPluginAPI.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs create mode 100644 BizHawk.Client.Common/plugins/PluginLibraryBase.cs rename BizHawk.Client.EmuHawk/Plugins/Libraries/{GUIDrawLibrary.cs => Plugin.GUILibrary.cs} (95%) diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 18110a72f2..65c07d9649 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -137,8 +137,10 @@ + + diff --git a/BizHawk.Client.Common/plugins/IPlugin.cs b/BizHawk.Client.Common/plugins/IPlugin.cs new file mode 100644 index 0000000000..9220e90dbd --- /dev/null +++ b/BizHawk.Client.Common/plugins/IPlugin.cs @@ -0,0 +1,12 @@ +namespace BizHawk.Client.Common +{ + interface IPlugin + { + void PreFrameCallback(); + void PostFrameCallback(); + void SaveStateCallback(string name); + void LoadStateCallback(string name); + void InputPollCallback(); + void Init(IPluginAPI api); + } +} diff --git a/BizHawk.Client.Common/plugins/IPluginAPI.cs b/BizHawk.Client.Common/plugins/IPluginAPI.cs new file mode 100644 index 0000000000..786858d96a --- /dev/null +++ b/BizHawk.Client.Common/plugins/IPluginAPI.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BizHawk.Client.Common +{ + interface IPluginAPI + { + EmulatorPluginLibrary EmuLib { get; set; } + GameInfoPluginLibrary GameInfoLib { get; set; } + GUIDrawPluginLibrary GuiLib { get; set; } + JoypadPluginLibrary JoypadLib { get; set; } + MemoryPluginLibrary MemLib { get; set; } + MemoryEventsPluginLibrary MemEventsLib { get; set; } + MemorySavestatePluginLibrary MemStateLib { get; set; } + MoviePluginLibrary MovieLib { get; set; } + SQLPluginLibrary SQLLib { get; set; } + UserDataPluginLibrary UserDataLib { get; set; } + List ClientLibs { get; set; } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginBase.cs b/BizHawk.Client.Common/plugins/PluginBase.cs index 44f88da68c..1e457e94f4 100644 --- a/BizHawk.Client.Common/plugins/PluginBase.cs +++ b/BizHawk.Client.Common/plugins/PluginBase.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; - -using BizHawk.Emulation.Common; -using BizHawk.Emulation.Common.IEmulatorExtensions; +using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { - public abstract class PluginBase + public abstract class PluginBase : IPlugin { [RequiredService] private IEmulator Emulator { get; set; } @@ -19,40 +15,5 @@ namespace BizHawk.Client.Common [OptionalService] private IDebuggable DebuggableCore { get; set; } - - public abstract void PreFrameCallback(); - public abstract void PostFrameCallback(); - public abstract void SaveStateCallback(string name); - public abstract void LoadStateCallback(string name); - public abstract void InputPollCallback(); - - protected virtual void AddReadCallback(Action cb, uint address, string domain) - { - if (DebuggableCore.MemoryCallbacksAvailable()) - { - DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Read, "Lua Hook", cb, address, null)); - } - } - protected virtual void AddWriteCallback(Action cb, uint address, string domain) - { - if (DebuggableCore.MemoryCallbacksAvailable()) - { - DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Write, "Lua Hook", cb, address, null)); - } - } - protected virtual void AddExecCallback(Action cb, uint address, string domain) - { - if (DebuggableCore.MemoryCallbacksAvailable() && DebuggableCore.MemoryCallbacks.ExecuteCallbacksAvailable) - { - DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Execute, "Lua Hook", cb, address, null)); - } - } - protected virtual void RemoveMemoryCallback(Action cb) - { - if (DebuggableCore.MemoryCallbacksAvailable()) - { - DebuggableCore.MemoryCallbacks.Remove(cb); - } - } } } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs b/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs new file mode 100644 index 0000000000..12dfc1ab3f --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs @@ -0,0 +1,45 @@ +using System; + +using BizHawk.Emulation.Common; +using BizHawk.Emulation.Common.IEmulatorExtensions; + +namespace BizHawk.Client.Common +{ + public sealed class MemoryEventsPluginLibrary + { + [RequiredService] + private IDebuggable DebuggableCore { get; set; } + + public MemoryEventsPluginLibrary () + { } + + public void AddReadCallback(Action cb, uint address, string domain) + { + if (DebuggableCore.MemoryCallbacksAvailable()) + { + DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Read, "Plugin Hook", cb, address, null)); + } + } + public void AddWriteCallback(Action cb, uint address, string domain) + { + if (DebuggableCore.MemoryCallbacksAvailable()) + { + DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Write, "Plugin Hook", cb, address, null)); + } + } + public void AddExecCallback(Action cb, uint address, string domain) + { + if (DebuggableCore.MemoryCallbacksAvailable() && DebuggableCore.MemoryCallbacks.ExecuteCallbacksAvailable) + { + DebuggableCore.MemoryCallbacks.Add(new MemoryCallback(domain, MemoryCallbackType.Execute, "Plugin Hook", cb, address, null)); + } + } + public void RemoveMemoryCallback(Action cb) + { + if (DebuggableCore.MemoryCallbacksAvailable()) + { + DebuggableCore.MemoryCallbacks.Remove(cb); + } + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs b/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs new file mode 100644 index 0000000000..5271b82219 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data.SQLite; + +namespace BizHawk.Client.Common +{ + public sealed class SQLPluginLibrary + { + public SQLPluginLibrary() + { } + + SQLiteConnection m_dbConnection; + string connectionString; + + public string CreateDatabase(string name) + { + try + { + SQLiteConnection.CreateFile(name); + return "Database Created Successfully"; + } + catch (SQLiteException sqlEX) + { + return sqlEX.Message; + } + + } + + public string OpenDatabase(string name) + { + try + { + SQLiteConnectionStringBuilder connBuilder = new SQLiteConnectionStringBuilder(); + connBuilder.DataSource = name; + connBuilder.Version = 3; //SQLite version + connBuilder.JournalMode = SQLiteJournalModeEnum.Wal; //Allows for reads and writes to happen at the same time + connBuilder.DefaultIsolationLevel = System.Data.IsolationLevel.ReadCommitted; //This only helps make the database lock left. May be pointless now + connBuilder.SyncMode = SynchronizationModes.Off; //This shortens the delay for do synchronous calls. + m_dbConnection = new SQLiteConnection(connBuilder.ToString()); + connectionString = connBuilder.ToString(); + m_dbConnection.Open(); + m_dbConnection.Close(); + return "Database Opened Successfully"; + } + catch (SQLiteException sqlEX) + { + return sqlEX.Message; + } + } + + public string WriteCommand(string query = "") + { + if (query == "") + { + return "query is empty"; + } + try + { + m_dbConnection.Open(); + string sql = query; + SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection); + command.ExecuteNonQuery(); + m_dbConnection.Close(); + + return "Command ran successfully"; + + } + catch (NullReferenceException nullEX) + { + return "Database not open."; + } + catch (SQLiteException sqlEX) + { + m_dbConnection.Close(); + return sqlEX.Message; + } + } + + public dynamic ReadCommand(string query = "") + { + if (query == "") + { + return "query is empty"; + } + try + { + var table = new Dictionary(); + m_dbConnection.Open(); + string sql = "PRAGMA read_uncommitted =1;" + query; + SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection); + SQLiteDataReader reader = command.ExecuteReader(); + bool rows = reader.HasRows; + long rowCount = 0; + var columns = new List(); + for (int i = 0; i < reader.FieldCount; ++i) //Add all column names into list + { + columns.Add(reader.GetName(i)); + } + while (reader.Read()) + { + for (int i = 0; i < reader.FieldCount; ++i) + { + table[columns[i] + " " + rowCount.ToString()] = reader.GetValue(i); + } + rowCount += 1; + } + reader.Close(); + m_dbConnection.Close(); + if (rows == false) + { + return "No rows found"; + } + + return table; + + } + catch (NullReferenceException) + { + return "Database not opened."; + } + catch (SQLiteException sqlEX) + { + m_dbConnection.Close(); + return sqlEX.Message; + } + } + + } +} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs b/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs index 1613ac46ce..3d60ad8fb1 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs @@ -3,7 +3,7 @@ using System.ComponentModel; using BizHawk.Client.Common; -namespace BizHawk.Client.EmuHawk +namespace BizHawk.Client.Common { public sealed class UserDataPluginLibrary { diff --git a/BizHawk.Client.Common/plugins/PluginLibraryBase.cs b/BizHawk.Client.Common/plugins/PluginLibraryBase.cs new file mode 100644 index 0000000000..c480871c69 --- /dev/null +++ b/BizHawk.Client.Common/plugins/PluginLibraryBase.cs @@ -0,0 +1,30 @@ +using System.Drawing; + +namespace BizHawk.Client.Common +{ + public abstract class PluginLibraryBase + { + protected PluginLibraryBase() { } + public abstract string Name { get; } + + protected static Color? ToColor(object o) + { + if (o == null) + { + return null; + } + + if (o.GetType() == typeof(double)) + { + return Color.FromArgb((int)(long)(double)o); + } + + if (o.GetType() == typeof(string)) + { + return Color.FromName(o.ToString()); + } + + return null; + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/Plugin.GUILibrary.cs similarity index 95% rename from BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs rename to BizHawk.Client.EmuHawk/Plugins/Libraries/Plugin.GUILibrary.cs index 71e0d1ec6f..90b6ddba27 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/GUIDrawLibrary.cs +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/Plugin.GUILibrary.cs @@ -1,17 +1,13 @@ using System; -using System.Collections.Generic; using System.Drawing; -using System.Windows.Forms; -using System.IO; -using BizHawk.Emulation.Common; using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { - public sealed class GUIDrawLibrary : GUIDrawPluginLibrary + public sealed class GUIPluginLibrary : GUIDrawPluginLibrary { - public GUIDrawLibrary() + public GUIPluginLibrary() { } From 9e814896cb68cdc7de91b7f46f7d1eb418c400e1 Mon Sep 17 00:00:00 2001 From: upthorn Date: Mon, 3 Sep 2018 19:31:01 -0700 Subject: [PATCH 04/22] Some plugin interface libraries, and further refactoring. --- .../BizHawk.Client.Common.csproj | 3 + BizHawk.Client.Common/plugins/IPluginAPI.cs | 27 +- BizHawk.Client.Common/plugins/PluginBase.cs | 47 ++- .../plugins/PluginLibrary.Emu.cs | 4 +- .../plugins/PluginLibrary.GUIDraw.cs | 27 +- .../plugins/PluginLibrary.Gameinfo.cs | 4 +- .../plugins/PluginLibrary.Joypad.cs | 44 ++- .../plugins/PluginLibrary.Memory.cs | 69 ++-- .../plugins/PluginLibrary.MemoryEvents.cs | 4 +- .../plugins/PluginLibrary.MemorySavestate.cs | 6 +- .../plugins/PluginLibrary.Movie.cs | 4 +- .../plugins/PluginLibrary.SQL.cs | 4 +- .../plugins/PluginLibrary.UserData.cs | 4 +- .../plugins/PluginLibraryBase.cs | 1 - .../plugins/PluginMemoryBase.cs | 36 +- .../Plugins/Libraries/PluginLibrary.Client.cs | 351 ++++++++++++++++++ .../Libraries/PluginLibrary.Communications.cs | 121 ++++++ ...gin.GUILibrary.cs => PluginLibrary.GUI.cs} | 9 +- .../Plugins/Libraries/PluginLibrary.Input.cs | 43 +++ .../Libraries/PluginLibrary.Savestate.cs | 47 +++ .../Plugins/Libraries/PluginLibrary.cs | 135 +++++++ BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs | 28 ++ 22 files changed, 904 insertions(+), 114 deletions(-) create mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs create mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs rename BizHawk.Client.EmuHawk/Plugins/Libraries/{Plugin.GUILibrary.cs => PluginLibrary.GUI.cs} (95%) create mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs create mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs create mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs create mode 100644 BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 65c07d9649..f3bcc12f20 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -132,6 +132,8 @@ + + @@ -142,6 +144,7 @@ + diff --git a/BizHawk.Client.Common/plugins/IPluginAPI.cs b/BizHawk.Client.Common/plugins/IPluginAPI.cs index 786858d96a..175df3af92 100644 --- a/BizHawk.Client.Common/plugins/IPluginAPI.cs +++ b/BizHawk.Client.Common/plugins/IPluginAPI.cs @@ -1,23 +1,20 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BizHawk.Client.Common { - interface IPluginAPI + public interface IPluginAPI { - EmulatorPluginLibrary EmuLib { get; set; } - GameInfoPluginLibrary GameInfoLib { get; set; } - GUIDrawPluginLibrary GuiLib { get; set; } - JoypadPluginLibrary JoypadLib { get; set; } - MemoryPluginLibrary MemLib { get; set; } - MemoryEventsPluginLibrary MemEventsLib { get; set; } - MemorySavestatePluginLibrary MemStateLib { get; set; } - MoviePluginLibrary MovieLib { get; set; } - SQLPluginLibrary SQLLib { get; set; } - UserDataPluginLibrary UserDataLib { get; set; } - List ClientLibs { get; set; } + EmulatorPluginLibrary EmuLib { get; } + GameInfoPluginLibrary GameInfoLib { get; } + GUIDrawPluginBase GUILib { get; } + JoypadPluginLibrary JoypadLib { get; } + MemoryPluginLibrary MemLib { get; } + MemoryEventsPluginLibrary MemEventsLib { get; } + MemorySavestatePluginLibrary MemStateLib { get; } + MoviePluginLibrary MovieLib { get; } + SQLPluginLibrary SQLLib { get; } + UserDataPluginLibrary UserDataLib { get; } + Dictionary Libraries { get; } } } diff --git a/BizHawk.Client.Common/plugins/PluginBase.cs b/BizHawk.Client.Common/plugins/PluginBase.cs index 1e457e94f4..7ef2f4453d 100644 --- a/BizHawk.Client.Common/plugins/PluginBase.cs +++ b/BizHawk.Client.Common/plugins/PluginBase.cs @@ -4,16 +4,47 @@ namespace BizHawk.Client.Common { public abstract class PluginBase : IPlugin { - [RequiredService] - private IEmulator Emulator { get; set; } + /// + /// The base class from which all + /// plugins will be derived + /// + /// Actual plugins should implement + /// one of the below callback methods + /// or register memory callbacks in + /// their Init function. + /// + protected IPluginAPI _api; - [RequiredService] - private IMemoryDomains Domains { get; set; } + public PluginBase() { } - [OptionalService] - private IInputPollable InputPollableCore { get; set; } + public abstract string Name { get; } + public abstract string Description { get; } + + public bool Enabled => Running; + public bool Paused => !Running; - [OptionalService] - private IDebuggable DebuggableCore { get; set; } + public bool Running { get; set; } + + public void Stop() + { + Running = false; + } + + public void Toggle() + { + Running = !Running; + } + + public virtual void PreFrameCallback() { } + public virtual void PostFrameCallback() { } + public virtual void SaveStateCallback(string name) { } + public virtual void LoadStateCallback(string name) { } + public virtual void InputPollCallback() { } + public virtual void ExitCallback() { } + public virtual void Init (IPluginAPI api) + { + _api = api; + Running = true; + } } } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs index eb3dd485b9..b205516989 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs @@ -15,7 +15,7 @@ using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES; namespace BizHawk.Client.Common { [Description("A library for interacting with the currently loaded emulator core")] - public sealed class EmulatorPluginLibrary + public sealed class EmulatorPluginLibrary : PluginLibraryBase { [RequiredService] private IEmulator Emulator { get; set; } @@ -41,7 +41,7 @@ namespace BizHawk.Client.Common public Action FrameAdvanceCallback { get; set; } public Action YieldCallback { get; set; } - public EmulatorPluginLibrary() + public EmulatorPluginLibrary() : base() { } public static void DisplayVsync(bool enabled) diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs b/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs index 46081390d2..e6612ad7f7 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs @@ -8,15 +8,13 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { - public abstract class GUIDrawPluginLibrary + public abstract class GUIDrawPluginBase : PluginLibraryBase { [RequiredService] protected IEmulator Emulator { get; set; } - public GUIDrawPluginLibrary() - { - - } + public GUIDrawPluginBase() : base() + { } public bool HasGUISurface = false; @@ -166,32 +164,36 @@ namespace BizHawk.Client.Common { try { + float w; + float h; if (x < x2) { - x2 = Math.Abs(x - x2); + w = x2 - x; } else { x2 = x - x2; x -= x2; + w = Math.Max(x2, 0.1f); } if (y < y2) { - y2 = Math.Abs(y - y2); + h = y2 - y; } else { y2 = y - y2; y -= y2; + h = Math.Max(y2, 0.1f); } - g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, x2, y2); + g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, w, h); var bg = background ?? _defaultBackground; if (bg.HasValue) { - g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, x2 - 1, y2 - 1); + g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, Math.Max(w - 1, 0), Math.Max(h - 1, 0)); } } catch (Exception) @@ -389,12 +391,13 @@ namespace BizHawk.Client.Common { using (var g = GetGraphics()) { - g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, width, height); + var w = Math.Max(width, 0.1F); + var h = Math.Max(height, 0.1F); + g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, w, h); var bg = background ?? _defaultBackground; if (bg.HasValue) { - g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, width - 1, height - 1); - } + g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, Math.Max(w - 1, 0), Math.Max(h - 1, 0)); } } } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs index 6c9c21b070..e74ea5f21b 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs @@ -5,12 +5,12 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { - public sealed class GameInfoPluginLibrary + public sealed class GameInfoPluginLibrary : PluginLibraryBase { [OptionalService] private IBoardInfo BoardInfo { get; set; } - public GameInfoPluginLibrary() + public GameInfoPluginLibrary() : base() { } public string GetRomName() diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs index e981b0ef31..f09a1e5cb1 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs @@ -3,9 +3,10 @@ using System.Collections.Generic; namespace BizHawk.Client.Common { - public sealed class JoypadPluginLibrary + public sealed class JoypadPluginLibrary : PluginLibraryBase { - public JoypadPluginLibrary() { } + public JoypadPluginLibrary() : base() + { } public Dictionary Get(int? controller = null) { @@ -82,8 +83,6 @@ namespace BizHawk.Client.Common } } - [LuaMethodExample("joypad.set( { [\"Left\"] = true, [ \"A\" ] = true, [ \"B\" ] = true } );")] - [LuaMethod("set", "sets the given buttons to their provided values for the current frame")] public void Set(Dictionary buttons, int? controller = null) { try @@ -146,9 +145,24 @@ namespace BizHawk.Client.Common /*Eat it*/ } } + public void Set(string button, bool state, int? controller = null) + { + try + { + var toPress = button; + if (controller.HasValue) + { + toPress = "P" + controller + " " + button; + } - [LuaMethodExample("joypad.setanalog( { [ \"Tilt X\" ] = true, [ \"Tilt Y\" ] = false } );")] - [LuaMethod("setanalog", "sets the given analog controls to their provided values for the current frame. Note that unlike set() there is only the logic of overriding with the given value.")] + Global.LuaAndAdaptor.SetButton(toPress, state); + Global.ActiveController.Overrides(Global.LuaAndAdaptor); + } + catch + { + /*Eat it*/ + } + } public void SetAnalog(Dictionary controls, object controller = null) { try @@ -182,5 +196,23 @@ namespace BizHawk.Client.Common /*Eat it*/ } } + public void SetAnalog(string control, float value, object controller = null) + { + try + { + if (controller == null) + { + Global.StickyXORAdapter.SetFloat(control, value); + } + else + { + Global.StickyXORAdapter.SetFloat("P" + controller + " " + control, value); + } + } + catch + { + /*Eat it*/ + } + } } } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs index aa9daf90d3..543ea1780b 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs @@ -10,11 +10,14 @@ namespace BizHawk.Client.Common public sealed class MemoryPluginLibrary : PluginMemoryBase { private MemoryDomain _currentMemoryDomain; - private bool _isBigEndian; - public MemoryPluginLibrary(bool Big = false) + private bool _isBigEndian = false; + public MemoryPluginLibrary() : base() { - _isBigEndian = Big; + } + public void SetBigEndian() + { + _isBigEndian = true; } protected override MemoryDomain Domain @@ -94,7 +97,7 @@ namespace BizHawk.Client.Common return false; } - public string HashRegion(int addr, int count, string domain = null) + public string HashRegion(long addr, int count, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; @@ -128,25 +131,25 @@ namespace BizHawk.Client.Common #region Endian Handling - private int ReadSigned(int addr, int size, string domain = null) + private int ReadSigned(long addr, int size, string domain = null) { if (_isBigEndian) return ReadSignedBig(addr, size, domain); else return ReadSignedLittle(addr, size, domain); } - private uint ReadUnsigned(int addr, int size, string domain = null) + private uint ReadUnsigned(long addr, int size, string domain = null) { if (_isBigEndian) return ReadUnsignedBig(addr, size, domain); else return ReadUnsignedLittle(addr, size, domain); } - private void WriteSigned(int addr, int value, int size, string domain = null) + private void WriteSigned(long addr, int value, int size, string domain = null) { if (_isBigEndian) WriteSignedBig(addr, value, size, domain); else WriteSignedLittle(addr, value, size, domain); } - private void WriteUnsigned(int addr, uint value, int size, string domain = null) + private void WriteUnsigned(long addr, uint value, int size, string domain = null) { if (_isBigEndian) WriteUnsignedBig(addr, value, size, domain); else WriteUnsignedLittle(addr, value, size, domain); @@ -156,32 +159,32 @@ namespace BizHawk.Client.Common #region Common Special and Legacy Methods - public uint ReadByte(int addr, string domain = null) + public uint ReadByte(long addr, string domain = null) { return ReadUnsignedByte(addr, domain); } - public void WriteByte(int addr, uint value, string domain = null) + public void WriteByte(long addr, uint value, string domain = null) { WriteUnsignedByte(addr, value, domain); } - public new List ReadByteRange(int addr, int length, string domain = null) + public new List ReadByteRange(long addr, int length, string domain = null) { return base.ReadByteRange(addr, length, domain); } - public new void WriteByteRange(int addr, List memoryblock, string domain = null) + public new void WriteByteRange(long addr, List memoryblock, string domain = null) { base.WriteByteRange(addr, memoryblock, domain); } - public float ReadFloat(int addr, string domain = null) + public float ReadFloat(long addr, string domain = null) { return base.ReadFloat(addr, _isBigEndian, domain); } - public void WriteFloat(int addr, double value, string domain = null) + public void WriteFloat(long addr, double value, string domain = null) { base.WriteFloat(addr, value, _isBigEndian, domain); } @@ -190,22 +193,22 @@ namespace BizHawk.Client.Common #region 1 Byte - public int ReadS8(int addr, string domain = null) + public int ReadS8(long addr, string domain = null) { return (sbyte)ReadUnsignedByte(addr, domain); } - public void WriteS8(int addr, uint value, string domain = null) + public void WriteS8(long addr, uint value, string domain = null) { WriteUnsignedByte(addr, value, domain); } - public uint ReadU8(int addr, string domain = null) + public uint ReadU8(long addr, string domain = null) { - return ReadUnsignedByte(addr, domain); + return (byte)ReadUnsignedByte(addr, domain); } - public void WriteU8(int addr, uint value, string domain = null) + public void WriteU8(long addr, uint value, string domain = null) { WriteUnsignedByte(addr, value, domain); } @@ -213,22 +216,22 @@ namespace BizHawk.Client.Common #endregion #region 2 Byte - public int ReadS16(int addr, string domain = null) + public int ReadS16(long addr, string domain = null) { - return ReadSigned(addr, 2, domain); + return (short)ReadSigned(addr, 2, domain); } - public void WriteS16(int addr, int value, string domain = null) + public void WriteS16(long addr, int value, string domain = null) { WriteSigned(addr, value, 2, domain); } - public uint ReadU16(int addr, string domain = null) + public uint ReadU16(long addr, string domain = null) { - return ReadUnsigned(addr, 2, domain); + return (ushort)ReadUnsigned(addr, 2, domain); } - public void WriteU16(int addr, uint value, string domain = null) + public void WriteU16(long addr, uint value, string domain = null) { WriteUnsigned(addr, value, 2, domain); } @@ -236,21 +239,21 @@ namespace BizHawk.Client.Common #region 3 Byte - public int ReadS24(int addr, string domain = null) + public int ReadS24(long addr, string domain = null) { return ReadSigned(addr, 3, domain); } - public void WriteS24(int addr, int value, string domain = null) + public void WriteS24(long addr, int value, string domain = null) { WriteSigned(addr, value, 3, domain); } - public uint ReadU24(int addr, string domain = null) + public uint ReadU24(long addr, string domain = null) { return ReadUnsigned(addr, 3, domain); } - public void WriteU24(int addr, uint value, string domain = null) + public void WriteU24(long addr, uint value, string domain = null) { WriteUnsigned(addr, value, 3, domain); } @@ -259,22 +262,22 @@ namespace BizHawk.Client.Common #region 4 Byte - public int ReadS32(int addr, string domain = null) + public int ReadS32(long addr, string domain = null) { return ReadSigned(addr, 4, domain); } - public void WriteS32(int addr, int value, string domain = null) + public void WriteS32(long addr, int value, string domain = null) { WriteSigned(addr, value, 4, domain); } - public uint ReadU32(int addr, string domain = null) + public uint ReadU32(long addr, string domain = null) { return ReadUnsigned(addr, 4, domain); } - public void WriteU32(int addr, uint value, string domain = null) + public void WriteU32(long addr, uint value, string domain = null) { WriteUnsigned(addr, value, 4, domain); } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs b/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs index 12dfc1ab3f..9816e9344d 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs @@ -5,12 +5,12 @@ using BizHawk.Emulation.Common.IEmulatorExtensions; namespace BizHawk.Client.Common { - public sealed class MemoryEventsPluginLibrary + public sealed class MemoryEventsPluginLibrary : PluginLibraryBase { [RequiredService] private IDebuggable DebuggableCore { get; set; } - public MemoryEventsPluginLibrary () + public MemoryEventsPluginLibrary () : base() { } public void AddReadCallback(Action cb, uint address, string domain) diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs b/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs index f0916a518a..90950d6f73 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs @@ -6,10 +6,10 @@ using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { - public sealed class MemorySavestatePluginLibrary + public sealed class MemorySavestatePluginLibrary : PluginLibraryBase { - public MemorySavestatePluginLibrary() - { } + public MemorySavestatePluginLibrary() : base() + { } [RequiredService] private IStatable StatableCore { get; set; } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs index 6673f561ff..ac9552d9cd 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs @@ -4,9 +4,9 @@ using System.IO; namespace BizHawk.Client.Common { - public sealed class MoviePluginLibrary + public sealed class MoviePluginLibrary : PluginLibraryBase { - public MoviePluginLibrary() + public MoviePluginLibrary() : base() { } [LuaMethodExample("if ( movie.startsfromsavestate( ) ) then\r\n\tconsole.log( \"Returns whether or not the movie is a savestate-anchored movie\" );\r\nend;")] diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs b/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs index 5271b82219..dae76333af 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs @@ -5,9 +5,9 @@ using System.Data.SQLite; namespace BizHawk.Client.Common { - public sealed class SQLPluginLibrary + public sealed class SQLPluginLibrary : PluginLibraryBase { - public SQLPluginLibrary() + public SQLPluginLibrary() : base() { } SQLiteConnection m_dbConnection; diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs b/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs index 3d60ad8fb1..27d2dc5af4 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs @@ -5,9 +5,9 @@ using BizHawk.Client.Common; namespace BizHawk.Client.Common { - public sealed class UserDataPluginLibrary + public sealed class UserDataPluginLibrary : PluginLibraryBase { - public UserDataPluginLibrary() + public UserDataPluginLibrary() : base() { } public void Set(string name, object value) diff --git a/BizHawk.Client.Common/plugins/PluginLibraryBase.cs b/BizHawk.Client.Common/plugins/PluginLibraryBase.cs index c480871c69..17485c7103 100644 --- a/BizHawk.Client.Common/plugins/PluginLibraryBase.cs +++ b/BizHawk.Client.Common/plugins/PluginLibraryBase.cs @@ -5,7 +5,6 @@ namespace BizHawk.Client.Common public abstract class PluginLibraryBase { protected PluginLibraryBase() { } - public abstract string Name { get; } protected static Color? ToColor(object o) { diff --git a/BizHawk.Client.Common/plugins/PluginMemoryBase.cs b/BizHawk.Client.Common/plugins/PluginMemoryBase.cs index 92bfad1a81..21bf8b89e0 100644 --- a/BizHawk.Client.Common/plugins/PluginMemoryBase.cs +++ b/BizHawk.Client.Common/plugins/PluginMemoryBase.cs @@ -8,7 +8,7 @@ namespace BizHawk.Client.Common /// /// Base class for the Memory and MainMemory plugin libraries /// - public abstract class PluginMemoryBase + public abstract class PluginMemoryBase : PluginLibraryBase { [RequiredService] protected IEmulator Emulator { get; set; } @@ -18,10 +18,8 @@ namespace BizHawk.Client.Common protected abstract MemoryDomain Domain { get; } - protected PluginMemoryBase() - { - - } + protected PluginMemoryBase() : base() + { } protected IMemoryDomains DomainList { @@ -58,7 +56,7 @@ namespace BizHawk.Client.Common return Domain.Name; } - protected uint ReadUnsignedByte(int addr, string domain = null) + protected uint ReadUnsignedByte(long addr, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; if (addr < d.Size) @@ -70,7 +68,7 @@ namespace BizHawk.Client.Common return 0; } - protected void WriteUnsignedByte(int addr, uint v, string domain = null) + protected void WriteUnsignedByte(long addr, uint v, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; if (d.CanPoke()) @@ -98,12 +96,12 @@ namespace BizHawk.Client.Common return s; } - protected int ReadSignedLittle(int addr, int size, string domain = null) + protected int ReadSignedLittle(long addr, int size, string domain = null) { return U2S(ReadUnsignedLittle(addr, size, domain), size); } - protected uint ReadUnsignedLittle(int addr, int size, string domain = null) + protected uint ReadUnsignedLittle(long addr, int size, string domain = null) { uint v = 0; for (var i = 0; i < size; ++i) @@ -114,12 +112,12 @@ namespace BizHawk.Client.Common return v; } - protected int ReadSignedBig(int addr, int size, string domain = null) + protected int ReadSignedBig(long addr, int size, string domain = null) { return U2S(ReadUnsignedBig(addr, size, domain), size); } - protected uint ReadUnsignedBig(int addr, int size, string domain = null) + protected uint ReadUnsignedBig(long addr, int size, string domain = null) { uint v = 0; for (var i = 0; i < size; ++i) @@ -130,12 +128,12 @@ namespace BizHawk.Client.Common return v; } - protected void WriteSignedLittle(int addr, int v, int size, string domain = null) + protected void WriteSignedLittle(long addr, int v, int size, string domain = null) { WriteUnsignedLittle(addr, (uint)v, size, domain); } - protected void WriteUnsignedLittle(int addr, uint v, int size, string domain = null) + protected void WriteUnsignedLittle(long addr, uint v, int size, string domain = null) { for (var i = 0; i < size; ++i) { @@ -143,12 +141,12 @@ namespace BizHawk.Client.Common } } - protected void WriteSignedBig(int addr, int v, int size, string domain = null) + protected void WriteSignedBig(long addr, int v, int size, string domain = null) { WriteUnsignedBig(addr, (uint)v, size, domain); } - protected void WriteUnsignedBig(int addr, uint v, int size, string domain = null) + protected void WriteUnsignedBig(long addr, uint v, int size, string domain = null) { for (var i = 0; i < size; ++i) { @@ -158,7 +156,7 @@ namespace BizHawk.Client.Common #region public Library implementations - protected List ReadByteRange(int addr, int length, string domain = null) + protected List ReadByteRange(long addr, int length, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; var lastAddr = length + addr; @@ -176,7 +174,7 @@ namespace BizHawk.Client.Common return list; } - protected void WriteByteRange(int addr, List memoryblock, string domain = null) + protected void WriteByteRange(long addr, List memoryblock, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; if (d.CanPoke()) @@ -199,7 +197,7 @@ namespace BizHawk.Client.Common } } - protected float ReadFloat(int addr, bool bigendian, string domain = null) + protected float ReadFloat(long addr, bool bigendian, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; if (addr < d.Size) @@ -214,7 +212,7 @@ namespace BizHawk.Client.Common return 0; } - protected void WriteFloat(int addr, double value, bool bigendian, string domain = null) + protected void WriteFloat(long addr, double value, bool bigendian, string domain = null) { var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)]; if (d.CanPoke()) diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs new file mode 100644 index 0000000000..b37d5f37dc --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs @@ -0,0 +1,351 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using BizHawk.Common; +using BizHawk.Emulation.Common; +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class EmuHawkPluginLibrary : PluginLibraryBase + { + [RequiredService] + private IEmulator Emulator { get; set; } + + [RequiredService] + private IVideoProvider VideoProvider { get; set; } + + private readonly Dictionary _filterMappings = new Dictionary + { + { 0, "None" }, + { 1, "x2SAI" }, + { 2, "SuperX2SAI" }, + { 3, "SuperEagle" }, + { 4, "Scanlines" }, + }; + + public EmuHawkPluginLibrary() : base() + { } + + public void CloseEmulator() + { + GlobalWin.MainForm.CloseEmulator(); + } + + public void CloseEmulatorWithCode(int exitCode) + { + GlobalWin.MainForm.CloseEmulator(exitCode); + } + + public static int BorderHeight() + { + var point = new System.Drawing.Point(0, 0); + return GlobalWin.DisplayManager.TransformPoint(point).Y; + } + + public static int BorderWidth() + { + var point = new System.Drawing.Point(0, 0); + return GlobalWin.DisplayManager.TransformPoint(point).X; + } + + public int BufferHeight() + { + return VideoProvider.BufferHeight; + } + + public int BufferWidth() + { + return VideoProvider.BufferWidth; + } + + public void ClearAutohold() + { + GlobalWin.MainForm.ClearHolds(); + } + + public static void CloseRom() + { + GlobalWin.MainForm.CloseRom(); + } + + public void EnableRewind(bool enabled) + { + GlobalWin.MainForm.EnableRewind(enabled); + } + + public void FrameSkip(int numFrames) + { + if (numFrames > 0) + { + Global.Config.FrameSkip = numFrames; + GlobalWin.MainForm.FrameSkipMessage(); + } + else + { + Console.WriteLine("Invalid frame skip value"); + } + } + + public static int GetTargetScanlineIntensity() + { + return Global.Config.TargetScanlineFilterIntensity; + } + + public int GetWindowSize() + { + return Global.Config.TargetZoomFactors[Emulator.SystemId]; + } + + public static void SetGameExtraPadding(int left, int top, int right, int bottom) + { + GlobalWin.DisplayManager.GameExtraPadding = new System.Windows.Forms.Padding(left, top, right, bottom); + GlobalWin.MainForm.FrameBufferResized(); + } + + public static void SetSoundOn(bool enable) + { + Global.Config.SoundEnabled = enable; + } + + public static bool GetSoundOn() + { + return Global.Config.SoundEnabled; + } + + public static void SetClientExtraPadding(int left, int top, int right, int bottom) + { + GlobalWin.DisplayManager.ClientExtraPadding = new System.Windows.Forms.Padding(left, top, right, bottom); + GlobalWin.MainForm.FrameBufferResized(); + } + + public static bool IsPaused() + { + return GlobalWin.MainForm.EmulatorPaused; + } + + public static bool IsTurbo() + { + return GlobalWin.MainForm.IsTurboing; + } + + public static bool IsSeeking() + { + return GlobalWin.MainForm.IsSeeking; + } + + public static void OpenCheats() + { + GlobalWin.Tools.Load(); + } + + public static void OpenHexEditor() + { + GlobalWin.Tools.Load(); + } + + public static void OpenRamWatch() + { + GlobalWin.Tools.LoadRamWatch(loadDialog: true); + } + + public static void OpenRamSearch() + { + GlobalWin.Tools.Load(); + } + + public static void OpenRom(string path) + { + var ioa = OpenAdvancedSerializer.ParseWithLegacy(path); + GlobalWin.MainForm.LoadRom(path, new MainForm.LoadRomArgs { OpenAdvanced = ioa }); + } + + public static void OpenTasStudio() + { + GlobalWin.Tools.Load(); + } + + public static void OpenToolBox() + { + GlobalWin.Tools.Load(); + } + + public static void OpenTraceLogger() + { + GlobalWin.Tools.Load(); + } + + public static void Pause() + { + GlobalWin.MainForm.PauseEmulator(); + } + + public static void PauseAv() + { + GlobalWin.MainForm.PauseAvi = true; + } + + public static void RebootCore() + { + ((LuaConsole)GlobalWin.Tools.Get()).LuaImp.IsRebootingCore = true; + GlobalWin.MainForm.RebootCore(); + ((LuaConsole)GlobalWin.Tools.Get()).LuaImp.IsRebootingCore = false; + } + + public static int ScreenHeight() + { + return GlobalWin.MainForm.PresentationPanel.NativeSize.Height; + } + + public static void Screenshot(string path = null) + { + if (path == null) + { + GlobalWin.MainForm.TakeScreenshot(); + } + else + { + GlobalWin.MainForm.TakeScreenshot(path); + } + } + + public static void ScreenshotToClipboard() + { + GlobalWin.MainForm.TakeScreenshotToClipboard(); + } + + public static void SetTargetScanlineIntensity(int val) + { + Global.Config.TargetScanlineFilterIntensity = val; + } + + public static void SetScreenshotOSD(bool value) + { + Global.Config.Screenshot_CaptureOSD = value; + } + + public static int ScreenWidth() + { + return GlobalWin.MainForm.PresentationPanel.NativeSize.Width; + } + + public void SetWindowSize(int size) + { + if (size == 1 || size == 2 || size == 3 || size == 4 || size == 5 || size == 10) + { + Global.Config.TargetZoomFactors[Emulator.SystemId] = size; + GlobalWin.MainForm.FrameBufferResized(); + GlobalWin.OSD.AddMessage("Window size set to " + size + "x"); + } + else + { + Console.WriteLine("Invalid window size"); + } + } + + public void SpeedMode(int percent) + { + if (percent > 0 && percent < 6400) + { + GlobalWin.MainForm.ClickSpeedItem(percent); + } + else + { + Console.WriteLine("Invalid speed value"); + } + } + + public static void TogglePause() + { + GlobalWin.MainForm.TogglePause(); + } + + public static int TransformPointX(int x) + { + var point = new System.Drawing.Point(x, 0); + return GlobalWin.DisplayManager.TransformPoint(point).X; + } + + public static int TransformPointY(int y) + { + var point = new System.Drawing.Point(0, y); + return GlobalWin.DisplayManager.TransformPoint(point).Y; + } + + public static void Unpause() + { + GlobalWin.MainForm.UnpauseEmulator(); + } + + public static void UnpauseAv() + { + GlobalWin.MainForm.PauseAvi = false; + } + + public static int Xpos() + { + return GlobalWin.MainForm.DesktopLocation.X; + } + + public static int Ypos() + { + return GlobalWin.MainForm.DesktopLocation.Y; + } + + public List GetAvailableTools() + { + var tools = GlobalWin.Tools.AvailableTools.ToList(); + var t = new List(tools.Count); + for (int i = 0; i < tools.Count; i++) + { + t[i] = tools[i].Name.ToLower(); + } + + return t; + } + + public Type GetTool(string name) + { + var toolType = ReflectionUtil.GetTypeByName(name) + .FirstOrDefault(x => typeof(IToolForm).IsAssignableFrom(x) && !x.IsInterface); + + if (toolType != null) + { + GlobalWin.Tools.Load(toolType); + } + + var selectedTool = GlobalWin.Tools.AvailableTools + .FirstOrDefault(tool => tool.GetType().Name.ToLower() == name.ToLower()); + + if (selectedTool != null) + { + return selectedTool; + } + + return null; + } + + public object CreateInstance(string name) + { + var possibleTypes = ReflectionUtil.GetTypeByName(name); + + if (possibleTypes.Any()) + { + return Activator.CreateInstance(possibleTypes.First()); + } + + return null; + } + + public void DisplayMessages(bool value) + { + Global.Config.DisplayMessages = value; + } + + public void SaveRam() + { + GlobalWin.MainForm.FlushSaveRAM(); + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs new file mode 100644 index 0000000000..43012c1817 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs @@ -0,0 +1,121 @@ +using System; +using System.ComponentModel; + +using BizHawk.Emulation.Common; +using BizHawk.Client.Common; +using System.Text; +using System.Collections.Generic; +using System.Net.Http; +using System.Windows.Forms; + + +namespace BizHawk.Client.EmuHawk +{ + public sealed class CommunicationPluginLibrary : PluginLibraryBase + { + [RequiredService] + private IEmulator Emulator { get; set; } + + [RequiredService] + private IVideoProvider VideoProvider { get; set; } + + public CommunicationPluginLibrary() : base() + { } + + public string SocketServerScreenShot() + { + return GlobalWin.socketServer.SendScreenshot(); + } + public string SocketServerScreenShotResponse() + { + return GlobalWin.socketServer.SendScreenshot(1000).ToString(); + } + + public string SocketServerSend(string SendString) + { + return "Sent : " + GlobalWin.socketServer.SendString(SendString).ToString() + " bytes"; + } + public string SocketServerResponse() + { + return GlobalWin.socketServer.ReceiveMessage(); + } + + public bool SocketServerSuccessful() + { + return GlobalWin.socketServer.Successful(); + } + public void SocketServerSetTimeout(int timeout) + { + GlobalWin.socketServer.SetTimeout(timeout); + } + // All MemoryMappedFile related methods + public void MmfSetFilename(string filename) + { + GlobalWin.memoryMappedFiles.SetFilename(filename); + } + public string MmfSetFilename() + { + return GlobalWin.memoryMappedFiles.GetFilename(); + } + + public int MmfScreenshot() + { + return GlobalWin.memoryMappedFiles.ScreenShotToFile(); + } + + public int MmfWrite(string mmf_filename, string outputString) + { + return GlobalWin.memoryMappedFiles.WriteToFile(mmf_filename, Encoding.ASCII.GetBytes(outputString)); + } + public string MmfRead(string mmf_filename, int expectedSize) + { + return GlobalWin.memoryMappedFiles.ReadFromFile(mmf_filename, expectedSize).ToString(); + } + // All HTTP related methods + public string HttpTest() + { + var list = new StringBuilder(); + list.AppendLine(GlobalWin.httpCommunication.TestGet()); + list.AppendLine(GlobalWin.httpCommunication.SendScreenshot()); + list.AppendLine("done testing"); + return list.ToString(); + } + public string HttpTestGet() + { + return GlobalWin.httpCommunication.TestGet(); + } + public string HttpGet(string url) + { + return GlobalWin.httpCommunication.ExecGet(url); + } + + public string HttpPost(string url, string payload) + { + return GlobalWin.httpCommunication.ExecPost(url, payload); + } + public string HttpPostScreenshot() + { + return GlobalWin.httpCommunication.SendScreenshot(); + } + public void HttpSetTimeout(int timeout) + { + GlobalWin.httpCommunication.SetTimeout(timeout); + } + public void HttpSetPostUrl(string url) + { + GlobalWin.httpCommunication.SetPostUrl(url); + } + public void HttpSetGetUrl(string url) + { + GlobalWin.httpCommunication.SetGetUrl(url); + } + public string HttpGetPostUrl() + { + return GlobalWin.httpCommunication.GetPostUrl(); + } + public string HttpGetGetUrl() + { + return GlobalWin.httpCommunication.GetGetUrl(); + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/Plugin.GUILibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs similarity index 95% rename from BizHawk.Client.EmuHawk/Plugins/Libraries/Plugin.GUILibrary.cs rename to BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs index 90b6ddba27..e22bd3e0fd 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/Plugin.GUILibrary.cs +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs @@ -5,11 +5,10 @@ using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { - public sealed class GUIPluginLibrary : GUIDrawPluginLibrary + public sealed class GUIPluginLibrary : GUIDrawPluginBase { - public GUIPluginLibrary() - { - } + public GUIPluginLibrary() : base() + { } private DisplaySurface _GUISurface = null; @@ -114,7 +113,7 @@ namespace BizHawk.Client.EmuHawk var font = new Font(GlobalWin.DisplayManager.CustomFonts.Families[index], 8, FontStyle.Regular, GraphicsUnit.Pixel); Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize(); var rect = new Rectangle(new Point(x, y), sizeOfText + new Size(1, 0)); - g.FillRectangle(GetBrush(backcolor ?? _defaultTextBackground.Value), rect); + if (backcolor.HasValue) g.FillRectangle(GetBrush(backcolor.Value), rect); g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y); } diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs new file mode 100644 index 0000000000..e2e289bae0 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs @@ -0,0 +1,43 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Windows.Forms; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class InputPluginLibrary : PluginLibraryBase + { + public InputPluginLibrary() : base() + { } + + public Dictionary Get() + { + var buttons = new Dictionary(); + foreach (var kvp in Global.ControllerInputCoalescer.BoolButtons().Where(kvp => kvp.Value)) + { + buttons[kvp.Key] = true; + } + + return buttons; + } + + public Dictionary GetMouse() + { + var buttons = new Dictionary(); + + // TODO - need to specify whether in "emu" or "native" coordinate space. + var p = GlobalWin.DisplayManager.UntransformPoint(Control.MousePosition); + buttons["X"] = p.X; + buttons["Y"] = p.Y; + buttons[MouseButtons.Left.ToString()] = (Control.MouseButtons & MouseButtons.Left) != 0; + buttons[MouseButtons.Middle.ToString()] = (Control.MouseButtons & MouseButtons.Middle) != 0; + buttons[MouseButtons.Right.ToString()] = (Control.MouseButtons & MouseButtons.Right) != 0; + buttons[MouseButtons.XButton1.ToString()] = (Control.MouseButtons & MouseButtons.XButton1) != 0; + buttons[MouseButtons.XButton2.ToString()] = (Control.MouseButtons & MouseButtons.XButton2) != 0; + buttons["Wheel"] = GlobalWin.MainForm.MouseWheelTracker; + return buttons; + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs new file mode 100644 index 0000000000..90f4e5e7f6 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.IO; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class SavestatePluginibrary : PluginLibraryBase + { + public SavestatePluginibrary() : base() + { } + + public void Load(string path) + { + if (!File.Exists(path)) + { + Console.WriteLine($"could not find file: {path}"); + } + else + { + GlobalWin.MainForm.LoadState(path, Path.GetFileName(path), true); + } + } + + public void LoadSlot(int slotNum) + { + if (slotNum >= 0 && slotNum <= 9) + { + GlobalWin.MainForm.LoadQuickSave("QuickSave" + slotNum, true); + } + } + + public void Save(string path) + { + GlobalWin.MainForm.SaveState(path, path, true); + } + + public void SaveSlot(int slotNum) + { + if (slotNum >= 0 && slotNum <= 9) + { + GlobalWin.MainForm.SaveQuickSave("QuickSave" + slotNum); + } + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs new file mode 100644 index 0000000000..1396c77334 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using BizHawk.Common.ReflectionExtensions; +using BizHawk.Emulation.Common; +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk + +{ + public class PluginLibrary + { +// public LuaDocumentation Docs { get; } + public PluginLibrary(IEmulatorServiceProvider serviceProvider) + { + // Docs.Clear(); + + // Register lua libraries + var libs = Assembly + .Load("BizHawk.Client.Common") + .GetTypes() + .Where(t => typeof(PluginLibraryBase).IsAssignableFrom(t)) + .Where(t => t.IsSealed) + .Where(t => ServiceInjector.IsAvailable(serviceProvider, t)) + .ToList(); + + libs.AddRange( + Assembly + .GetAssembly(typeof(PluginLibrary)) + .GetTypes() + .Where(t => typeof(PluginLibraryBase).IsAssignableFrom(t)) + .Where(t => t.IsSealed) + .Where(t => ServiceInjector.IsAvailable(serviceProvider, t))); + + foreach (var lib in libs) + { + bool addLibrary = true; + //var attributes = lib.GetCustomAttributes(typeof(LuaLibraryAttribute), false); + //if (attributes.Any()) + //{ + // addLibrary = VersionInfo.DeveloperBuild || (attributes.First() as LuaLibraryAttribute).Released; + //} + + if (addLibrary) + { + var instance = (PluginLibraryBase)Activator.CreateInstance(lib); + //instance.LuaRegister(lib, Docs); + //instance.LogOutputCallback = ConsoleLuaLibrary.LogOutput; + ServiceInjector.UpdateServices(serviceProvider, instance); + Libraries.Add(lib, instance); + } + } + } + private readonly Dictionary Libraries = new Dictionary(); + public List PluginList { get; } = new List(); + + public IEnumerable RunningPlugins + { + get { return PluginList.Where(plug => plug.Enabled); } + } + +// private FormsPluginLibrary FormsLibrary => (FormsLuaLibrary)Libraries[typeof(FormsLuaLibrary)]; + private EmulatorPluginLibrary EmulatorLuaLibrary => (EmulatorPluginLibrary)Libraries[typeof(EmulatorPluginLibrary)]; + public GUIPluginLibrary GuiLibrary => (GUIPluginLibrary)Libraries[typeof(GUIPluginLibrary)]; + + public void Restart(IEmulatorServiceProvider newServiceProvider) + { + foreach (var lib in Libraries) + { + ServiceInjector.UpdateServices(newServiceProvider, lib.Value); + } + foreach (var plugin in PluginList) + { + plugin.Init(new PluginAPI(Libraries)); + } + } + + public void StartPluginDrawing() + { + if (PluginList.Any() && !GuiLibrary.HasGUISurface) + { + GuiLibrary.DrawNew("emu"); + } + } + + public void EndPluginDrawing() + { + if (PluginList.Any()) + { + GuiLibrary.DrawFinish(); + } + } + + public void CallSaveStateEvent(string name) + { + foreach (var plugin in RunningPlugins) plugin.SaveStateCallback(name); + } + + public void CallLoadStateEvent(string name) + { + foreach (var plugin in RunningPlugins) plugin.LoadStateCallback(name); + } + + public void CallFrameBeforeEvent() + { + StartPluginDrawing(); + foreach (var plugin in RunningPlugins) plugin.PreFrameCallback(); + } + + public void CallFrameAfterEvent() + { + foreach (var plugin in RunningPlugins) plugin.PostFrameCallback(); + EndPluginDrawing(); + } + + public void CallExitEvent() + { + foreach (var plugin in RunningPlugins) plugin.ExitCallback(); + } + + public void Close() + { + GuiLibrary.Dispose(); + } + + public void Load(PluginBase plugin) + { + plugin.Init(new PluginAPI(Libraries)); + PluginList.Add(plugin); + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs b/BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs new file mode 100644 index 0000000000..c2e1ea3960 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class PluginAPI : IPluginAPI + { + public EmulatorPluginLibrary EmuLib => (EmulatorPluginLibrary)Libraries[typeof(EmulatorPluginLibrary)]; + public GameInfoPluginLibrary GameInfoLib => (GameInfoPluginLibrary)Libraries[typeof(GameInfoPluginLibrary)]; + public GUIDrawPluginBase GUILib => (GUIDrawPluginBase)Libraries[typeof(GUIPluginLibrary)]; + public JoypadPluginLibrary JoypadLib => (JoypadPluginLibrary)Libraries[typeof(JoypadPluginLibrary)]; + public MemoryPluginLibrary MemLib => (MemoryPluginLibrary)Libraries[typeof(MemoryPluginLibrary)]; + public MemoryEventsPluginLibrary MemEventsLib => (MemoryEventsPluginLibrary)Libraries[typeof(MemoryEventsPluginLibrary)]; + public MemorySavestatePluginLibrary MemStateLib => (MemorySavestatePluginLibrary)Libraries[typeof(MemorySavestatePluginLibrary)]; + public MoviePluginLibrary MovieLib => (MoviePluginLibrary)Libraries[typeof(MoviePluginLibrary)]; + public SQLPluginLibrary SQLLib => (SQLPluginLibrary)Libraries[typeof(SQLPluginLibrary)]; + public UserDataPluginLibrary UserDataLib => (UserDataPluginLibrary)Libraries[typeof(UserDataPluginLibrary)]; + public Dictionary Libraries { get; set; } + public PluginAPI(Dictionary libs) + { + Libraries = libs; + } + } +} From 6eed08f9653a36a3e87d28d0dbfc3e8b1a9b4b87 Mon Sep 17 00:00:00 2001 From: upthorn Date: Mon, 3 Sep 2018 19:31:43 -0700 Subject: [PATCH 05/22] An example plugin. Hard-coded for now. --- .../BizHawk.Client.EmuHawk.csproj | 9 +- BizHawk.Client.EmuHawk/GlobalWin.cs | 1 + BizHawk.Client.EmuHawk/MainForm.cs | 8 + .../Plugins/Example/Ecco2AssistantPlugin.cs | 798 ++++++++++++++++++ 4 files changed, 815 insertions(+), 1 deletion(-) create mode 100644 BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index e4d50eb1de..3b5cf29d1d 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -634,7 +634,9 @@ - + + + @@ -719,6 +721,10 @@ PlatformChooser.cs + + + + @@ -1841,6 +1847,7 @@ + diff --git a/BizHawk.Client.EmuHawk/GlobalWin.cs b/BizHawk.Client.EmuHawk/GlobalWin.cs index 5df3f651bf..5ede6c61fc 100644 --- a/BizHawk.Client.EmuHawk/GlobalWin.cs +++ b/BizHawk.Client.EmuHawk/GlobalWin.cs @@ -7,6 +7,7 @@ namespace BizHawk.Client.EmuHawk { public static MainForm MainForm; public static ToolManager Tools; + public static PluginLibrary Plugins; /// /// the IGL to be used for rendering diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index a989739283..9e488a00d5 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -253,6 +253,8 @@ namespace BizHawk.Client.EmuHawk GlobalWin.Sound.StartSound(); InputManager.RewireInputChain(); GlobalWin.Tools = new ToolManager(this); + GlobalWin.Plugins = new PluginLibrary(Emulator.ServiceProvider); + GlobalWin.Plugins.Load(new Ecco2AssistantPlugin()); RewireSound(); // Workaround for windows, location is -32000 when minimized, if they close it during this time, that's what gets saved @@ -2925,6 +2927,7 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallFrameBeforeEvent(); } + GlobalWin.Plugins.CallFrameBeforeEvent(); if (IsTurboing) { @@ -3011,6 +3014,7 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallFrameAfterEvent(); } + GlobalWin.Plugins.CallFrameAfterEvent(); if (IsTurboing) { @@ -3744,6 +3748,7 @@ namespace BizHawk.Client.EmuHawk } GlobalWin.Tools.Restart(); + GlobalWin.Plugins.Restart(Emulator.ServiceProvider); if (Global.Config.LoadCheatFileByGame) { @@ -3917,6 +3922,7 @@ namespace BizHawk.Client.EmuHawk Global.Game = GameInfo.NullInstance; GlobalWin.Tools.Restart(); + GlobalWin.Plugins.Restart(Emulator.ServiceProvider); RewireSound(); Text = "BizHawk" + (VersionInfo.DeveloperBuild ? " (interim) " : ""); HandlePlatformMenus(); @@ -4012,6 +4018,7 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallLoadStateEvent(userFriendlyStateName); } + GlobalWin.Plugins.CallLoadStateEvent(userFriendlyStateName); SetMainformMovieInfo(); GlobalWin.Tools.UpdateToolsBefore(fromLua); @@ -4141,6 +4148,7 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallSaveStateEvent(quickSlotName); } + GlobalWin.Plugins.CallSaveStateEvent(quickSlotName); } private void SaveStateAs() diff --git a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs b/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs new file mode 100644 index 0000000000..753bc5d425 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs @@ -0,0 +1,798 @@ +using System; +using System.Collections.Generic; +using System.Drawing; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class Ecco2AssistantPlugin : PluginBase + { + public override string Name => "Ecco 2 Assistant"; + + public override string Description => "Displays a hud with hitboxes, etc. Assists with maintaining maximum speed."; + + private enum Modes { disabled, Ecco1, Ecco2 } + private Modes _mode; + + private int _camX = 0; + private int _camY = 0; + private int _camXAddr; + private int _camYAddr; + private bool _prevOn = false; + private uint _prevCharge = 0; + private uint _prevF = 0; + + void DrawEccoOct(int x, int y, int r, Color? color = null, int fillAlpha = 0) + { + Point[] octPoints = { + new Point(x, y - r), + new Point((int)(x + Math.Sin(Math.PI / 4) * r), (int)(y - Math.Sin(Math.PI / 4) *r)), + new Point(x + r, y), + new Point((int)(x + Math.Sin(Math.PI / 4) * r), (int)(y + Math.Sin(Math.PI / 4) *r)), + new Point(x, y + r), + new Point((int)(x - Math.Sin(Math.PI / 4) * r), (int)(y + Math.Sin(Math.PI / 4) *r)), + new Point(x - r, y), + new Point((int)(x - Math.Sin(Math.PI / 4) * r), (int)(y - Math.Sin(Math.PI / 4) *r)) + }; + Color fillColor = color.HasValue ? Color.FromArgb(fillAlpha, color.Value) : Color.Empty; + _api.GUILib.DrawPolygon(octPoints, color, fillColor); + } + void DrawBoxMWH(int x, int y, int w, int h, Color? color = null, int fillAlpha = 0) + { + Color fillColor = color.HasValue ? Color.FromArgb(fillAlpha, color.Value) : Color.Empty; + _api.GUILib.DrawRectangle(x - w, y - h, w << 1, h << 1, color, fillColor); + } + void Print_Text(string message, int size, int x, int y, Color color) + { + _api.GUILib.DrawText(x, y, message, color, null); + } + void PutText(string message, int x, int y, int xl, int yl, int xh, int yh, Color bg, Color fg) + { + xl = Math.Max(xl, 0); + yl = Math.Max(xl, 0); + xh = Math.Min(xh + 639, 639); + yh = Math.Min(yh + 441, 441); + xh -= 4 * message.Length; + x = x - ((5 * (message.Length - 1)) / 2); + x = Math.Min(Math.Max(x, Math.Max(xl, 1)), Math.Min(xh, 638 - 4 * (int)message.Length)); + y = Math.Min(Math.Max(y - 3, Math.Max(yl, 1)), yh); + int[] xOffset = { -1, -1, -1, 0, 1, 1, 1, 0 }; + int[] yOffset = { -1, 0, 1, 1, 1, 0, -1, -1 }; + for (int i = 0; i < 8; i++) + Print_Text(message, message.Length, x + xOffset[i], y + yOffset[i], bg); + Print_Text(message, message.Length, x, y, fg); + } + + + void EccoDraw3D() + { + int ScreenX = (_api.MemLib.ReadS32(0xFFD5E0) >> 0xC); + int ScreenY = (_api.MemLib.ReadS32(0xFFD5E8) >> 0xC); + int ScreenZ = (_api.MemLib.ReadS32(0xFFD5E4) >> 0xB); + uint curObj = _api.MemLib.ReadU24(0xFFD4C1); + while (curObj != 0) + { + int Xpos = (_api.MemLib.ReadS32(curObj + 0x6) >> 0xC); + int Ypos = (_api.MemLib.ReadS32(curObj + 0xE) >> 0xC); + int Zpos = (_api.MemLib.ReadS32(curObj + 0xA) >> 0xB); + int Y = 224 - (Zpos - ScreenZ); + int X = (Xpos - ScreenX) + 0xA0; + uint type = _api.MemLib.ReadU32(curObj + 0x5A); + short height, width; + int display = 0; + if ((type == 0xD817E) || (type == 0xD4AB8)) + { + Y = 113 - (Ypos - ScreenY); + height = 0x10; + if (_api.MemLib.ReadU32(0xFFB166) < 0x1800) height = 0x8; + short radius = 31; + if (type == 0xD4AB8) + { + radius = 7; + height = 0x20; + } + width = radius; + DrawEccoOct(X, Y, radius, Color.Lime, 0); + display = 1; + } + else + { + width = height = 1; + if (curObj == 0xFFB134) display = 3; + } + if ((display & 1) != 0) + { + Y = 224 - (Zpos - ScreenZ); + DrawBoxMWH(X, Y, width, height, Color.Blue, 0); + } + if ((display & 2) != 0) + { + Y = 113 - (Ypos - ScreenY); + DrawBoxMWH(X, Y, width, height, Color.Lime, 0); + } + curObj = _api.MemLib.ReadU24(curObj+1); + } + } + void EccoDrawBoxes() + { + // CamX-=8; + int Width2, Height2; + //Ecco HP and Air + int i = 0; + int HP = _api.MemLib.ReadS16(0xFFAA16) << 3; + int air = _api.MemLib.ReadS16(0xFFAA18); + Color color; + int off = 0; + for (int j = 0; j < air; j++) + { + if (j - off == 448) + { + i++; off += 448; + } + color = Color.FromArgb(j >> 2, j >> 2, j >> 2); + _api.GUILib.DrawLine(128, j - off, 144, j - off, color); + } + for (i = 0; i < 16; i++) + for (int j = 0; j < Math.Min(HP, 448); j++) + { + color = Color.FromArgb(0, 0, (j>>1 & 0xF0)); + _api.GUILib.DrawPixel(144 + i, j, color); + } + + //Asterite + uint curObj = _api.MemLib.ReadU24(0xFFCFC9); + int Xpos, Xpos2, Ypos, Ypos2, Xmid, Ymid, X, X2, Y, Y2; + Xmid = 0; + Ymid = 0; + while (curObj != 0) + { + if (_api.MemLib.ReadU32(curObj + 8) != 0) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x3C); + Xpos2= _api.MemLib.ReadS16(curObj + 0x24); + Ypos = _api.MemLib.ReadS16(curObj + 0x40); + Ypos2= _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + if (_api.MemLib.ReadU8(curObj + 0x71) != 0) + { + DrawEccoOct(Xpos, Ypos, 40, Color.FromArgb(255, 192, 0), 0x7F); + DrawEccoOct(Xpos2, Ypos2, 40, Color.FromArgb(255, 192, 0), 0x7F); + } + } + else + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + } + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(0, Ymid-5), 424), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(2, Ymid-3), 426), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(2, Ymid-3), 426), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(0, Ymid-5), 424), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(1, Xmid-15), 606), Math.Min(Math.Max(1, Ymid-4), 425), Color.Blue); + curObj = _api.MemLib.ReadU24(curObj+1); + } + uint curlev = _api.MemLib.ReadU8(0xFFA7E0); + if ((_api.MemLib.ReadU8(0xFFA7D0) == 30)) + { + curObj = _api.MemLib.ReadU24(0xFFD425); + if ((curObj != 0) && (_api.MemLib.ReadU32(curObj + 8) != 0)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + DrawEccoOct(Xpos, Ypos, 20, Color.FromArgb(255, 192, 0)); + } + } + //aqua tubes + curObj = _api.MemLib.ReadU24(0xFFCFC5); + while (curObj != 0) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2= _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2= _api.MemLib.ReadS16(curObj + 0x38); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + // displayed = false; + uint type = _api.MemLib.ReadU8(curObj + 0x7E); + int yoff = 0; + switch (type) + { + /* case 0x11: + Xpos2 = Xmid; + Xmid = (Xpos + Xpos2) >> 1; + break; + case 0x12: + Xpos = Xmid; + Xmid = (Xpos + Xpos2) >> 1; + break; + case 0x13: + Ypos = Ymid; + Ymid = (Ypos + Ypos2) >> 1; + break; + case 0x14: + Ypos2 = Ymid; + Ymid = (Ypos + Ypos2) >> 1; + break;*/ + case 0x15: + for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) + _api.GUILib.DrawPixel(Xpos2 - TempX, Ymid + yoff, Color.FromArgb(127, 0, 255)); + for (int TempX = Math.Min(Math.Max(0, Xmid), 320); TempX <= Math.Min(Math.Max(8, Xpos2), 327); TempX++) + _api.GUILib.DrawPixel(TempX, Ymid, Color.FromArgb(127, 0, 255)); + for (uint TempX = (uint)Math.Min(Math.Max(0, Ymid), 223); TempX <= Math.Min(Math.Max(0, Ypos2), 223); TempX++) + _api.GUILib.DrawPixel(Xmid, (int)TempX, Color.FromArgb(127, 0, 255)); + break; + case 0x18: + case 0x19: + for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) + { + _api.GUILib.DrawPixel(Xmid + yoff, Ypos2-TempX, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + break; + case 0x1A: + for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) + _api.GUILib.DrawPixel(Xpos + TempX, Ymid + yoff, Color.FromArgb(127, 0, 255)); + for (int TempX = Math.Min(Math.Max(0, Xpos), 320); TempX <= Math.Min(Math.Max(8, Xmid), 327); TempX++) + _api.GUILib.DrawPixel(TempX, Ymid, Color.FromArgb(127, 0, 255)); + for (uint TempX = (uint)Math.Min(Math.Max(0, Ymid), 223); TempX <= Math.Min(Math.Max(0, Ypos2), 223); TempX++) + _api.GUILib.DrawPixel(Xmid, (int)TempX, Color.FromArgb(127, 0, 255)); + break; + case 0x1D: + for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) + { + _api.GUILib.DrawPixel(Xmid - yoff, Ypos2 - TempX, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + break; + case 0x1F: + for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) + _api.GUILib.DrawPixel(Xpos + TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); + for (int TempX = Math.Min(Math.Max(0, Xpos), 320); TempX <= Math.Min(Math.Max(8, Xmid), 327); TempX++) + _api.GUILib.DrawPixel(TempX, Ymid, Color.FromArgb(127, 0, 255)); + for (uint TempX = (uint)Math.Min(Math.Max(0, Ypos), 223); TempX <= Math.Min(Math.Max(0, Ymid), 223); TempX++) + _api.GUILib.DrawPixel(Xmid, (int)TempX, Color.FromArgb(127, 0, 255)); + break; + case 0x20: + case 0x21: + for (int TempX = 0; TempX <= Xmid-Xpos; TempX++) + { + _api.GUILib.DrawPixel(Xpos + TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + break; + case 0x22: + case 0x23: + for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) + { + _api.GUILib.DrawPixel(Xmid - yoff, Ypos + TempX, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + break; + case 0x24: + for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) + _api.GUILib.DrawPixel(Xpos2 - TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); + break; + case 0x25: + case 0x26: + for (int TempX = 0; TempX <= Xmid-Xpos; TempX++) + { + _api.GUILib.DrawPixel(Xpos2 - TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + break; + case 0x27: + case 0x28: + for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) + { + _api.GUILib.DrawPixel(Xmid + yoff, Ypos + TempX, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + break; + case 0x2B: + _api.GUILib.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.FromArgb(127, 0, 255)); + for (int TempX = 0; TempX <= Ymid - Ypos; TempX++) + { + _api.GUILib.DrawPixel(Xpos + yoff, Ymid - TempX, Color.FromArgb(127, 0, 255)); + _api.GUILib.DrawPixel(Xpos2 - yoff, Ymid - TempX, Color.FromArgb(127, 0, 255)); + if ((TempX & 1) != 0) yoff++; + } + yoff = Xmid - (Xpos + yoff); + _api.GUILib.DrawLine(Xmid - yoff, Ypos, Xmid + yoff, Ypos, Color.FromArgb(127, 0, 255)); + break; + default: + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(255, 127, 0, 255)); + break; + } + // if (!displayed) + if (type != 0x10) + { + uint temp = _api.MemLib.ReadU8(curObj + 0x7E); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(1, Xmid-2), 629), Math.Min(Math.Max(1, Ymid-4), 425), Color.Blue); + } + curObj = _api.MemLib.ReadU24(curObj+1); + } + //walls + bool displayed; + curObj = _api.MemLib.ReadU24(0xFFCFC1); + while (curObj != 0) + { + + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2= _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2= _api.MemLib.ReadS16(curObj + 0x38); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + displayed = false; + uint type = _api.MemLib.ReadU8(curObj + 0x7E); + int yoff = 0; + switch (type) + { + case 0x11: + Xpos2 = Xmid; + Xmid = (Xpos + Xpos2) >> 1; + break; + case 0x12: + Xpos = Xmid; + Xmid = (Xpos + Xpos2) >> 1; + break; + case 0x13: + Ypos = Ymid; + Ymid = (Ypos + Ypos2) >> 1; + break; + case 0x14: + Ypos2 = Ymid; + Ymid = (Ypos + Ypos2) >> 1; + break; + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + _api.GUILib.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.White); + _api.GUILib.DrawLine(Xmid, Ypos2, Xmid, Ymid, Color.FromArgb(127,Color.White)); + _api.GUILib.DrawLine(Xmid, Ymid, Xpos2, Ymid, Color.FromArgb(127, Color.White)); + displayed = true; + break; + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.White); + _api.GUILib.DrawLine(Xmid, Ymid, Xmid, Ypos2, Color.FromArgb(127, Color.White)); + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ymid, Color.FromArgb(127, Color.White)); + displayed = true; + break; + case 0x1F: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.White); + _api.GUILib.DrawLine(Xmid, Ymid, Xmid, Ypos, Color.FromArgb(127, Color.White)); + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ymid, Color.FromArgb(127, Color.White)); + displayed = true; + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + _api.GUILib.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.White); + _api.GUILib.DrawLine(Xmid, Ypos, Xmid, Ymid, Color.FromArgb(127, Color.White)); + _api.GUILib.DrawLine(Xmid, Ymid, Xpos2, Ymid, Color.FromArgb(127, Color.White)); + displayed = true; + break; + case 0x2B: + _api.GUILib.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.FromArgb(127, Color.White)); + for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) + { + _api.GUILib.DrawPixel(Xpos + yoff, Ymid - TempX, Color.White); + _api.GUILib.DrawPixel(Xpos2 - yoff, Ymid - TempX, Color.White); + if ((TempX & 1) != 0) yoff++; + } + yoff = Xmid - (Xpos + yoff); + _api.GUILib.DrawLine(Xmid - yoff, Ypos, Xmid + yoff, Ypos); + displayed = true; + break; + default: + if (type != 0x10) + { + var temp = _api.MemLib.ReadU8(curObj + 0x7E); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); + Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(1, Xmid-2), 629), Math.Min(Math.Max(1, Ymid-4), 425), Color.Lime); + } + break; + } + if (!displayed) _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.White); + curObj = _api.MemLib.ReadU24(curObj+1); + } + //inanimate objects + curObj = _api.MemLib.ReadU24(0xFFCFBD); + while (curObj != 0) + { + if (_api.MemLib.ReadU8(curObj + 0x7E) > 0xF); + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2= _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2= _api.MemLib.ReadS16(curObj + 0x38); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + } + Xpos += Xpos2; + Ypos += Ypos2; + Xpos >>= 1; + Ypos >>= 1; + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xpos-16), 605), Math.Min(Math.Max(0, Ypos-5), 424), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xpos-14), 607), Math.Min(Math.Max(2, Ypos-3), 426), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xpos-16), 605), Math.Min(Math.Max(2, Ypos-3), 426), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xpos-14), 607), Math.Min(Math.Max(0, Ypos-5), 424), Color.Lime); + Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(1, Xpos-15), 606), Math.Min(Math.Max(1, Ypos-4), 425), Color.Blue); + curObj = _api.MemLib.ReadU24(curObj+1); + } + //animate objects + if (_mode == Modes.Ecco2) + curObj = _api.MemLib.ReadU24(0xFFCFB9); + else + curObj = _api.MemLib.ReadU24(0xFFD829); + while (curObj != 0) + { + uint type = 0; + switch (_mode) { + case Modes.Ecco2: + { + uint flags = _api.MemLib.ReadU16(curObj + 0x10); + //if ((flags & 0x2000) || !(flags & 2)); + type = _api.MemLib.ReadU32(curObj + 0xC); + if ((type == 0xBA52E) || (type == 0xBA66E)) + { + uint Adelikat = curObj; + while (Adelikat != 0) + { + Xpos = _api.MemLib.ReadS16(Adelikat + 0x24); + Ypos = _api.MemLib.ReadS16(Adelikat + 0x28); + Xpos -= _camX; + Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(Adelikat + 0x44), Color.Lime); + Adelikat = _api.MemLib.ReadU32(Adelikat + 4); + } + Xpos = _api.MemLib.ReadS16(curObj + 0x24); + Ypos = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; + Ypos -= _camY; + } + else if (type == 0xE47EE) + { + uint Adelikat = curObj; + while (Adelikat != 0) + { + Xpos = _api.MemLib.ReadS16(Adelikat + 0x1C); + Ypos = _api.MemLib.ReadS16(Adelikat + 0x20); + Xpos -= _camX; + Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, (_api.MemLib.ReadS16(Adelikat + 0x2C) >> 1) + 16, Color.Lime); + Adelikat = _api.MemLib.ReadU32(Adelikat + 4); + } + Xpos = _api.MemLib.ReadS16(curObj + 0x24); + Ypos = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; + Ypos -= _camY; + } + else if ((type == 0x9F5B0) || (type == 0xA3B18)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x24); + Ypos = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; + Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(curObj + 0x44), Color.Lime); + } + else if (type == 0xDCEE0) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x24); + Ypos = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, 0x5C, Color.Lime); + } + else + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS16(curObj + 0x24); + Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + if ((type == 0xA6C4A) || (type == 0xC43D4)) DrawEccoOct(Xmid, Ymid, 70, Color.Lime); + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + } + break; + } + case Modes.Ecco1: + type = _api.MemLib.ReadU32(curObj + 0x6); + Xpos = _api.MemLib.ReadS16(curObj + 0x17); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x1F); + Ypos = _api.MemLib.ReadS16(curObj + 0x1B); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x23); + Xmid = _api.MemLib.ReadS16(curObj + 0x0F); + Ymid = _api.MemLib.ReadS16(curObj + 0x13); + Xpos >>= 2; + Xpos2 >>= 2; + Ypos >>= 2; + Ypos2 >>= 2; + Xmid >>= 2; + Ymid >>= 2; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + break; + } + Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(0, Ymid-5), 424), Color.Blue); + Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(2, Ymid-3), 426), Color.Blue); + Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(2, Ymid-3), 426), Color.Blue); + Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(0, Ymid-5), 424), Color.Blue); + Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(1, Xmid-15), 606), Math.Min(Math.Max(1, Ymid-4), 425), Color.Red); + curObj = _api.MemLib.ReadU24(curObj+1); + } + //events + curObj = _api.MemLib.ReadU24(0xFFCFB5); + while (curObj != 0) + { + uint type = _api.MemLib.ReadU32(curObj + 0xC); + if ((type == 0xA44EE) || (type == 0xD120C)) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + DrawEccoOct(Xmid, Ymid, 0x20, Color.Cyan); + } + else if (type == 0xDEF94) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawEccoOct(Xmid, Ymid, 0x18, Color.Cyan); + } + else + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2= _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2= _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS16(curObj + 0x24); + Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); + } + PutText(type.ToString("X8"), Xmid, Ymid, 1, 1, 0, 0, Color.White, Color.Blue); + PutText(curObj.ToString("X8"), Xmid, Ymid, 1, 9, 0, 0, Color.White, Color.Blue); + curObj = _api.MemLib.ReadU24(curObj+1); + } + //Ecco body + Xpos = _api.MemLib.ReadS16(0xFFAA22); + Ypos = _api.MemLib.ReadS16(0xFFAA26); + Xpos2 = _api.MemLib.ReadS16(0xFFAA2A); + Ypos2 = _api.MemLib.ReadS16(0xFFAA2E); + Xmid = _api.MemLib.ReadS16(0xFFAA1A); + Ymid = _api.MemLib.ReadS16(0xFFAA1E); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + X = Xpos; + X2 = Xpos2; + Y = Ypos; + Y2 = Ypos2; + int X3 = (Xmid + (ushort) Xpos) >> 1; + int X4 = (Xmid + (ushort) Xpos2) >> 1; + int Y3 = (Ymid + (ushort) Ypos) >> 1; + int Y4 = (Ymid + (ushort) Ypos2) >> 1; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Magenta); + DrawBoxMWH(X, Y, 1, 1, Color.Magenta); + DrawBoxMWH(X2, Y2, 1, 1, Color.Magenta); + DrawBoxMWH(X3, Y3, 1, 1, Color.Magenta); + DrawBoxMWH(X4, Y4, 1, 1, Color.Magenta); + _api.GUILib.DrawPixel(Xmid, Ymid, Color.Blue); + _api.GUILib.DrawPixel(X, Y, Color.Blue); + _api.GUILib.DrawPixel(X2, Y2, Color.Blue); + _api.GUILib.DrawPixel(X3, Y3, Color.Blue); + _api.GUILib.DrawPixel(X4, Y4, Color.Blue); + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + //Ecco head + Xpos = _api.MemLib.ReadS16(0xFFA8F8); + Xpos2 = _api.MemLib.ReadS16(0xFFA900); + Ypos = _api.MemLib.ReadS16(0xFFA8FC); + Ypos2 = _api.MemLib.ReadS16(0xFFA904); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.White); + //Ecco tail + Xpos = _api.MemLib.ReadS16(0xFFA978); + Xpos2 = _api.MemLib.ReadS16(0xFFA980); + Ypos = _api.MemLib.ReadS16(0xFFA97C); + Ypos2 = _api.MemLib.ReadS16(0xFFA984); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.White); + // sonar + if (_api.MemLib.ReadU8(0xFFAB77) != 0) + { + Xmid = _api.MemLib.ReadS16(0xFFA9EC); + Width2 = _api.MemLib.ReadS16(0xFFA9FC); + Xmid -= _camX; + Ymid = _api.MemLib.ReadS16(0xFFA9F0); + Ymid -= _camY; + Height2 = _api.MemLib.ReadS16(0xFFAA00); + color = ((_api.MemLib.ReadU8(0xFFAA0C) != 0) ? Color.FromArgb(255, 0, 127) : Color.FromArgb(0, 0, 255)); + DrawBoxMWH(Xmid, Ymid, Width2, Height2, color); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue); + _api.GUILib.DrawPixel(Xmid, Ymid, color); + } + //Pulsar + curObj = _api.MemLib.ReadU24(0xFFCFD1); + if (curObj != 0) + { + // sbyte Blah = _api.MemLib.ReadU8(CardBoard + 0x15); + curObj += 0x26; + // if (!(Blah & 1)) + // CardBoard += 0x14; + for (int l = 0; l < 4; l++) + { + if (_api.MemLib.ReadU16(curObj + 0x12) != 0) + { + Xmid = _api.MemLib.ReadS16(curObj); + Ymid = _api.MemLib.ReadS16(curObj + 4); + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 0x30, 0x30, Color.Red); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue); + _api.GUILib.DrawPixel(Xmid, Ymid, Color.Red); + } + curObj += 0x14; + } + } + } + + void EccoAutofire(bool on) + { + //Modif N - ECCO HACK - make caps lock (weirdly) autofire player 1's C key + uint charge; + uint mode = _api.MemLib.ReadU8(0xFFA555); + int frameCount = _api.EmuLib.FrameCount(); + int lagCount = _api.EmuLib.LagCount(); + switch (mode) + { + case 0x00: + if (on) + { + if (_api.MemLib.ReadU16(0xFFF342) == 0xFFFD) + _api.JoypadLib.Set("C", false, 1); + else + _api.JoypadLib.Set("C", true, 1); + } + break; + case 0xE6: + if (_api.MemLib.ReadU16(0xFFD5E8) == 0x00000002) { + Dictionary buttons = new Dictionary(); + buttons["B"] = !(buttons["C"] = false); + _api.JoypadLib.Set(buttons, 1); + } + else + { + Dictionary buttons = new Dictionary(); + buttons["B"] = !(buttons["C"] = true); + _api.JoypadLib.Set(buttons, 1); + } + break; + case 0xF6: + charge = _api.MemLib.ReadU8(0xFFB19B); + if (on) + { + if ((charge == 1) || (_prevCharge == 1) || !(_prevOn || (_api.MemLib.ReadU8(0xFFB19B) != 0))) + _api.JoypadLib.Set("B", true, 1); + else + _api.JoypadLib.Set("B", false, 1); + if ((_api.MemLib.ReadU16(0xFFB168) == 0x3800) && ((_api.MemLib.ReadU16(0xFFA7C8) % 2) != 0)) + _api.EmuLib.SetIsLagged(true); + _api.JoypadLib.Set("C", (_api.MemLib.ReadU16(0xFFA7C8) % 2) != 0, 1); + } + _prevCharge = charge; + break; + case 0x20: + case 0x28: + case 0xAC: + if (on) + { + _api.JoypadLib.Set("C", (_api.MemLib.ReadS8(0xFFAA6E) >= 11), 1); + } + break; + default: + break; + } + _prevOn = on; + } + public override void Init(IPluginAPI api) + { + base.Init(api); + _api.MemLib.SetBigEndian(); + string gameName = _api.GameInfoLib.GetRomName(); + if ((gameName == "ECCO - The Tides of Time (J) [!]") || + (gameName == "ECCO - The Tides of Time (U) [!]") || + (gameName == "ECCO - The Tides of Time (E) [!]")) + { + _mode = Modes.Ecco2; + _camXAddr = 0xFFAD9C; + _camYAddr = 0xFFAD9E; + EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); + } + else if ((gameName == "ECCO The Dolphin (J) [!]") || + (gameName == "ECCO The Dolphin (UE) [!]")) + + { + _mode = Modes.Ecco1; + _camXAddr = 0xFFB836; + _camYAddr = 0xFFB834; + EmuHawkPluginLibrary.SetGameExtraPadding(160,112,160,112); + } + else + { + _mode = Modes.disabled; + Running = false; + } + } + public override void PreFrameCallback() + { + if (_mode != Modes.disabled) + { + EccoAutofire(_api.JoypadLib.Get(1)["C"] != _api.JoypadLib.GetImmediate()["P1 C"]); + } + } + public override void PostFrameCallback() + { + uint frame = _api.MemLib.ReadU32(0xFFA524); + uint mode = _api.MemLib.ReadByte(0xFFA555); + switch (mode) { + case 0x20: + case 0x28: + case 0xAC: + EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); + EccoDrawBoxes(); + break; + case 0xF6: + EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); + EccoDraw3D(); + break; + default: + EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); + break; + } + _camX = _api.MemLib.ReadS16(_camXAddr)-160; + _camY = _api.MemLib.ReadS16(_camYAddr)-112; + if (frame <= _prevF) + _api.EmuLib.SetIsLagged(true); + _prevF = frame; + } + public override void LoadStateCallback(string name) + { + _prevF = _api.MemLib.ReadU32(0xFFA524); + } + } +} From 9874c496aca1875a67b905c0cc7e960d6accf377 Mon Sep 17 00:00:00 2001 From: upthorn Date: Wed, 5 Dec 2018 11:58:19 -0800 Subject: [PATCH 06/22] Minor revisions to plugin API --- .../plugins/PluginLibrary.Emu.cs | 85 ++++++++++++++++++- .../plugins/PluginLibrary.GUIDraw.cs | 31 ++++++- .../plugins/PluginLibrary.Joypad.cs | 10 ++- .../Plugins/Libraries/PluginLibrary.cs | 30 +++---- 4 files changed, 129 insertions(+), 27 deletions(-) diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs index b205516989..b0ccf94061 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs @@ -226,7 +226,90 @@ namespace BizHawk.Client.Common { Global.Config.AutoMinimizeSkipping = enabled; } - + public object GetSettings() + { + if (Emulator is GPGX) + { + var gpgx = Emulator as GPGX; + return gpgx.GetSettings(); + } + else if (Emulator is LibsnesCore) + { + var snes = Emulator as LibsnesCore; + return snes.GetSettings(); + } + else if (Emulator is NES) + { + var nes = Emulator as NES; + return nes.GetSettings(); + } + else if (Emulator is QuickNES) + { + var quicknes = Emulator as QuickNES; + return quicknes.GetSettings(); + } + else if (Emulator is PCEngine) + { + var pce = Emulator as PCEngine; + return pce.GetSettings(); + } + else if (Emulator is SMS) + { + var sms = Emulator as SMS; + return sms.GetSettings(); + } + else if (Emulator is WonderSwan) + { + var ws = Emulator as WonderSwan; + return ws.GetSettings(); + } + else + { + return null; + } + } + public bool PutSettings(object settings) + { + if (Emulator is GPGX) + { + var gpgx = Emulator as GPGX; + return gpgx.PutSettings(settings as GPGX.GPGXSettings); + } + else if (Emulator is LibsnesCore) + { + var snes = Emulator as LibsnesCore; + return snes.PutSettings(settings as LibsnesCore.SnesSettings); + } + else if (Emulator is NES) + { + var nes = Emulator as NES; + return nes.PutSettings(settings as NES.NESSettings); + } + else if (Emulator is QuickNES) + { + var quicknes = Emulator as QuickNES; + return quicknes.PutSettings(settings as QuickNES.QuickNESSettings); + } + else if (Emulator is PCEngine) + { + var pce = Emulator as PCEngine; + return pce.PutSettings(settings as PCEngine.PCESettings); + } + else if (Emulator is SMS) + { + var sms = Emulator as SMS; + return sms.PutSettings(settings as SMS.SMSSettings); + } + else if (Emulator is WonderSwan) + { + var ws = Emulator as WonderSwan; + return ws.PutSettings(settings as WonderSwan.Settings); + } + else + { + return false; + } + } public void SetRenderPlanes(params bool[] luaParam) { if (Emulator is GPGX) diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs b/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs index e6612ad7f7..2647c19a89 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.Drawing.Imaging; using System.Windows.Forms; using System.IO; @@ -23,6 +24,22 @@ namespace BizHawk.Client.Common protected Color? _defaultTextBackground = Color.FromArgb(128, 0, 0, 0); protected int _defaultPixelFont = 1; // gens protected Padding _padding = new Padding(0); + protected ImageAttributes _attributes = new ImageAttributes(); + private System.Drawing.Drawing2D.CompositingMode _compositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver; + + public virtual void ToggleCompositingMode() + { + _compositingMode = 1 - _compositingMode; + } + + public virtual ImageAttributes GetAttributes() + { + return _attributes; + } + public virtual void SetAttributes(ImageAttributes a) + { + _attributes = a; + } #region Gui API public virtual void Dispose() @@ -135,6 +152,7 @@ namespace BizHawk.Client.Common { try { + g.CompositingMode = _compositingMode; g.DrawBezier(GetPen(color ?? _defaultForeground), p1, p2, p3, p4); } catch (Exception) @@ -150,6 +168,7 @@ namespace BizHawk.Client.Common { try { + g.CompositingMode = _compositingMode; g.DrawBeziers(GetPen(color ?? _defaultForeground), points); } catch (Exception) @@ -188,6 +207,7 @@ namespace BizHawk.Client.Common h = Math.Max(y2, 0.1f); } + g.CompositingMode = _compositingMode; g.DrawRectangle(GetPen(line ?? _defaultForeground), x, y, w, h); var bg = background ?? _defaultBackground; @@ -217,6 +237,7 @@ namespace BizHawk.Client.Common g.FillEllipse(brush, x, y, width, height); } + g.CompositingMode = _compositingMode; g.DrawEllipse(GetPen(line ?? _defaultForeground), x, y, width, height); } catch (Exception) @@ -249,6 +270,7 @@ namespace BizHawk.Client.Common icon = new Icon(path); } + g.CompositingMode = _compositingMode; g.DrawIcon(icon, x, y); } catch (Exception) @@ -281,8 +303,10 @@ namespace BizHawk.Client.Common _imageCache.Add(path, img); } } + var destRect = new Rectangle(x, y, width ?? img.Width, height ?? img.Height); - g.DrawImage(img, x, y, width ?? img.Width, height ?? img.Height); + g.CompositingMode = _compositingMode; + g.DrawImage(img, destRect, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, _attributes); } } @@ -319,7 +343,8 @@ namespace BizHawk.Client.Common var destRect = new Rectangle(dest_x, dest_y, dest_width ?? source_width, dest_height ?? source_height); - g.DrawImage(img, destRect, source_x, source_y, source_width, source_height, GraphicsUnit.Pixel); + g.CompositingMode = _compositingMode; + g.DrawImage(img, destRect, source_x, source_y, source_width, source_height, GraphicsUnit.Pixel, _attributes); } } @@ -327,6 +352,7 @@ namespace BizHawk.Client.Common { using (var g = GetGraphics()) { + g.CompositingMode = _compositingMode; g.DrawLine(GetPen(color ?? _defaultForeground), x1, y1, x2, y2); } } @@ -341,6 +367,7 @@ namespace BizHawk.Client.Common { using (var g = GetGraphics()) { + g.CompositingMode = _compositingMode; var bg = background ?? _defaultBackground; if (bg.HasValue) { diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs index f09a1e5cb1..5eeb3ff1e6 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs +++ b/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs @@ -145,7 +145,7 @@ namespace BizHawk.Client.Common /*Eat it*/ } } - public void Set(string button, bool state, int? controller = null) + public void Set(string button, bool? state = null, int? controller = null) { try { @@ -154,8 +154,10 @@ namespace BizHawk.Client.Common { toPress = "P" + controller + " " + button; } - - Global.LuaAndAdaptor.SetButton(toPress, state); + if (state.HasValue) + Global.LuaAndAdaptor.SetButton(toPress, state.Value); + else + Global.LuaAndAdaptor.UnSet(toPress); Global.ActiveController.Overrides(Global.LuaAndAdaptor); } catch @@ -196,7 +198,7 @@ namespace BizHawk.Client.Common /*Eat it*/ } } - public void SetAnalog(string control, float value, object controller = null) + public void SetAnalog(string control, float? value = null, object controller = null) { try { diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs index 1396c77334..258cd128e3 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs @@ -14,7 +14,7 @@ namespace BizHawk.Client.EmuHawk public class PluginLibrary { // public LuaDocumentation Docs { get; } - public PluginLibrary(IEmulatorServiceProvider serviceProvider) + private void Register(IEmulatorServiceProvider serviceProvider) { // Docs.Clear(); @@ -37,23 +37,15 @@ namespace BizHawk.Client.EmuHawk foreach (var lib in libs) { - bool addLibrary = true; - //var attributes = lib.GetCustomAttributes(typeof(LuaLibraryAttribute), false); - //if (attributes.Any()) - //{ - // addLibrary = VersionInfo.DeveloperBuild || (attributes.First() as LuaLibraryAttribute).Released; - //} - - if (addLibrary) - { - var instance = (PluginLibraryBase)Activator.CreateInstance(lib); - //instance.LuaRegister(lib, Docs); - //instance.LogOutputCallback = ConsoleLuaLibrary.LogOutput; - ServiceInjector.UpdateServices(serviceProvider, instance); - Libraries.Add(lib, instance); - } + var instance = (PluginLibraryBase)Activator.CreateInstance(lib); + ServiceInjector.UpdateServices(serviceProvider, instance); + Libraries.Add(lib, instance); } } + public PluginLibrary(IEmulatorServiceProvider serviceProvider) + { + Register(serviceProvider); + } private readonly Dictionary Libraries = new Dictionary(); public List PluginList { get; } = new List(); @@ -68,10 +60,8 @@ namespace BizHawk.Client.EmuHawk public void Restart(IEmulatorServiceProvider newServiceProvider) { - foreach (var lib in Libraries) - { - ServiceInjector.UpdateServices(newServiceProvider, lib.Value); - } + Libraries.Clear(); + Register(newServiceProvider); foreach (var plugin in PluginList) { plugin.Init(new PluginAPI(Libraries)); From a13b9b3a317396568970c6a28b6563e6d68d99c5 Mon Sep 17 00:00:00 2001 From: upthorn Date: Wed, 5 Dec 2018 11:59:13 -0800 Subject: [PATCH 07/22] Significant updates to example Ecco 2 plugin. --- .../Plugins/Example/Ecco2AssistantPlugin.cs | 3454 +++++++++++++++-- 1 file changed, 3048 insertions(+), 406 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs b/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs index 753bc5d425..75a58dcd79 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs +++ b/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Drawing; +using System.Linq; using BizHawk.Client.Common; +using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; namespace BizHawk.Client.EmuHawk { @@ -19,102 +22,490 @@ namespace BizHawk.Client.EmuHawk private int _camY = 0; private int _camXAddr; private int _camYAddr; - private bool _prevOn = false; - private uint _prevCharge = 0; private uint _prevF = 0; - - void DrawEccoOct(int x, int y, int r, Color? color = null, int fillAlpha = 0) + private int _top = 0; + private int _bottom = 0; + private int _left = 0; + private int _right = 0; + private const int _signalAlpha = 255; + private int _tickerY = 81; + private int _dumpMap = 0; + private int _prevX = 0; + private int _prevY = 0; + private int _destX = 0; + private int _destY = 0; + private int _snapPast = 0; + private string _rowStateGuid = string.Empty; + private EmuHawkPluginLibrary _clientLib; + private Color[] _turnSignalColors = { - Point[] octPoints = { - new Point(x, y - r), - new Point((int)(x + Math.Sin(Math.PI / 4) * r), (int)(y - Math.Sin(Math.PI / 4) *r)), - new Point(x + r, y), - new Point((int)(x + Math.Sin(Math.PI / 4) * r), (int)(y + Math.Sin(Math.PI / 4) *r)), - new Point(x, y + r), - new Point((int)(x - Math.Sin(Math.PI / 4) * r), (int)(y + Math.Sin(Math.PI / 4) *r)), - new Point(x - r, y), - new Point((int)(x - Math.Sin(Math.PI / 4) * r), (int)(y - Math.Sin(Math.PI / 4) *r)) - }; - Color fillColor = color.HasValue ? Color.FromArgb(fillAlpha, color.Value) : Color.Empty; - _api.GUILib.DrawPolygon(octPoints, color, fillColor); + Color.FromArgb(_signalAlpha, 127, 127, 0), + Color.FromArgb(_signalAlpha, 255, 0, 0), + Color.FromArgb(_signalAlpha, 192, 0, 63), + Color.FromArgb(_signalAlpha, 63, 0, 192), + Color.FromArgb(_signalAlpha, 0, 0, 255), + Color.FromArgb(_signalAlpha, 0, 63, 192), + Color.FromArgb(_signalAlpha, 0, 192, 63), + Color.FromArgb(_signalAlpha, 0, 255, 0) + }; + private int _rseed = 1; + private int EccoRand(bool refresh = false) + { + if (refresh) + { + _rseed = (int)(_api.MemLib.ReadU16(0xFFE2F8)); + } + bool odd = (_rseed & 1) != 0; + _rseed >>= 1; + if (odd) + { + _rseed ^= 0xB400; + } + return _rseed; } - void DrawBoxMWH(int x, int y, int w, int h, Color? color = null, int fillAlpha = 0) + private void DrawEccoRhomb(int x, int y, int radius, Color color, int fillAlpha = 63) { - Color fillColor = color.HasValue ? Color.FromArgb(fillAlpha, color.Value) : Color.Empty; + Point[] rhombus = { + new Point(x, y - radius), + new Point(x + radius, y), + new Point(x, y + radius), + new Point(x - radius, y) + }; + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawPolygon(rhombus, color, fillColor); + } + private void DrawEccoRhomb_scaled(int x, int y, int width, int height, int rscale, int bscale, int lscale, int tscale, Color color, int fillAlpha = 63) + { + Point[] rhombus = { + new Point(x + (width << rscale), y), + new Point(x, y + (height << bscale)), + new Point(x - (width << lscale), y), + new Point(x, y - (height << tscale)) + }; + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawPolygon(rhombus, color, fillColor); + } + private void DrawEccoOct(int x, int y, int r, Color color, int fillAlpha = 63) + { + var octOff = (int)(Math.Sqrt(2) * r) >> 1; + Point[] octagon = { + new Point(x, y - r), + new Point(x + octOff, y - octOff), + new Point(x + r, y), + new Point(x + octOff, y + octOff), + new Point(x, y + r), + new Point(x - octOff, y + octOff), + new Point(x - r, y), + new Point(x - octOff, y - octOff) + }; + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawPolygon(octagon, color, fillColor); + } + private void DrawEccoOct_scaled(int x, int y, int xscale, int yscale, int r, Color color, int fillAlpha = 63) + { + var octOff = (int)(Math.Sin(Math.PI / 4) * r); + var xoctOff = octOff << xscale; + var yoctOff = octOff << yscale; + var xr = r << xscale; + var yr = r << yscale; + Point[] octagon = { + new Point(x, y - yr), + new Point(x + xoctOff, y - yoctOff), + new Point(x + xr, y), + new Point(x + xoctOff, y + yoctOff), + new Point(x, y + yr), + new Point(x - xoctOff, y + yoctOff), + new Point(x - xr, y), + new Point(x - xoctOff, y - yoctOff) + }; + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawPolygon(octagon, color, fillColor); + } + private Point? Intersection(Point start1, Point end1, Point start2, Point end2) + { + if ((Math.Max(start1.X, end1.X) < Math.Min(start2.X, end2.X)) + || (Math.Min(start1.X, end1.X) > Math.Max(start2.X, end2.X)) + || (Math.Max(start1.Y, end1.Y) < Math.Min(start2.Y, end2.Y)) + || (Math.Min(start1.Y, end1.Y) > Math.Max(start2.Y, end2.Y))) + return null; + + + double ay_cy, ax_cx, px, py; + double dx_cx = end2.X - start2.X, + dy_cy = end2.Y - start2.Y, + bx_ax = end1.X - start1.X, + by_ay = end1.Y - start1.Y; + + double de = (bx_ax) * (dy_cy) - (by_ay) * (dx_cx); + + if (Math.Abs(de) < 0.01) + return null; + + ax_cx = start1.X - start2.X; + ay_cy = start1.Y - start2.Y; + double r = ((ay_cy) * (dx_cx) - (ax_cx) * (dy_cy)) / de; + double s = ((ay_cy) * (bx_ax) - (ax_cx) * (by_ay)) / de; + px = start1.X + r * (bx_ax); + py = start1.Y + r * (by_ay); + if ((px < Math.Min(start1.X, end1.X)) || (px > Math.Max(start1.X, end1.X)) + || (px < Math.Min(start2.X, end2.X)) || (px > Math.Max(start2.X, end2.X)) + || (py < Math.Min(start1.Y, end1.Y)) || (py > Math.Max(start1.Y, end1.Y)) + || (py < Math.Min(start2.Y, end2.Y)) || (py > Math.Max(start2.Y, end2.Y))) + return null; + return new Point((int)px, (int)py); + } + private void DrawRectRhombusIntersection(Point rectMid, Point rhombMid, int rw, int rh, int r, Color color, int fillAlpha = 63) // Octagon provided by the intersection of a rectangle and a rhombus + { + Point[] rect = + { + new Point(rectMid.X - rw, rectMid.Y + rh), + new Point(rectMid.X - rw, rectMid.Y - rh), + new Point(rectMid.X + rw, rectMid.Y - rh), + new Point(rectMid.X + rw, rectMid.Y + rh) + }; + Point[] rhombus = + { + new Point(rhombMid.X - r, rhombMid.Y), + new Point(rhombMid.X, rhombMid.Y - r), + new Point(rhombMid.X + r, rhombMid.Y), + new Point(rhombMid.X, rhombMid.Y + r) + }; + List finalShape = new List(); + foreach (Point p in rect) + { + if (Math.Abs(p.X - rhombMid.X) + Math.Abs(p.Y - rhombMid.Y) <= r) + finalShape.Add(p); + } + foreach (Point p in rhombus) + { + if ((Math.Abs(p.X - rectMid.X) <= rw) && (Math.Abs(p.Y - rectMid.Y) <= rh)) + finalShape.Add(p); + } + for (int i = 0; i < 5; i++) + { + Point? p = Intersection(rhombus[i & 3], rhombus[(i + 1) & 3], rect[i & 3], rect[(i + 1) & 3]); + if (p.HasValue) finalShape.Add(p.Value); + p = Intersection(rhombus[i & 3], rhombus[(i + 1) & 3], rect[(i + 1) & 3], rect[(i + 2) & 3]); + if (p.HasValue) finalShape.Add(p.Value); + } + double mX = 0; + double my = 0; + foreach (Point p in finalShape) + { + mX += p.X; + my += p.Y; + } + mX /= finalShape.ToArray().Length; + my /= finalShape.ToArray().Length; + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawPolygon(finalShape.OrderBy(p => Math.Atan2(p.Y - my, p.X - mX)).ToArray(), color, fillColor); + } + private void DrawEccoTriangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color, int fillAlpha = 63) + { + Color? fillColor = null; + Point[] triPoints = + { + new Point(x1, y1), + new Point(x2, y2), + new Point(x3, y3) + }; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawPolygon(triPoints, color, fillColor); + } + private void DrawBoxMWH(int x, int y, int w, int h, Color color, int fillAlpha = 63) + { + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); _api.GUILib.DrawRectangle(x - w, y - h, w << 1, h << 1, color, fillColor); } - void Print_Text(string message, int size, int x, int y, Color color) + private void DrawBox(int x, int y, int x2, int y2, Color color, int fillAlpha = 63) + { + Color? fillColor = null; + if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); + _api.GUILib.DrawBox(x, y, x2, y2, color, fillColor); + } + private void Print_Text(string message, int x, int y, Color color) { _api.GUILib.DrawText(x, y, message, color, null); } - void PutText(string message, int x, int y, int xl, int yl, int xh, int yh, Color bg, Color fg) + private void PutText(string message, int x, int y, int xl, int yl, int xh, int yh, Color bg, Color fg) { xl = Math.Max(xl, 0); - yl = Math.Max(xl, 0); + yl = Math.Max(yl, 0); xh = Math.Min(xh + 639, 639); yh = Math.Min(yh + 441, 441); xh -= 4 * message.Length; x = x - ((5 * (message.Length - 1)) / 2); - x = Math.Min(Math.Max(x, Math.Max(xl, 1)), Math.Min(xh, 638 - 4 * (int)message.Length)); - y = Math.Min(Math.Max(y - 3, Math.Max(yl, 1)), yh); + y -= 3; +// x = Math.Min(Math.Max(x, Math.Max(xl, 1)), Math.Min(xh, 638 - 4 * (int)message.Length)); +// y = Math.Min(Math.Max(y - 3, Math.Max(yl, 1)), yh); int[] xOffset = { -1, -1, -1, 0, 1, 1, 1, 0 }; int[] yOffset = { -1, 0, 1, 1, 1, 0, -1, -1 }; for (int i = 0; i < 8; i++) - Print_Text(message, message.Length, x + xOffset[i], y + yOffset[i], bg); - Print_Text(message, message.Length, x, y, fg); + Print_Text(message, x + xOffset[i], y + yOffset[i], bg); + Print_Text(message, x, y, fg); } - - - void EccoDraw3D() + private void TickerText(string message, Color? fg = null) { - int ScreenX = (_api.MemLib.ReadS32(0xFFD5E0) >> 0xC); - int ScreenY = (_api.MemLib.ReadS32(0xFFD5E8) >> 0xC); - int ScreenZ = (_api.MemLib.ReadS32(0xFFD5E4) >> 0xB); + if (_dumpMap == 0) + _api.GUILib.Text(1, _tickerY, message, fg); + _tickerY += 16; + } + private void EccoDraw3D() + { + int CamX = (_api.MemLib.ReadS32(0xFFD5E0) >> 0xC) - _left; + int CamY = (_api.MemLib.ReadS32(0xFFD5E8) >> 0xC) + _top; + int CamZ = (_api.MemLib.ReadS32(0xFFD5E4) >> 0xC) + _top; uint curObj = _api.MemLib.ReadU24(0xFFD4C1); while (curObj != 0) { int Xpos = (_api.MemLib.ReadS32(curObj + 0x6) >> 0xC); int Ypos = (_api.MemLib.ReadS32(curObj + 0xE) >> 0xC); - int Zpos = (_api.MemLib.ReadS32(curObj + 0xA) >> 0xB); - int Y = 224 - (Zpos - ScreenZ); - int X = (Xpos - ScreenX) + 0xA0; + int Zpos = (_api.MemLib.ReadS32(curObj + 0xA) >> 0xC); + int Xmid = 160 + (Xpos - CamX); + int Ymid = 112 - (Ypos - CamY); + int Zmid = _top + 112 - (Zpos - CamZ); uint type = _api.MemLib.ReadU32(curObj + 0x5A); - short height, width; - int display = 0; - if ((type == 0xD817E) || (type == 0xD4AB8)) + int width, height, depth = height = width = 0; + if (type == 0xD4AB8) // 3D poison Bubble { - Y = 113 - (Ypos - ScreenY); - height = 0x10; - if (_api.MemLib.ReadU32(0xFFB166) < 0x1800) height = 0x8; - short radius = 31; - if (type == 0xD4AB8) - { - radius = 7; - height = 0x20; - } + depth = 0x10; + int radius = 8; width = radius; - DrawEccoOct(X, Y, radius, Color.Lime, 0); - display = 1; + DrawEccoOct(Xmid, Ymid, radius, Color.Lime); + DrawBoxMWH(Xmid, Zmid, width, depth, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); + } + else if (type == 0xD817E)// 3D Ring + { + depth = 8; + if (_api.MemLib.ReadU32(0xFFB166) < 0x1800) depth = 4; + int radius = 32; + width = radius; + DrawEccoOct(Xmid, Ymid, radius, (_api.MemLib.ReadS16(curObj + 0x62) == 0) ? Color.Orange : Color.Gray); + DrawBoxMWH(Xmid, Zmid, width, depth, Color.Red); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Red, 0); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x6) / 4096.0:0.######}:{_api.MemLib.ReadS32(curObj + 0xE) / 4096.0:0.######}:{_api.MemLib.ReadS32(curObj + 0xA) / 2048.0:0.######}:{_api.MemLib.ReadByte(curObj + 0x72)}",Color.Lime); + } + else if (type == 0xD49CC) // Vines collisions are based on draw position, which is a fucking pain in the ass to calculate + { + int Xvel = (_api.MemLib.ReadS32(curObj + 0x3A) - _api.MemLib.ReadS32(curObj + 0x6)); + int Zvel = (_api.MemLib.ReadS32(curObj + 0x3E) - _api.MemLib.ReadS32(curObj + 0xA)); + int dx = _api.MemLib.ReadS32(0xFFD5E0) - _api.MemLib.ReadS32(0xFFD5C8) >> 3; + int dy = _api.MemLib.ReadS32(0xFFD5E8) - _api.MemLib.ReadS32(0xFFD600) >> 3; + int dz = _api.MemLib.ReadS32(0xFFD5E4) - _api.MemLib.ReadS32(0xFFD5CC); + var chargeCount = _api.MemLib.ReadByte(0xFFB19B); + if (chargeCount == 0) + { + dz >>= 2; + } + else if ((chargeCount > 0x20) || (chargeCount <= 0x10)) + { + dz >>= 3; + } + else if (chargeCount > 0x10) + { + dz >>= 4; + } + if (_api.MemLib.ReadByte(curObj + 0x64) == 0) + { + Xvel >>= 0xA; + Zvel >>= 9; + } + else + { + Xvel >>= 9; + Zvel >>= 0xA; + } + Xvel += _api.MemLib.ReadS32(curObj + 0x2E); + Zvel += _api.MemLib.ReadS32(curObj + 0x32); + Zpos = (_api.MemLib.ReadS32(curObj + 0x26) + dz - _api.MemLib.ReadS32(0xFFD5E4)) >> 0xB; + if ((Zpos < 0x600) && (Zpos > 0)) + { + Zpos += 0x20; + int Xcur, Xmax, Ycur, Ymax; + int Zpos2 = (_api.MemLib.ReadS32(curObj + 0xA) + Zvel + dz - _api.MemLib.ReadS32(0xFFD5E4)) >> 0xB; + Zpos2 = Math.Max(Zpos2 + 0x20, 1); + if (_api.MemLib.ReadS16(curObj + 0x62) != 0) + { + Xmid = _api.MemLib.ReadS32(curObj + 0x6) + dx + Xvel - _api.MemLib.ReadS32(0xFFD5E0); + if (Math.Abs(Xmid) > 0x400000) + continue; + Xpos = _api.MemLib.ReadS32(curObj + 0x22) + dx - _api.MemLib.ReadS32(0xFFD5E0); + if (Math.Abs(Xpos) > 0x400000) + continue; + Xcur = (Xmid << 2) / Zpos2 + (Xmid >> 5) + 0xA000 + (Xmid >> 5); + Xmax = (Xpos << 2) / Zpos + (Xpos >> 5) + 0xA000 + (Xpos >> 5); + } + else + { + Xcur = 0; + Xmax = 256; + } + Ymid = _api.MemLib.ReadS32(0xFFD5E8) + dy - _api.MemLib.ReadS32(curObj + 0xE); + Ycur = ((Ymid << 3) / Zpos2) + 0x6000; + Ypos = _api.MemLib.ReadS32(0xFFD5E8) + dy - _api.MemLib.ReadS32(curObj + 0x2A); + Ymax = ((Ypos << 3) / Zpos) + 0x6000; + dx = Xmax - Xcur; + dy = Ymax - Ycur; + int asindx = Math.Abs(dx >> 6) & 0xFFFF; + int asindy = Math.Abs(dy >> 6) & 0xFFFF; + int ang; + if (asindx == asindy) + { + if (dx > 0) + { + if (dy > 0) + { + ang = 0x20; + } + else + { + ang = 0xE0; + } + } + else + { + if (dy > 0) + { + ang = 0x60; + } + else + { + ang = 0xA0; + } + } + } + else + { + if (asindx > asindy) + { + asindy <<= 5; + asindy += asindx - 1; + asindy &= 0xFFFF; + asindy /= asindx; + } + else + { + asindx <<= 5; + asindx += asindy - 1; + asindx &= 0xFFFF; + asindx /= asindy; + asindy = 0x40 - asindx; + } + if (dx > 0) + { + if (dy > 0) + { + ang = asindy; + } + else + { + ang = 0xff - asindy; + } + } + else + { + if (dy > 0) + { + ang = 0x7f - asindy; + } + else + { + ang = 0x81 + asindy; + } + } + } + Xcur += _api.MemLib.ReadS8(0x2CC8 + ang) << 6; + Ycur += _api.MemLib.ReadS8(0x2BC8 + ang) << 6; + var dSml = Math.Abs(dx); + var dBig = Math.Abs(dy); + if (dBig < dSml) + { + dSml ^= dBig; + dBig ^= dSml; + dSml ^= dBig; + } + int OctRad = (dBig + (dSml >> 1) - (dSml >> 3)); + int i = Math.Max(((OctRad >> 8) + 0x1F) >> 5, 1); + dx /= i; + dy /= i; + + Zmid = (_api.MemLib.ReadS32(curObj + 0xA) + _api.MemLib.ReadS32(curObj + 0x26)) >> 1; + Zmid >>= 0xC; + Zmid = 112 + _top - (Zmid - CamZ); + do + { + i--; + DrawEccoRhomb((Xcur >> 8) + _left, (Ycur >> 8) + _top, 8, Color.Lime); + DrawBoxMWH((Xcur >> 8) + _left, Zmid, 8, 0x10, Color.Blue); + Xcur += dx; + Ycur += dy; + } while (i >= 0); + DrawBoxMWH((_api.MemLib.ReadS32(0xFFB1AA) >> 8) + _left, (_api.MemLib.ReadS32(0xFFB1AE) >> 8) + _top, 1, 1, Color.Lime, 0); + } + } + else if ((type == 0xD3B40) || (type == 0xD3DB2)) // 3D Shark and Jellyfish + { + width = (_api.MemLib.ReadS32(curObj + 0x12) >> 0xC); + height = (_api.MemLib.ReadS32(curObj + 0x1A) >> 0xC); + depth = (_api.MemLib.ReadS32(curObj + 0x16) >> 0xC); + DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); + DrawBoxMWH(Xmid, Zmid, width, depth, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); + } + else if ((type == 0xD4028) || (type == 0xD4DBA)) // 3D Eagle and 3D Shell + { + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); + } + else if (type == 0xD4432) // 3D Sonar Blast + { + DrawEccoOct(Xmid, Ymid, 48, Color.Orange); + DrawEccoOct(Xmid, Ymid, 32, Color.Lime); + DrawBoxMWH(Xmid, Zmid, 32, 32, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); + } + else if (type == 0xD463A) // 3D Homing Bubble + { + DrawEccoOct(Xmid, Ymid, 48, Color.Orange); + DrawEccoOct(Xmid, Ymid, 32, Color.Lime); + DrawBoxMWH(Xmid, Zmid, 32, 32, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); + } + else if ((type == 0xD37CE) || (type == 0xD4214) || (type == 0xD3808)) // bubbles, splashes, gfx sprites + { + width = height = depth = 0; } else { - width = height = 1; - if (curObj == 0xFFB134) display = 3; - } - if ((display & 1) != 0) - { - Y = 224 - (Zpos - ScreenZ); - DrawBoxMWH(X, Y, width, height, Color.Blue, 0); - } - if ((display & 2) != 0) - { - Y = 113 - (Ypos - ScreenY); - DrawBoxMWH(X, Y, width, height, Color.Lime, 0); + if (curObj != 0xFFB134) + { + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); + PutText(type.ToString("X8"), Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); + PutText(curObj.ToString("X8"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); + } + else + { + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange); + DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Red); + } } curObj = _api.MemLib.ReadU24(curObj+1); } } - void EccoDrawBoxes() + private void EccoDrawBoxes() { // CamX-=8; int Width2, Height2; @@ -131,59 +522,74 @@ namespace BizHawk.Client.EmuHawk i++; off += 448; } color = Color.FromArgb(j >> 2, j >> 2, j >> 2); - _api.GUILib.DrawLine(128, j - off, 144, j - off, color); + _api.GUILib.DrawLine(_left - 32, j - off, _left - 17, j - off, color); + } + for (int j = 0; j < HP; j += 8) + { + color = Color.FromArgb(Math.Max(0x38 - (j >> 3),0), 0, Math.Min(j >> 1,255)); + _api.GUILib.DrawRectangle(_left - 16, j, 15, 7, color, color); } - for (i = 0; i < 16; i++) - for (int j = 0; j < Math.Min(HP, 448); j++) - { - color = Color.FromArgb(0, 0, (j>>1 & 0xF0)); - _api.GUILib.DrawPixel(144 + i, j, color); - } //Asterite - uint curObj = _api.MemLib.ReadU24(0xFFCFC9); + uint type = _api.MemLib.ReadU32(0xFFD440); + uint curObj = 0; int Xpos, Xpos2, Ypos, Ypos2, Xmid, Ymid, X, X2, Y, Y2; - Xmid = 0; - Ymid = 0; - while (curObj != 0) + Xpos = Ypos = Xpos2 = Ypos2 = Xmid = Ymid = X = X2 = Y = Y2 = 0; + if (type == 0xB119A) { - if (_api.MemLib.ReadU32(curObj + 8) != 0) + curObj = _api.MemLib.ReadU24(_api.MemLib.ReadU24(0xFFD429)+5); + while (curObj != 0) { Xpos = _api.MemLib.ReadS16(curObj + 0x3C); - Xpos2= _api.MemLib.ReadS16(curObj + 0x24); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x24); Ypos = _api.MemLib.ReadS16(curObj + 0x40); - Ypos2= _api.MemLib.ReadS16(curObj + 0x28); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x28); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; if (_api.MemLib.ReadU8(curObj + 0x71) != 0) { - DrawEccoOct(Xpos, Ypos, 40, Color.FromArgb(255, 192, 0), 0x7F); - DrawEccoOct(Xpos2, Ypos2, 40, Color.FromArgb(255, 192, 0), 0x7F); + DrawEccoOct(Xpos, Ypos, 48, Color.Blue, 16); + DrawEccoOct(Xpos2, Ypos2, 48, Color.Blue, 16); + } + curObj = _api.MemLib.ReadU24(curObj + 5); + } + if ((_api.MemLib.ReadU8(0xFFA7D0) == 30)) + { + curObj = _api.MemLib.ReadU24(0xFFD425); + if ((curObj != 0) && (_api.MemLib.ReadU32(curObj + 8) != 0)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + DrawEccoOct(Xpos, Ypos, 20, Color.Orange); } } - else - { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - } - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(0, Ymid-5), 424), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(2, Ymid-3), 426), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(2, Ymid-3), 426), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(0, Ymid-5), 424), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(1, Xmid-15), 606), Math.Min(Math.Max(1, Ymid-4), 425), Color.Blue); - curObj = _api.MemLib.ReadU24(curObj+1); } - uint curlev = _api.MemLib.ReadU8(0xFFA7E0); - if ((_api.MemLib.ReadU8(0xFFA7D0) == 30)) + else if (type == 0xB2CB8) { - curObj = _api.MemLib.ReadU24(0xFFD425); - if ((curObj != 0) && (_api.MemLib.ReadU32(curObj + 8) != 0)) + curObj = _api.MemLib.ReadU24(_api.MemLib.ReadU24(0xFFD429) + 5); + while (curObj != 0) { - Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; - DrawEccoOct(Xpos, Ypos, 20, Color.FromArgb(255, 192, 0)); + Xpos = _api.MemLib.ReadS16(curObj + 0x3C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x24); + Ypos = _api.MemLib.ReadS16(curObj + 0x40); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + if (_api.MemLib.ReadU8(curObj + 0x71) != 0) + { + if (_api.MemLib.ReadByte(0xFFA7D0) != 0x1F) + { + DrawEccoOct(Xpos, Ypos, 40, Color.Lime); + DrawEccoOct(Xpos2, Ypos2, 40, Color.Lime); + } + DrawEccoOct(Xpos, Ypos, 48, Color.Blue, 16); + DrawEccoOct(Xpos2, Ypos2, 48, Color.Blue, 16); + } + curObj = _api.MemLib.ReadU24(curObj + 5); } } //aqua tubes @@ -199,254 +605,408 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; // displayed = false; - uint type = _api.MemLib.ReadU8(curObj + 0x7E); - int yoff = 0; + type = _api.MemLib.ReadU8(curObj + 0x7E); switch (type) { - /* case 0x11: - Xpos2 = Xmid; - Xmid = (Xpos + Xpos2) >> 1; - break; - case 0x12: - Xpos = Xmid; - Xmid = (Xpos + Xpos2) >> 1; - break; - case 0x13: - Ypos = Ymid; - Ymid = (Ypos + Ypos2) >> 1; - break; - case 0x14: - Ypos2 = Ymid; - Ymid = (Ypos + Ypos2) >> 1; - break;*/ case 0x15: - for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) - _api.GUILib.DrawPixel(Xpos2 - TempX, Ymid + yoff, Color.FromArgb(127, 0, 255)); - for (int TempX = Math.Min(Math.Max(0, Xmid), 320); TempX <= Math.Min(Math.Max(8, Xpos2), 327); TempX++) - _api.GUILib.DrawPixel(TempX, Ymid, Color.FromArgb(127, 0, 255)); - for (uint TempX = (uint)Math.Min(Math.Max(0, Ymid), 223); TempX <= Math.Min(Math.Max(0, Ypos2), 223); TempX++) - _api.GUILib.DrawPixel(Xmid, (int)TempX, Color.FromArgb(127, 0, 255)); - break; case 0x18: case 0x19: - for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) - { - _api.GUILib.DrawPixel(Xmid + yoff, Ypos2-TempX, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.Purple); break; case 0x1A: - for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) - _api.GUILib.DrawPixel(Xpos + TempX, Ymid + yoff, Color.FromArgb(127, 0, 255)); - for (int TempX = Math.Min(Math.Max(0, Xpos), 320); TempX <= Math.Min(Math.Max(8, Xmid), 327); TempX++) - _api.GUILib.DrawPixel(TempX, Ymid, Color.FromArgb(127, 0, 255)); - for (uint TempX = (uint)Math.Min(Math.Max(0, Ymid), 223); TempX <= Math.Min(Math.Max(0, Ypos2), 223); TempX++) - _api.GUILib.DrawPixel(Xmid, (int)TempX, Color.FromArgb(127, 0, 255)); - break; case 0x1D: - for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) - { - _api.GUILib.DrawPixel(Xmid - yoff, Ypos2 - TempX, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } - break; - case 0x1F: - for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) - _api.GUILib.DrawPixel(Xpos + TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); - for (int TempX = Math.Min(Math.Max(0, Xpos), 320); TempX <= Math.Min(Math.Max(8, Xmid), 327); TempX++) - _api.GUILib.DrawPixel(TempX, Ymid, Color.FromArgb(127, 0, 255)); - for (uint TempX = (uint)Math.Min(Math.Max(0, Ypos), 223); TempX <= Math.Min(Math.Max(0, Ymid), 223); TempX++) - _api.GUILib.DrawPixel(Xmid, (int)TempX, Color.FromArgb(127, 0, 255)); - break; case 0x20: case 0x21: - for (int TempX = 0; TempX <= Xmid-Xpos; TempX++) - { - _api.GUILib.DrawPixel(Xpos + TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.Purple); break; + case 0x1F: case 0x22: case 0x23: - for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) - { - _api.GUILib.DrawPixel(Xmid - yoff, Ypos + TempX, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.Purple); break; case 0x24: - for (int TempX = 0; TempX <= Xmid-Xpos; TempX++, yoff++) - _api.GUILib.DrawPixel(Xpos2 - TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); - break; case 0x25: case 0x26: - for (int TempX = 0; TempX <= Xmid-Xpos; TempX++) - { - _api.GUILib.DrawPixel(Xpos2 - TempX, Ymid - yoff, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } - break; case 0x27: case 0x28: - for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) - { - _api.GUILib.DrawPixel(Xmid + yoff, Ypos + TempX, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.Purple); break; case 0x2B: - _api.GUILib.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.FromArgb(127, 0, 255)); - for (int TempX = 0; TempX <= Ymid - Ypos; TempX++) - { - _api.GUILib.DrawPixel(Xpos + yoff, Ymid - TempX, Color.FromArgb(127, 0, 255)); - _api.GUILib.DrawPixel(Xpos2 - yoff, Ymid - TempX, Color.FromArgb(127, 0, 255)); - if ((TempX & 1) != 0) yoff++; - } - yoff = Xmid - (Xpos + yoff); - _api.GUILib.DrawLine(Xmid - yoff, Ypos, Xmid + yoff, Ypos, Color.FromArgb(127, 0, 255)); + Point[] trapPoints = + { + new Point(Xpos, Ymid), + new Point(Xpos + (Ymid - Ypos >> 1), Ypos), + new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), + new Point(Xpos2, Ymid) + }; + _api.GUILib.DrawPolygon(trapPoints, Color.Purple, Color.FromArgb(63, Color.Purple)); break; default: - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(255, 127, 0, 255)); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Purple); + if (type != 0x10) + PutText(type.ToString("X2"), Xmid, Ymid, 1, 1, -1, -1, Color.Red, Color.Blue); break; } - // if (!displayed) - if (type != 0x10) - { - uint temp = _api.MemLib.ReadU8(curObj + 0x7E); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(1, Xmid-2), 629), Math.Min(Math.Max(1, Ymid-4), 425), Color.Blue); - } curObj = _api.MemLib.ReadU24(curObj+1); } //walls - bool displayed; curObj = _api.MemLib.ReadU24(0xFFCFC1); while (curObj != 0) { - + Xmid = _api.MemLib.ReadS16(curObj + 0x24); + Xmid = _api.MemLib.ReadS16(curObj + 0x28); Xpos = _api.MemLib.ReadS16(curObj + 0x2C); Xpos2= _api.MemLib.ReadS16(curObj + 0x34); Ypos = _api.MemLib.ReadS16(curObj + 0x30); Ypos2= _api.MemLib.ReadS16(curObj + 0x38); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - displayed = false; - uint type = _api.MemLib.ReadU8(curObj + 0x7E); - int yoff = 0; - switch (type) + Xmid -= _camX; Ymid -= _camY; + int colltype = _api.MemLib.ReadS8(curObj + 0x7E); + switch (colltype) { + case 0x10: + case 0x2D: + case 0x2E: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + break; case 0x11: - Xpos2 = Xmid; Xmid = (Xpos + Xpos2) >> 1; + Xpos2 = Xmid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.PowderBlue); break; case 0x12: - Xpos = Xmid; Xmid = (Xpos + Xpos2) >> 1; + Xpos = Xmid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos, Ypos2, Color.PowderBlue); break; case 0x13: - Ypos = Ymid; Ymid = (Ypos + Ypos2) >> 1; + Ypos = Ymid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.PowderBlue); break; case 0x14: - Ypos2 = Ymid; Ymid = (Ypos + Ypos2) >> 1; + Ypos2 = Ymid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.PowderBlue); break; case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: - _api.GUILib.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.White); - _api.GUILib.DrawLine(Xmid, Ypos2, Xmid, Ymid, Color.FromArgb(127,Color.White)); - _api.GUILib.DrawLine(Xmid, Ymid, Xpos2, Ymid, Color.FromArgb(127, Color.White)); - displayed = true; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); break; case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.White); - _api.GUILib.DrawLine(Xmid, Ymid, Xmid, Ypos2, Color.FromArgb(127, Color.White)); - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ymid, Color.FromArgb(127, Color.White)); - displayed = true; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); break; case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23: - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.White); - _api.GUILib.DrawLine(Xmid, Ymid, Xmid, Ypos, Color.FromArgb(127, Color.White)); - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ymid, Color.FromArgb(127, Color.White)); - displayed = true; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.FromArgb(63,Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); break; case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: - _api.GUILib.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.White); - _api.GUILib.DrawLine(Xmid, Ypos, Xmid, Ymid, Color.FromArgb(127, Color.White)); - _api.GUILib.DrawLine(Xmid, Ymid, Xpos2, Ymid, Color.FromArgb(127, Color.White)); - displayed = true; + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.FromArgb(63,Color.Yellow)); + _api.GUILib.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); + break; + case 0x29: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); + _api.GUILib.DrawLine(Xpos , Ypos, Xpos , Ypos2, Color.Black); + _api.GUILib.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.Black); + break; + case 0x2A: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); break; case 0x2B: - _api.GUILib.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.FromArgb(127, Color.White)); - for (int TempX = 0; TempX <= Ymid-Ypos; TempX++) + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + Point[] trapPoints = { - _api.GUILib.DrawPixel(Xpos + yoff, Ymid - TempX, Color.White); - _api.GUILib.DrawPixel(Xpos2 - yoff, Ymid - TempX, Color.White); - if ((TempX & 1) != 0) yoff++; - } - yoff = Xmid - (Xpos + yoff); - _api.GUILib.DrawLine(Xmid - yoff, Ypos, Xmid + yoff, Ypos); - displayed = true; + new Point(Xpos, Ymid), + new Point(Xpos + (Ymid - Ypos >> 1), Ypos), + new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), + new Point(Xpos2, Ymid) + }; + _api.GUILib.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); + //_api.GUILib.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.Yellow); break; default: - if (type != 0x10) - { - var temp = _api.MemLib.ReadU8(curObj + 0x7E); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(0, Xmid-3), 628), Math.Min(Math.Max(2, Ymid-3), 426), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(2, Xmid-1), 630), Math.Min(Math.Max(0, Ymid-5), 424), Color.Red); - Print_Text(temp.ToString("%02X"), 2, Math.Min(Math.Max(1, Xmid-2), 629), Math.Min(Math.Max(1, Ymid-4), 425), Color.Lime); - } + DrawEccoRhomb_scaled(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); break; } - if (!displayed) _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.White); curObj = _api.MemLib.ReadU24(curObj+1); } //inanimate objects curObj = _api.MemLib.ReadU24(0xFFCFBD); while (curObj != 0) { - if (_api.MemLib.ReadU8(curObj + 0x7E) > 0xF); + type = _api.MemLib.ReadU32(curObj + 0xC); + int colltype = _api.MemLib.ReadS8(curObj + 0x7E); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + int Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + int Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + if (type == 0x9CE3A) //Remnant Stars { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2= _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2= _api.MemLib.ReadS16(curObj + 0x38); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - } - Xpos += Xpos2; - Ypos += Ypos2; - Xpos >>= 1; - Ypos >>= 1; - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xpos-16), 605), Math.Min(Math.Max(0, Ypos-5), 424), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xpos-14), 607), Math.Min(Math.Max(2, Ypos-3), 426), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(0, Xpos-16), 605), Math.Min(Math.Max(2, Ypos-3), 426), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(2, Xpos-14), 607), Math.Min(Math.Max(0, Ypos-5), 424), Color.Lime); - Print_Text(curObj.ToString("X8"), 8, Math.Min(Math.Max(1, Xpos-15), 606), Math.Min(Math.Max(1, Ypos-4), 425), Color.Blue); - curObj = _api.MemLib.ReadU24(curObj+1); + uint subObj = _api.MemLib.ReadU24(curObj + 0x5); + uint anim = _api.MemLib.ReadU16(curObj + 0x6C); + if ((anim <= 7) && (subObj == 0xFFA9D4)) + { + DrawEccoRhomb(Xmid, Ymid, 96, Color.Red); + PutText($"{((7 - anim) * 4) - ((_api.MemLib.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Lime, Color.Blue); + } + } + else if ((type == 0x9CC06) || (type == 0x9CA10)) + { + Xvec = ((_api.MemLib.ReadS32(curObj + 0x24) + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((_api.MemLib.ReadS32(curObj + 0x28) + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + } + else if (type == 0x9B5D8) + { + Xvec = Xmid; + Yvec = Ymid; + } + else if (type == 0xC0152) // Vortex Future Vertical Gate + { + Xvec = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Yvec = (_api.MemLib.ReadS32(curObj + 0x20) + _api.MemLib.ReadS32(curObj + 0x60) >> 16) - _camY; + _api.GUILib.DrawLine(Xmid, 0, Xmid, 448, Color.PowderBlue); + DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + } + else if (type == 0xC3330) // City Of Forever Horizontal Gate Slave + { + Xvec = (_api.MemLib.ReadS32(curObj + 0x1C) + _api.MemLib.ReadS32(curObj + 0x5C) >> 16) - _camX; + Yvec = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + } + else if (type == 0xC35B0) // City Of Forever Horizontal Gate Master + { + var mode = _api.MemLib.ReadByte(curObj + 0x15); + var tmpx = Xpos; + Xpos = _api.MemLib.ReadS32(curObj + 0x1C); + Xvec = (Xpos + _api.MemLib.ReadS32(curObj + 0x5C) >> 16) - _camX; + Xpos >>= 16; Xpos -= _camX; + Yvec = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + if ((mode == 1) || (mode == 3)) + { + DrawEccoOct(Xpos, Yvec, 128, Color.Orange); + } + Xpos = tmpx; + DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + } + else if (type == 0xC343A) // City Of Forever Vertical Gate + { + var mode = _api.MemLib.ReadByte(curObj + 0x15); + if ((mode == 1) || (mode == 3)) + { + DrawEccoOct(Xmid, Ymid, 128, Color.Orange); + } + Xvec = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Yvec = (_api.MemLib.ReadS32(curObj + 0x20) + _api.MemLib.ReadS32(curObj + 0x60) >> 16) - _camY; + DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + } + else if (type == 0xA579A) // Antigrav Ball + { + DrawEccoOct(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x4C), (_api.MemLib.ReadU16(0xFFA7C8) & 7) == 7 ? Color.Blue : Color.Gray); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); + Xpos = Ypos = Xpos2 = Ypos2 = _camX - 128; + } + else if (type == 0xDF4E2) // Moray Abyss Conch Shell + { + Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + DrawBox(Xpos - 96, 0 - _camY, Xpos + 96, _api.MemLib.ReadS16(0xFFA7AC) - _camY - 64, Color.Orange, 0); + var mode = _api.MemLib.ReadByte(curObj + 0x15); + var modeTimer = _api.MemLib.ReadS16(curObj + 0x6E); + var Xvel1 = _api.MemLib.ReadS32(curObj + 0x54) / 65536.0; + var Yvel1 = _api.MemLib.ReadS32(curObj + 0x58) / 65536.0; + var Xvel2 = _api.MemLib.ReadS32(curObj + 0x5C) / 65536.0; + var Yvel2 = _api.MemLib.ReadS32(curObj + 0x60) / 65536.0; + TickerText($"{mode}:{modeTimer}:{_api.MemLib.ReadS16(0xFFA7AC) - 64 - Ymid - _camY}", Color.Red); + TickerText($"{Xvel1:0.######}:{Yvel1:0.######}", Color.Red); + TickerText($"{Xvel2:0.######}:{Yvel2:0.######}", Color.Red); + TickerText($"{Xvel1 + Xvel2:0.######}:{Yvel1 + Yvel2:0.######}", Color.Red); + switch (mode) + { + case 0: + Xpos2 = Math.Abs(Xmid - Xpos); + if (Xpos2 > 0x48) + { + Xpos2 = (0x60 - Xpos2) << 1; + Ypos2 = Ymid + Xpos2; + } + else + { + Ypos2 = Ymid - (Xpos2 >> 1) + 0x60; + } + DrawBoxMWH(Xpos, Ypos2, 1, 1, Color.Gray, 0); + DrawBoxMWH(Xpos, 112 + _top, 72, 224, (modeTimer <= 1) ? Color.Orange : Color.Gray, 0); + break; + case 1: + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Orange, 0); + Xpos2 = _api.MemLib.ReadS32(0xFFAA1A) - _api.MemLib.ReadS32(curObj + 0x24); + Ypos2 = _api.MemLib.ReadS32(0xFFAA1E) - _api.MemLib.ReadS32(curObj + 0x28); + var dSml = Math.Abs(Xpos2); + var dBig = Math.Abs(Ypos2); + if (dBig < dSml) + { + dSml ^= dBig; + dBig ^= dSml; + dSml ^= dBig; + } + var rad = (dBig + (dSml >> 1) - (dSml >> 3)) / 65536.0; + Xpos2 = (int)(Xpos2 * (256.0 / (rad+1))) >> 20; + Ypos2 = (int)(Ypos2 * (256.0 / (rad+1))) >> 20; + _api.GUILib.DrawLine(Xmid, Ymid, Xmid + Xpos2, Ymid + Ypos2, Color.Gray); + TickerText($"{Xpos2 / 512.0:0.######}:{Ypos2 / 512.0:0.######}", Color.Red); + break; + case 2: + TickerText($"{_api.MemLib.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); + break; + } + } + else if ((type == 0xC57A6) || (type == 0xDEE3C) || (type == 0xDF8A0) || (type == 0xDFA98) + || (type == 0xA0BE4) || (type == 0x9FEB2) || (type == 0xA5670) || (type == 0xAEC1A) + || (type == 0xA6C4A) || (type == 0xAB65A) || (type == 0x9F2EC)) { } + else + { + PutText($"{type:X5}:{_api.MemLib.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.Lime, Color.Blue); + PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.Lime, Color.Blue); + } + colltype = _api.MemLib.ReadS8(curObj + 0x7E); + switch (colltype) + { + case 0x10: + case 0x2D: + case 0x2E: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + break; + case 0x11: + Xmid = (Xpos + Xpos2) >> 1; + Xpos2 = Xmid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + break; + case 0x12: + Xmid = (Xpos + Xpos2) >> 1; + Xpos = Xmid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + break; + case 0x13: + Ymid = (Ypos + Ypos2) >> 1; + Ypos = Ymid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + break; + case 0x14: + Ymid = (Ypos + Ypos2) >> 1; + Ypos2 = Ymid; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + break; + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); + break; + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); + break; + case 0x1F: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); + _api.GUILib.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); + break; + case 0x2A: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); + break; + case 0x2B: + Xmid = (Xpos + Xpos2) >> 1; + Ymid = (Ypos + Ypos2) >> 1; + Point[] trapPoints = + { + new Point(Xpos, Ymid), + new Point(Xpos + (Ymid - Ypos >> 1), Ypos), + new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), + new Point(Xpos2, Ymid) + }; + _api.GUILib.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); + break; + case 0x2C: + break; + default: + DrawEccoRhomb_scaled(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); + break; + } + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + curObj = _api.MemLib.ReadU24(curObj+1); } //animate objects if (_mode == Modes.Ecco2) @@ -455,78 +1015,1416 @@ namespace BizHawk.Client.EmuHawk curObj = _api.MemLib.ReadU24(0xFFD829); while (curObj != 0) { - uint type = 0; + type = 0; switch (_mode) { case Modes.Ecco2: - { - uint flags = _api.MemLib.ReadU16(curObj + 0x10); - //if ((flags & 0x2000) || !(flags & 2)); - type = _api.MemLib.ReadU32(curObj + 0xC); - if ((type == 0xBA52E) || (type == 0xBA66E)) { - uint Adelikat = curObj; - while (Adelikat != 0) + uint flags = _api.MemLib.ReadU16(curObj + 0x10); + int Xvec = 0; + int Yvec = 0; + //if ((flags & 0x2000) || !(flags & 2)); + HP = _api.MemLib.ReadS8(curObj + 0x7B); + type = _api.MemLib.ReadU32(curObj + 0xC); + if ((type == 0xA1FE6) || (type == 0xA208E) // Chain link creatures such as vortex worm, magic arm, etc + || (type == 0xA2288) || (type == 0xA27A4) || (type == 0xA2BB0) || (type == 0xA2C50)) { - Xpos = _api.MemLib.ReadS16(Adelikat + 0x24); - Ypos = _api.MemLib.ReadS16(Adelikat + 0x28); + uint subObj = curObj; + while (subObj != 0) + { + Xpos = _api.MemLib.ReadS32(subObj + 0x24); + Ypos = _api.MemLib.ReadS32(subObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(subObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(subObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; + Ypos -= _camY; + if (_api.MemLib.ReadS16(subObj + 0x44) == _api.MemLib.ReadS16(subObj + 0x48)) + { + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.Cyan, 0); + } + else + { + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.Lime, 0); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x48), Color.Blue, 0); + } + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + subObj = _api.MemLib.ReadU24(subObj + 5); + } + if (HP > 2) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); + } + } + else if ((type == 0xB7486) || (type == 0xB864E) //Chain link creatures such as eels and worms + || (type == 0xB8A64) || (type == 0xB8C1A) + || (type == 0xB904A) || (type == 0xB9728) || (type == 0xB9B6A) || (type == 0xBA52E) + || (type == 0xBA66E) || (type == 0xE0988) || (type == 0xA18E2) || (type == 0xE069A)) + { + uint subObj = curObj; + while (subObj != 0) + { + Xpos = _api.MemLib.ReadS32(subObj + 0x24); + Ypos = _api.MemLib.ReadS32(subObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(subObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(subObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; + Ypos -= _camY; + if (_api.MemLib.ReadS16(subObj + 0x44) == _api.MemLib.ReadS16(subObj + 0x48)) + { + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.White, 0); + } + else + { + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.Lime, 0); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x48), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x48), Color.Magenta, 0); + } + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + if (type == 0xBA66E) + { + DrawEccoOct(Xpos, Ypos, 32, Color.Blue, 16); + if (subObj == curObj) + { + var mode = _api.MemLib.ReadByte(subObj + 0x15); + TickerText($"{_api.MemLib.ReadByte(subObj + 0x14)}:{mode}:{_api.MemLib.ReadByte(subObj + 0x70)}", Color.Red); + TickerText($"{_api.MemLib.ReadS32(subObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); + TickerText($"{_api.MemLib.ReadS32(subObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(subObj + 0x50) / 65536.0:0.######}", Color.Red); + switch (mode) + { + case 0: + case 2: + case 4: + Xpos2 = _api.MemLib.ReadS32(0xFFAA22) - _api.MemLib.ReadS32(subObj + 0x24); + Ypos2 = _api.MemLib.ReadS32(0xFFAA26) - _api.MemLib.ReadS32(subObj + 0x28); + var dSml = Math.Abs(Xpos2); + var dBig = Math.Abs(Ypos2); + if (dBig < dSml) + { + dSml ^= dBig; + dBig ^= dSml; + dSml ^= dBig; + } + var rad = (dBig + (dSml >> 1) - (dSml >> 3)) / 65536.0; + Xpos2 = (int)(Xpos2 * (256.0 / (rad + 1))) >> 20; + Ypos2 = (int)(Ypos2 * (256.0 / (rad + 1))) >> 20; + _api.GUILib.DrawLine(Xpos, Ypos, Xpos + Xpos2, Ypos + Ypos2, Color.Red); + break; + default: + break; + + } + } + } + else if ((type == 0xBA52E) && (subObj == _api.MemLib.ReadU24(curObj + 0x1D))) + { + DrawEccoOct(Xpos, Ypos, 32, (_api.MemLib.ReadByte(subObj + 0x70) == 0) ? Color.Blue : Color.Gray, 16); + var mode = _api.MemLib.ReadByte(curObj + 0x15); + TickerText($"{_api.MemLib.ReadByte(curObj + 0x14)}:{mode}:{_api.MemLib.ReadS16(curObj + 0x6E)}:{_api.MemLib.ReadByte(subObj + 0x70)}", Color.Red); + TickerText($"{_api.MemLib.ReadS32(subObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); + } + else if (type == 0xE0988) + { + DrawEccoOct(Xpos, Ypos, 48, Color.FromArgb(64, Color.Blue), 16); + } + if (HP > 2) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); + } + subObj = _api.MemLib.ReadU24(subObj + 5); + } + } + else if (type == 0xB7DF4) + { + Xpos = _api.MemLib.ReadS32(curObj + 0x24); + Ypos = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(Adelikat + 0x44), Color.Lime); - Adelikat = _api.MemLib.ReadU32(Adelikat + 4); + DrawEccoOct(Xpos, Ypos, 26, Color.PowderBlue); + DrawEccoOct(Xpos, Ypos, 26, Color.White); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec); } - Xpos = _api.MemLib.ReadS16(curObj + 0x24); - Ypos = _api.MemLib.ReadS16(curObj + 0x28); - Xpos -= _camX; - Ypos -= _camY; - } - else if (type == 0xE47EE) - { - uint Adelikat = curObj; - while (Adelikat != 0) + else if (type == 0xE47EE) { - Xpos = _api.MemLib.ReadS16(Adelikat + 0x1C); - Ypos = _api.MemLib.ReadS16(Adelikat + 0x20); + uint subObj = _api.MemLib.ReadU24(curObj + 5); + while (subObj != 0) + { + Xpos = _api.MemLib.ReadS32(subObj + 0x1C); + Ypos = _api.MemLib.ReadS32(subObj + 0x20); + Xvec = ((Xpos + _api.MemLib.ReadS32(subObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(subObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; + Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, ((_api.MemLib.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.White); + DrawEccoOct(Xpos, Ypos, ((_api.MemLib.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.Yellow, 0); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + subObj = _api.MemLib.ReadU24(subObj + 5); + } + } + else if (type == 0xDBE64) // Medusa Boss + { + uint subObj = curObj; + uint next; + do + { + next = _api.MemLib.ReadU24(subObj + 5); + if (next != 0) subObj = next; + } while (next != 0); + Xpos = _api.MemLib.ReadS16(subObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(subObj + 0x34); + Ypos = _api.MemLib.ReadS16(subObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(subObj + 0x38); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + DrawEccoOct(Xpos, Ypos, 32, Color.Red); + DrawEccoOct(Xpos2, Ypos2, 32, Color.Red); + Xpos = _api.MemLib.ReadS32(curObj + 0x24); + Ypos = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, (_api.MemLib.ReadS16(Adelikat + 0x2C) >> 1) + 16, Color.Lime); - Adelikat = _api.MemLib.ReadU32(Adelikat + 4); + var octOff = (int)(Math.Sqrt(2) * 60) >> 1; + Point[] hemiOctPoints = + { + new Point(Xpos - 60, Ypos), + new Point(Xpos - octOff, Ypos - octOff), + new Point(Xpos, Ypos - 60), + new Point(Xpos + octOff, Ypos - octOff), + new Point(Xpos + 60, Ypos) + }; + _api.GUILib.DrawPolygon(hemiOctPoints, Color.Cyan, Color.FromArgb(0x3F, Color.Cyan)); + for (int l = 0; l < 4; l++) + { + _api.GUILib.DrawLine(hemiOctPoints[l].X, hemiOctPoints[l].Y, hemiOctPoints[l + 1].X, hemiOctPoints[l + 1].Y, Color.Cyan); + } + DrawBoxMWH(Xpos, Ypos + 12, 52, 12, Color.Cyan); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); } - Xpos = _api.MemLib.ReadS16(curObj + 0x24); - Ypos = _api.MemLib.ReadS16(curObj + 0x28); - Xpos -= _camX; - Ypos -= _camY; + else if (type == 0xDCEE0) // Globe Holder boss + { + uint subObj; + var mode = _api.MemLib.ReadByte(curObj + 0x15); + if (mode < 4) + { + subObj = _api.MemLib.ReadU24(curObj + 9); + while (subObj != 0) + { + Xmid = _api.MemLib.ReadS32(subObj + 0x24); + Ymid = _api.MemLib.ReadS32(subObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(subObj + 0x54) + _api.MemLib.ReadS32(subObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(subObj + 0x58) + _api.MemLib.ReadS32(subObj + 0x60)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawEccoOct(Xmid, Ymid, 12, Color.Orange); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + var next = _api.MemLib.ReadU24(subObj + 9); + if ((next == 0) && ((mode & 1) != 0)) + { + DrawEccoOct(Xmid, Ymid, _api.MemLib.ReadS16(subObj + 0x3C), Color.Orange); + } + subObj = _api.MemLib.ReadU24(subObj + 9); + } + subObj = _api.MemLib.ReadU24(curObj + 5); + while (subObj != 0) + { + Xmid = _api.MemLib.ReadS32(subObj + 0x24); + Ymid = _api.MemLib.ReadS32(subObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(subObj + 0x54) + _api.MemLib.ReadS32(subObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(subObj + 0x58) + _api.MemLib.ReadS32(subObj + 0x60)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawEccoOct(Xmid, Ymid, 12, Color.Orange); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + var next = _api.MemLib.ReadU24(subObj + 5); + if ((next == 0) && ((mode & 2) != 0)) + { + DrawEccoOct(Xmid, Ymid, _api.MemLib.ReadS16(subObj + 0x3C), Color.Orange); + } + subObj = _api.MemLib.ReadU24(subObj + 5); + } + } + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + int Xtmp = _api.MemLib.ReadS32(curObj + 0x2C); + int Ytmp = _api.MemLib.ReadS32(curObj + 0x30); + int Xtmp2 = _api.MemLib.ReadS32(curObj + 0x34); + int Ytmp2 = _api.MemLib.ReadS32(curObj + 0x38); + Xpos = (Xtmp >> 16) - _camX; Xpos2 = (Xtmp2 >> 16) - _camX; + Ypos = (Ytmp >> 16) - _camY; Ypos2 = (Ytmp2 >> 16) - _camY; + Xvec = ((_api.MemLib.ReadS32(curObj + 0x24) + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((_api.MemLib.ReadS32(curObj + 0x28) + +_api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + if (mode < 7) + { + double overlap = 0; + DrawEccoOct(Xmid, Ymid, 0x5C, _api.MemLib.ReadByte(curObj + 0x7C) == 0 ? Color.Blue : Color.Gray); + DrawEccoOct(Xmid, Ymid, 0x5C, Color.Cyan, 0); + Xvec = (_api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)); + Yvec = (_api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)); + subObj = _api.MemLib.ReadU24(curObj + 0x69); + if (subObj != 0) + { + Xpos = _api.MemLib.ReadS32(subObj + 0x2C); + Ypos = _api.MemLib.ReadS32(subObj + 0x30); + Xpos2 = _api.MemLib.ReadS32(subObj + 0x34); + Ypos2 = _api.MemLib.ReadS32(subObj + 0x38); + while ((Xtmp > Xpos) && (Xtmp2 < Xpos2) && (Ytmp > Ypos) && (Ytmp2 < Ypos2) && ((Xvec != 0) || (Yvec != 0))) + { + Xtmp += Xvec; Xtmp2 += Xvec; + Ytmp += Yvec; Ytmp2 += Yvec; + } + overlap = Math.Max(Math.Max(Xpos - Xtmp, Xtmp2 - Xpos2), Math.Max(Ypos - Ytmp, Ytmp2 - Ypos2)) / 65536.0; + Xpos >>= 16; Xpos2 >>= 16; + Ypos >>= 16; Ypos2 >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, (overlap >= 6) ? Color.Orange : Color.White, 0); + } + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, (overlap >= 6) ? Color.Orange : Color.White, (overlap >= 6) ? 63 : 0); + if (mode < 4) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x4C) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x50) - _camY; + if ((mode & 1) == 0) DrawEccoOct(Xmid, Ymid - 0xAE, 32, Color.Orange); + if ((mode & 2) == 0) DrawEccoOct(Xmid, Ymid + 0xAE, 32, Color.Orange); + } + TickerText($"{mode}:{_api.MemLib.ReadByte(curObj + 0x7F)}:{_api.MemLib.ReadByte(curObj + 0x6D)}:{_api.MemLib.ReadByte(curObj + 0x7C)}", Color.Red); + } + else if (mode == 8) + { + DrawEccoOct(Xmid - 16, Ymid - 16, 12, Color.Red); + } + } + else if (type == 0xE1BA2) // Vortex Queen Boss + { + var vulnCount = _api.MemLib.ReadByte(curObj + 0x7F); + var state = _api.MemLib.ReadByte(curObj + 0x7C); + var stateCounter = _api.MemLib.ReadU16(curObj + 0x6E); + var mode = _api.MemLib.ReadU16(curObj + 0x64); + var modeCounter = _api.MemLib.ReadU16(curObj + 0x66); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x40); + Xvec = Xmid + _api.MemLib.ReadS32(curObj + 0x54); + Yvec = Ymid + _api.MemLib.ReadS32(curObj + 0x58); + Xvec >>= 16; Yvec >>= 16; + Xmid >>= 16; Ymid >>= 16; + Xvec -= _camX; Yvec -= _camY; + Xmid -= _camX; Ymid -= _camY; + if (mode < 5) + { + var octOff = (int)(80 * Math.Sqrt(2)) >> 1; + Point hexOff = Intersection(new Point(-80, 0), new Point(-octOff, -octOff), new Point(-80, -32), new Point(-octOff, -32)).Value; + Point[] roundedRect = { + new Point(Xmid - 80, Ymid), + new Point(Xmid + hexOff.X, Ymid - 32), + new Point(Xmid - hexOff.X, Ymid - 32), + new Point(Xmid + 80, Ymid), + new Point(Xmid - hexOff.X, Ymid + 32), + new Point(Xmid + hexOff.X, Ymid + 32) + }; + _api.GUILib.DrawPolygon(roundedRect, Color.Orange, Color.FromArgb(63, Color.Orange)); + } + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + TickerText($"{state:X2}:{stateCounter}:{mode}:{modeCounter}:{_api.MemLib.ReadByte(curObj + 0x70) & 0xF}", Color.Red); + var subObj = _api.MemLib.ReadU24(curObj + 0x5); + var tongueMode = mode; + mode = _api.MemLib.ReadByte(subObj + 0x15); + modeCounter = _api.MemLib.ReadU16(subObj + 0x6E); + Xmid = _api.MemLib.ReadS32(subObj + 0x24); + Ymid = _api.MemLib.ReadS32(subObj + 0x40); + Xvec = (Xmid + _api.MemLib.ReadS32(subObj + 0x5C) >> 16) - _camX; + Yvec = (Ymid + _api.MemLib.ReadS32(subObj + 0x60) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + Ymid -= 32; Yvec -= 32; + var levelHeight = _api.MemLib.ReadS16(0xFFA7AC) - _camY; + switch (mode) + { + case 0: + DrawBox(Xmid - 32, Ymid - ((state == 5) ? 0x60 : 0x70), Xmid + 32, Ymid - 16, Color.Red); + break; + case 2: + Ypos = _api.MemLib.ReadS16(subObj + 0x50) - _camY; + _api.GUILib.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); + DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); + break; + case 3: + modeCounter = _api.MemLib.ReadByte(subObj + 0x7C); + break; + case 5: + Point[] throatShape = + { + new Point(Xmid - 48, levelHeight), + new Point(Xmid - 48, Ymid + 60), + new Point(Xmid - 16, Ymid + 20), + new Point(Xmid + 16, Ymid + 20), + new Point(Xmid + 48, Ymid + 60), + new Point(Xmid + 48, levelHeight) + }; + _api.GUILib.DrawPolygon(throatShape, Color.Red, Color.FromArgb(63, Color.Red)); + DrawEccoOct(Xmid, Ymid, 24, Color.Red); + DrawEccoOct(Xmid, Ymid, 24, Color.White, 0); + break; + case 6: + if ((state != 7) && (vulnCount == 0) && (tongueMode != 7)) + { + DrawEccoOct(Xmid, Ymid + 16, 64, Color.Blue); + } + if (tongueMode == 7) + { + uint subObj2 = _api.MemLib.ReadU24(0xFFCFCD); + while (subObj2 != 0) + { + if (_api.MemLib.ReadU16(subObj2 + 0x10) == 0xFF) + { + Xpos = _api.MemLib.ReadS16(subObj2 + 0x24) - _camX; + Ypos = _api.MemLib.ReadS16(subObj2 + 0x28) - _camY; + Xpos2 = ((_api.MemLib.ReadS32(subObj2 + 0x24) + _api.MemLib.ReadS32(subObj2 + 0x54)) >> 16) - _camX; + Ypos2 = ((_api.MemLib.ReadS32(subObj2 + 0x28) + _api.MemLib.ReadS32(subObj2 + 0x58)) >> 16) - _camY; + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + } + subObj2 = _api.MemLib.ReadU24(subObj2 + 1); + } + } + Ypos = _api.MemLib.ReadS16(subObj + 0x50) - _camY; + _api.GUILib.DrawLine(Xmid - 48, Ypos - 94, Xmid + 48, Ypos - 94, Color.Orange); + _api.GUILib.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); + DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); + break; + default: + break; + } + if ((mode < 7) || ((mode == 7) && (_api.MemLib.ReadU24(0xFFCFC9) != 0))) + { + if (_api.MemLib.ReadByte(subObj + 0x70) == 0) + { + DrawEccoOct(Xmid, Ymid, 32, Color.Red); + DrawBox(Xmid - 48, Ymid + 32, Xmid + 48, levelHeight, Color.Red); + } + Ypos = _api.MemLib.ReadS16(subObj + 0x50) - _camY - 94; + _api.GUILib.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); + DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); + } + if (_api.MemLib.ReadS32(subObj + 0xC) == 0xE17B4) + { + Point[] shapePoints = + { + new Point(Xmid - 48, levelHeight), + new Point(Xmid - 48, Ymid + 60), + new Point(Xmid - 16, Ymid + 20), + new Point(Xmid + 16, Ymid + 20), + new Point(Xmid + 48, Ymid + 60), + new Point(Xmid + 48, levelHeight) + }; + _api.GUILib.DrawPolygon(shapePoints, Color.Red, Color.FromArgb(63, Color.Red)); + DrawEccoOct(Xmid, Ymid, 24, Color.Red); + DrawEccoOct(Xmid, Ymid, 24, Color.White, 0); + } + Ypos = (_api.MemLib.ReadS16(subObj + 0x50) - _camY) - 264; + DrawBoxMWH(160 + _left, Ypos, 320, 12, (32 < stateCounter) && (stateCounter < 160) ? Color.Brown : Color.Gray); + if ((32 < stateCounter) && (stateCounter < 160)) + { + DrawBoxMWH(_left + 160, Ypos, 320, 12, Color.White, 0); + } + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + TickerText($"{mode:X2}:{modeCounter}:{HP}:{vulnCount}", Color.Red); + HP = 0; + } + else if (type == 0xA5BD2) // Telekinetic future dolphins + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); + DrawEccoOct(Xmid, Ymid, 4, Color.Red); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0x9F5B0) || (type == 0x9F4DC) || (type == 0x9F6A0)) // Falling rock, breaks barriers + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + if (type == 0x9F6A0) + { + int width = _api.MemLib.ReadS16(curObj + 0x44) << 1; + DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); + } + TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); + } + else if (type == 0xA3B18) + { + Xpos = _api.MemLib.ReadS32(curObj + 0x24); + Ypos = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; + Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(curObj + 0x44), Color.Yellow); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + } + else if (type == 0xA4018) + { + Xpos = _api.MemLib.ReadS32(curObj + 0x24); + Ypos = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; + Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(curObj + 0x44), Color.Gray); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + } + else if (type == 0xA091E) // Blue Whale + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + Xpos = Xmid; Ypos = Ymid; + Ymid -= 64; Yvec -= 64; + DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x50, Color.Red, 31); + DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x40, Color.Red, 31); + DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x30, Color.Red, 31); + DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x20, Color.Red, 31); + DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x10, Color.Red, 31); + if (_api.MemLib.ReadByte(curObj + 0x7F) == 0) + { + Xpos += (_api.MemLib.ReadS16(curObj + 0x6E) == 0) ? -278 : 162; + Ypos += 44 - _api.MemLib.ReadS16(curObj + 0x48); + DrawEccoOct(Xpos, Ypos, 32, Color.Blue); + } + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + + } + else if (type == 0xE66D8) //Vortex Larva + { + uint subObj = _api.MemLib.ReadU24(curObj + 5); + while (subObj != 0) + { + Xpos = _api.MemLib.ReadS16(subObj + 0x1C); + Ypos = _api.MemLib.ReadS16(subObj + 0x20); + Xpos2 = _api.MemLib.ReadS16(subObj + 0x24); + Ypos2 = _api.MemLib.ReadS16(subObj + 0x28); + Xpos -= _camX; Ypos -= _camY; + Xpos2 -= _camX; Ypos2 -= _camY; + DrawEccoOct(Xpos, Ypos, 30, Color.White, 32); + DrawEccoOct(Xpos, Ypos, 30, Color.Yellow, 0); + DrawEccoOct(Xpos2, Ypos2, 30, Color.White, 32); + DrawEccoOct(Xpos2, Ypos2, 30, Color.Yellow, 0); + subObj = _api.MemLib.ReadU24(subObj + 5); + } + Xpos = _api.MemLib.ReadS32(curObj + 0x24); + Ypos = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x72) - _camX; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x76) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; Ypos -= _camY; + DrawEccoOct(Xpos, Ypos, 0xB0, Color.Yellow); + DrawEccoOct(Xpos, Ypos, 0xB0, Color.Red, 0); + DrawEccoOct(Xpos, Ypos, 0x70, Color.Red); + DrawEccoOct(Xpos, Ypos, 0x38, Color.White); + DrawEccoOct(Xpos, Ypos, 0x38, Color.Red, 0); + DrawEccoOct(Xpos, Ypos, 48, Color.Blue, ((_api.MemLib.ReadByte(curObj + 0x7B) > 2) && (_api.MemLib.ReadByte(curObj + 0x14) != 0)) ? 63 : 0); + DrawEccoOct(Xpos2, Ypos2, 32, Color.Orange); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + TickerText($"{_api.MemLib.ReadByte(curObj + 0x14):X2}:{_api.MemLib.ReadByte(curObj + 0x7B):X2}:{_api.MemLib.ReadS16(curObj + 0x6E):D2}", Color.Red); + TickerText($"{ _api.MemLib.ReadByte(curObj + 0x7C):X2}:{_api.MemLib.ReadS16(curObj + 0x18):D3}", Color.Red); + TickerText($"{(_api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C))/65536.0:0.######}:{(_api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) / 65536.0:0.######}", Color.Red); + + } + else if (type == 0x9CE3A) //Remnant Stars + { + flags = _api.MemLib.ReadU16(curObj + 0x10); + uint subObj = _api.MemLib.ReadU24(curObj + 0x5); + uint anim = _api.MemLib.ReadU16(curObj + 0x6C); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + if ((anim <= 7) && (subObj == 0xFFA9D4)) + { + DrawEccoRhomb(Xmid, Ymid, 96, Color.Red); + PutText($"{((7 - anim) * 4) - ((_api.MemLib.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Blue, Color.Red); + + } + } + else if (type == 0xA997C) // Vortex Soldier + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = (Xmid + _api.MemLib.ReadS32(curObj + 0x54) >> 16) - _camX; + Yvec = (Ymid + _api.MemLib.ReadS32(curObj + 0x58) >> 16) - _camY; + Xvec += _api.MemLib.ReadS16(curObj + 0x64); + Yvec += _api.MemLib.ReadS16(curObj + 0x66); + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + if (_api.MemLib.ReadByte(curObj + 0x7A) == 0) + { + DrawRectRhombusIntersection(new Point(Xmid, Ymid + 6), new Point(Xmid, Ymid), 50, 44, 64, Color.Red); + } + DrawRectRhombusIntersection(new Point(Xmid, Ymid - 25), new Point(Xmid, Ymid), 38, 47, 64, Color.Red); + DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.Blue, 16); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xA6C4A) || (type == 0xC43D4)) // Barrier Glyphs + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + var subType = _api.MemLib.ReadByte(curObj + 0x13); + if ((_api.MemLib.ReadU8(curObj + 0x7A) == 0) && (_api.MemLib.ReadU8(0xFFA7B5) != 0) + && ((type != 0xA6C4A) || (subType == 0x14) || (subType == 0x97))) + { + DrawEccoOct(Xmid, Ymid, 70, Color.Red); + } + DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.Blue); + DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.PowderBlue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xB4F46) || (type == 0xB4E1C) || (type == 0xB4C18) || (type == 0xB4ACC) || (type == 0xB4B72)) // Guiding Orca/Dolphin + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + int Xdst = _api.MemLib.ReadS16(curObj + 0x64); + Xdst <<= 7; + Xdst = Xdst + 0x40 - _camX; + int Ydst = _api.MemLib.ReadS16(curObj + 0x66); + Ydst <<= 7; + Ydst = Ydst + 0x40 - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + _api.GUILib.DrawLine(Xmid, Ymid, Xdst, Ydst, Color.Orange); + DrawBoxMWH(Xdst, Ydst, 64, 64, Color.Orange); + TickerText($"{_api.MemLib.ReadS16(curObj + 0x24)}:{_api.MemLib.ReadS16(curObj + 0x28)}:{_api.MemLib.ReadByte(curObj + 0x7D)}:{_api.MemLib.ReadByte(curObj + 0x7A)}", Color.Lime); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x72) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x76) / 65536.0:0.######}", Color.Lime); + } + else if (type == 0xB5938) // Lost Orca + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + //DrawBoxMWH(Xmid, Ymid, 64, 32, Color.Lime); + if (_api.MemLib.ReadU16(curObj + 0x6E) == 0) + { + if (_api.MemLib.ReadByte(curObj + 0x7D) == 0) + { + DrawBox(Xmid + 8, Ymid - 32, Xmid + 64, Ymid + 32, Color.Red); + } + else + { + DrawBox(Xmid - 64, Ymid - 32, Xmid - 8, Ymid + 32, Color.Red); + } + } + _api.GUILib.DrawLine(Xpos - 80, Ymid, Xpos + 80, Ymid, Color.Green); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xB552A) || (type == 0xB5C42) || (type == 0xB5AFE)) // Following Orca, Returning Orca, & Idling Orca + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xB624A) // Orca Mother + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + int height = _api.MemLib.ReadS16(curObj + 0x48) + 32; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 80, 32, Color.Red, 31); + DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + if (_api.MemLib.ReadS32(0xFFAB7E) != 0) + { + DrawEccoOct(Xmid, Ymid, 0x50, Color.Red, 31); + } + } + else if (type == 0xC047E) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + var width = 2; + var height = 2; + if (_api.MemLib.ReadByte(curObj + 0x15) == 0) + { + width = _api.MemLib.ReadS16(curObj + 0x44); + height = _api.MemLib.ReadS16(curObj + 0x48); + } + DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); + } + else if (type == 0xC056E) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + var width = _api.MemLib.ReadS16(curObj + 0x44); + var height = _api.MemLib.ReadS16(curObj + 0x48); + DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); + } + else if (type == 0xC4208) // Broken Glyph Base + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + var width = _api.MemLib.ReadS16(curObj + 0x44); + var height = _api.MemLib.ReadS16(curObj + 0x48); + DrawBoxMWH(Xmid, Ymid, width, height, Color.PowderBlue); + if (_api.MemLib.ReadByte(curObj + 0x15) == 0) + { + DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 80, 80, 120, Color.Orange); + } + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xAC242) // Broken Glyph Top repairing + { + uint subObj = _api.MemLib.ReadU24(curObj + 0x5); + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xpos = _api.MemLib.ReadS16(subObj + 0x24) - _camX; + Ypos = _api.MemLib.ReadS16(subObj + 0x28) - _camY; + var width = _api.MemLib.ReadS16(curObj + 0x44); + var height = _api.MemLib.ReadS16(curObj + 0x48); + DrawBoxMWH(Xmid, Ymid, width, height, Color.Gray); + Point[] rhombPoints = + { + new Point(Xpos - 3, Ypos), + new Point(Xpos, Ypos - 3), + new Point(Xpos + 3, Ypos), + new Point(Xpos, Ypos + 3) + }; + _api.GUILib.DrawPolygon(rhombPoints, Color.Orange, Color.FromArgb(63, Color.Orange)); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + } + else if (type == 0xBE9C8) // Broken Glyph Top free + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xD9C0E) || (type == 0xDA9EA)) + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawBoxMWH(Xmid, Ymid, 0xA0, 0x70, Color.Red); + } + else if ((type == 0xBF204) || (type == 0xDA2C0)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xAF9CC) // Mirror Dolphin + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX + (_api.MemLib.ReadByte(curObj + 0x15) == 0 ? 27 : -27); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + var width = _api.MemLib.ReadS16(curObj + 0x44); + var height = _api.MemLib.ReadS16(curObj + 0x48); + DrawBoxMWH(Xmid, Ymid, width, height, Color.Blue, 31); + if (_api.MemLib.ReadByte(curObj + 0x13) != 0xAC) + { + DrawBoxMWH(Xmid, Ymid, 96, 96, Color.Orange); + } + _api.GUILib.DrawLine(Xpos, 0, Xpos, 448, Color.Red); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xAF43E) // Vortex Lightning Trap + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + if (_api.MemLib.ReadByte(curObj + 0x15) != 0) + { + if (_api.MemLib.ReadS16(0xFFAA12) != 0) + { + Ymid -= 8; + } + DrawBoxMWH(Xmid, Ymid, 92, 16, Color.Red); + PutText(_api.MemLib.ReadByte(curObj + 0x15).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); + } + else + { + DrawBoxMWH(Xmid, Ymid, 92, 16, Color.Gray); + PutText(_api.MemLib.ReadByte(curObj + 0x7F).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); + } + } + else if (type == 0xA6E24) // Barrier Glyph Forcefield + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = _api.MemLib.ReadS32(0xFFAA1A) - Xmid; + Yvec = _api.MemLib.ReadS32(0xFFAA1E) - Ymid; + var div = Math.Abs(Xvec) + Math.Abs(Yvec); + Xvec /= div; Yvec /= div; + Xvec += Xmid; Yvec += Ymid; + Xmid >>= 16; Ymid >>= 16; + Xvec >>= 16; Yvec >>= 16; + Xmid -= _camX; Ymid -= _camY; + Xvec -= _camX; Yvec -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xC4A44) || (type == 0xAA32C)) // Pulsar power-up and Vortex bullet-spawner + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue, 16); + } + else if (type == 0xC2F00) // Sky bubbles + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + var mode = _api.MemLib.ReadByte(curObj + 0x15); + switch (mode) + { + case 0: + DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 70, 70, 105, Color.Gray); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + break; + case 1: + DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 70, 70, 105, Color.Red); + break; + case 2: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); + break; + default: + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Gray); + break; + } + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0x9FA7E) //Air refiller/drainer + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Lime)); + } + else if (type == 0xBFC14) //Pushable fish + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Orange); + + } + else if ((type == 0xBE97C) //Slowing Kelp //Default Bounds nose-responsive + || (type == 0xACDAE)) //Metasphere + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xACB42) // Turtle + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + var mode = _api.MemLib.ReadByte(curObj + 0x15); + switch (mode) + { + case 0: + case 1: + case 2: + case 3: + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x4C)) >> 16) - _camX; + break; + case 4: + case 5: + case 6: + case 7: + Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x4C)) >> 16) - _camX; + break; + default: + Xvec = (Xmid >> 16) - _camX; + break; + } + Yvec = Ymid; + Xmid >>= 16; Xmid -= _camX; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + int width = _api.MemLib.ReadS16(curObj + 0x44) << 1; + DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); + TickerText($"{_api.MemLib.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xACA7E) // Retracting Turtle + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + (_api.MemLib.ReadS32(curObj + 0x4C) >> 1)) >> 16) - _camX; + Yvec = ((Ymid + (_api.MemLib.ReadS32(curObj + 0x50) >> 1)) >> 16) - _camY; + Xmid >>= 16; Xmid -= _camX; + Ymid >>= 16; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + int width = _api.MemLib.ReadS16(curObj + 0x44) << 1; + DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); + TickerText($"{(_api.MemLib.ReadS32(curObj + 0x4C) >> 1) / 65536.0:0.######}:{(_api.MemLib.ReadS32(curObj + 0x50) >> 1) / 65536.0:0.######}", Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xB5134) || (type == 0xA7E0C) //Default Bounds sonar-responsive + || (type == 0xAF868) || (type == 0xAF960) || (type == 0xD8E5C) || (type == 0xAA5C6)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if ((type == 0xACCB4) || (type == 0xACD7E) //Default Baunds non-responsive + || (type == 0xD8D96) || (type == 0xA955E) || (type == 0xA92E4) || (type == 0xC05DC) + || (type == 0xC2684)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Gray); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0x9DE86) // Star Wreath + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + Xpos = _api.MemLib.ReadS32(curObj + 0x1C); + Ypos = _api.MemLib.ReadS32(curObj + 0x20); + Xpos2 = ((Xpos + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Ypos2 = ((Ypos + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; Ypos -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + DrawBoxMWH(Xpos, Ypos, 1, 1, (_api.MemLib.ReadByte(curObj + 0x7F) == 0) ? Color.Blue : Color.Black, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + if (_api.MemLib.ReadByte(curObj + 0x12) % 7 == 0) + { + TickerText($"{_api.MemLib.ReadS32(curObj + 0x5C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x60) / 65536.0:0.######}:{_api.MemLib.ReadByte(curObj + 0x7F)}", Color.Lime); + } + } + else if ((type == 0x9D774) || (type == 0x9DA26)) // Fish + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 0x14, 0x14, Color.Lime); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xAD87C) // Enemy dolphins in metamorph levels + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(_api.MemLib.ReadS16(curObj + 0x1C) - _camX, _api.MemLib.ReadS16(curObj + 0x20) - _camY, 1024, 1024, Color.Orange, 0); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xC6128) // Drone attacking dolphin + { + Xmid = _api.MemLib.ReadS16(curObj + 0x4C) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x50) - _camY; + DrawEccoOct(Xmid, Ymid, 360, Color.Red, 0); + } + else if (type == 0xC605A) // Drone attacking dolphin sonar + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camY; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawBox(Xmid, Ymid - 1, Xmid + 32, Ymid + 1, Color.Orange); + } + else if (type == 0xB1BE0) // Globe + { + int mode = _api.MemLib.ReadS8(curObj + 0x15); + if (mode == 1) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); + _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xB1A10) // Approaching globes + { + Xmid = _api.MemLib.ReadS16(0xFFAA1A) - _camX; + Ymid = _api.MemLib.ReadS16(0xFFAA1E) - _camY; + DrawEccoOct(Xmid - 56, Ymid, 8, Color.Orange); + DrawEccoOct(Xmid + 56, Ymid, 8, Color.Orange); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xpos = _api.MemLib.ReadS32(curObj + 0x4C); + Ypos = _api.MemLib.ReadS32(curObj + 0x50); + Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos2 = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Ypos2 = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + Xpos >>= 16; Ypos >>= 16; + Xpos -= _camX; Ypos -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + } + else if (type == 0xB1920) // Orbiting globes + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xpos = _api.MemLib.ReadS16(curObj + 0x4C) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x50) - _camY; + Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + } + else if (type == 0xC28A0) // Control point in Four Islands/Dolphin that gives Rock-breaking song + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, _api.MemLib.ReadByte(curObj + 0x15) == 0 ? Color.Orange : Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + // Crystal Springs merging glyphs + else if (type == 0xC651E) // Bound glyph + { + Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + DrawEccoRhomb(Xpos, Ypos, 4 << 4, Color.Orange); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xC67E4) // Freed glyph + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xC6970) // Pulled glyph + { + uint subObj = _api.MemLib.ReadU24(curObj + 5); + Xvec = _api.MemLib.ReadS32(subObj + 0x54); + Yvec = _api.MemLib.ReadS32(subObj + 0x58); + for (i = 1; i < _api.MemLib.ReadByte(curObj + 0x7F); i++) + { + Xvec ^= Yvec; + Yvec ^= Xvec; + Xvec ^= Yvec; + Xvec = 0 - Xvec; + } + Xpos = (Xvec + _api.MemLib.ReadS32(subObj + 0x1C) >> 16) - _camX; + Ypos = (Yvec + _api.MemLib.ReadS32(subObj + 0x20) >> 16) - _camY; + DrawEccoRhomb(Xpos, Ypos, 3, Color.Orange); + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); + } + else if (type == 0xC6BA8) // Delivery Point + { + Xvec = _api.MemLib.ReadS32(curObj + 0x54); + Yvec = _api.MemLib.ReadS32(curObj + 0x58); + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + for (i = 0; i < 4; i++) + { + Xpos = (Xvec + _api.MemLib.ReadS32(curObj + 0x1C) >> 16) - _camX; + Ypos = (Yvec + _api.MemLib.ReadS32(curObj + 0x20) >> 16) - _camY; + _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + Xvec ^= Yvec; + Yvec ^= Xvec; + Xvec ^= Yvec; + Xvec = 0 - Xvec; + } + } + else if (type == 0xC6A6C) // Delivered glyph + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xC6F82) // Full delivery point + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawEccoOct(Xmid, Ymid, 3, Color.Orange); + } + else if (type == 0xC6A9E) // Merging glyph + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xC7052) { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS16(curObj + 0x24); + Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + uint dropSpeed = _api.MemLib.ReadU8(curObj + 0x16); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xmid, Ymid + (int)(dropSpeed), Color.Orange); + } + else if ((type == 0xD8B7C) || (type == 0xD89EA) || (type == 0x9E3AA) || (type == 0x9E5A8) // GFX particles don't need displayed. + || (type == 0x9B5D8) || (type == 0x9E2A6) || (type == 0xACD1E) || (type == 0xD9678) + || (type == 0xD9A3C) || (type == 0xD9240) || (type == 0x9E1DE) || (type == 0xDF86A) + || (type == 0xB159A) || (type == 0xDA898) || (type == 0xDA720) || (type == 0xD9FDC) + || (type == 0xC0D4E) || (type == 0xC0D38) || (type == 0xDCDAC) || (type == 0xC0B42) + || (type == 0xE3CD2) || (type == 0xE385E) || (type == 0xC20E8) || (type == 0xC22A6) + || (type == 0xC31B4) || (type == 0xA9EF0) || (type == 0xA9D90) || (type == 0xC6304) + || (type == 0xC26E4) || (type == 0xAEE68) || (type == 0xD9B2A) || (type == 0xD95AE) + || (type == 0)) + { + // This space intentionally left blank + } + else if ((type == 0xC152C) || (type == 0xA75E8) //Objects with default bounds confirmed + || (type == 0x9D076) || (type == 0xA7092) || (type == 0xC02EA) || (type == 0xA5378) + || (type == 0xACA7E) || (type == 0x9D28C) || (type == 0xA2D42) || (type == 0xA975E) + || (type == 0xBE9C8) || (type == 0xBFDA4) || (type == 0xAC736) || (type == 0xB716E) + || (type == 0xB1BE0) || (type == 0xB1A10) || (type == 0x9E546) || (type == 0xC2CB8) + || (type == 0xA0F04) || (type == 0xA6ACA) || (type == 0xA35A6) || (type == 0xAA12E) + || (type == 0xC651E) || (type == 0x9CC06) || (type == 0xA9202) || (type == 0xA6FDE) + || (type == 0xA6F62) || (type == 0xA745C) || (type == 0xC3EF0) || (type == 0xC3F90) + || (type == 0xC3FFC) || (type == 0xC3DB8) || (type == 0xAC766) || (type == 0xC5F66) + || (type == 0xA306E) || (type == 0xB0C7E) || (type == 0xB17F2) || (type == 0xB0CDC) + || (type == 0xC2106) || (type == 0xC208C) || (type == 0xC1EBA) || (type == 0xC251C) + || (type == 0xC32C8) || (type == 0xAB5E6) || (type == 0xAC796) || (type == 0xAC9F2) + || (type == 0xA538A)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(255, 0, 127)); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); + if (type != 0xA975E) + { + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + if (HP > 2) + { + PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); + } + } + else // Default bounds + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + PutText(type.ToString("X5"), Xmid, Ymid + 8, 1, 9, -1, -1, Color.Blue, Color.Red); + } + break; } - else if ((type == 0x9F5B0) || (type == 0xA3B18)) - { - Xpos = _api.MemLib.ReadS16(curObj + 0x24); - Ypos = _api.MemLib.ReadS16(curObj + 0x28); - Xpos -= _camX; - Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(curObj + 0x44), Color.Lime); - } - else if (type == 0xDCEE0) - { - Xpos = _api.MemLib.ReadS16(curObj + 0x24); - Ypos = _api.MemLib.ReadS16(curObj + 0x28); - Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, 0x5C, Color.Lime); - } - else - { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS16(curObj + 0x24); - Ymid = _api.MemLib.ReadS16(curObj + 0x28); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - if ((type == 0xA6C4A) || (type == 0xC43D4)) DrawEccoOct(Xmid, Ymid, 70, Color.Lime); - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - } - break; - } case Modes.Ecco1: type = _api.MemLib.ReadU32(curObj + 0x6); Xpos = _api.MemLib.ReadS16(curObj + 0x17); @@ -544,26 +2442,51 @@ namespace BizHawk.Client.EmuHawk Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - break; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + PutText(type.ToString("X8"), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); + break; } - Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(0, Ymid-5), 424), Color.Blue); - Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(2, Ymid-3), 426), Color.Blue); - Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(0, Xmid-16), 605), Math.Min(Math.Max(2, Ymid-3), 426), Color.Blue); - Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(2, Xmid-14), 607), Math.Min(Math.Max(0, Ymid-5), 424), Color.Blue); - Print_Text(type.ToString("X8"), 8, Math.Min(Math.Max(1, Xmid-15), 606), Math.Min(Math.Max(1, Ymid-4), 425), Color.Red); curObj = _api.MemLib.ReadU24(curObj+1); } //events curObj = _api.MemLib.ReadU24(0xFFCFB5); while (curObj != 0) { - uint type = _api.MemLib.ReadU32(curObj + 0xC); - if ((type == 0xA44EE) || (type == 0xD120C)) + type = _api.MemLib.ReadU32(curObj + 0xC); + if ((type == 0) // Null object + || (type == 0x9C1FA) || (type == 0x9C6D0) // Skytubes BG Image manager + || (type == 0x9ED72) || (type == 0xA57F2) // And Miscellaneous GFX particles + || (type == 0xC3A42) || (type == 0xB33D8) // And Cutscene controller + || (type == 0xB308A) || (type == 0xA1676) || (type == 0xB6822) || (type == 0xD12E2)) { } + else if ((type == 0xA44EE) || (type == 0xD120C)) { Xmid = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; Ymid = _api.MemLib.ReadS16(curObj + 0x20) - _camY; - DrawEccoOct(Xmid, Ymid, 0x20, Color.Cyan); + DrawEccoOct(Xmid, Ymid, 0x20, Color.Red); + } + else if (type == 0x9F0D0) // Water Current + { + int Xvec = _api.MemLib.ReadS32(curObj + 0x54); + int Yvec = _api.MemLib.ReadS32(curObj + 0x58); + if ((Xvec != 0) || (Yvec != 0)) + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xvec += Xmid; Yvec += Ymid; + Xmid >>= 16; Ymid >>= 16; + Xvec >>= 16; Yvec >>= 16; + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + Xvec -= _camX; Yvec -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Red)); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } } else if (type == 0xDEF94) { @@ -571,9 +2494,179 @@ namespace BizHawk.Client.EmuHawk Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; DrawEccoOct(Xmid, Ymid, 0x18, Color.Cyan); } - else + else if (type == 0xA6584) // Eagle { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawEccoOct(Xmid, Ymid, 0x10, Color.Red); + } + else if ((type == 0x9BA8A) // Autoscroller controller + || (type == 0xE27D4) || (type == 0xE270E) || (type == 0xE26C2)) + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + var Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + var Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0x9B948) // Autoscroller waypoint + { + Xmid = _api.MemLib.ReadS32(curObj + 0x24); + Ymid = _api.MemLib.ReadS32(curObj + 0x28); + var Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; + var Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; + DrawBoxMWH(Xmid, Ymid, 8, 8, Color.Orange); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + } + else if (type == 0xA5448) // Bomb spawner + { + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + PutText($"{_api.MemLib.ReadU16(curObj + 0x6E)}", Xmid, Ymid, 1, 1, -1, -1, Color.White, Color.Blue); + } + else if ((type == 0xA529C) || (type == 0xA5236) || (type == 0xA51E6)) // Explosion + { + uint subObj = _api.MemLib.ReadU24(curObj + 5); + if (subObj != 0) + { + Xpos = _api.MemLib.ReadS16(subObj + 0x1C) - _camX; + Ypos = _api.MemLib.ReadS16(subObj + 0x28) - _camY; + int Width = _api.MemLib.ReadS16(subObj + 0x24) - Xpos - _camX; + DrawBoxMWH(Xpos, Ypos, Width, 16, Color.Red); + } + subObj = _api.MemLib.ReadU24(curObj + 9); + if (subObj != 0) + { + Xpos = _api.MemLib.ReadS16(subObj + 0x1C) - _camX; + Ypos = _api.MemLib.ReadS16(subObj + 0x28) - _camY; + int Width = _api.MemLib.ReadS16(subObj + 0x24) - Xpos - _camX; + DrawBoxMWH(Xpos, Ypos, Width, 16, Color.Red); + } + } + else if (type == 0x9B5D8) + { + var subtype = _api.MemLib.ReadByte(curObj + 0x13); + int width = 0; + int height = 0; + switch (subtype) + { + case 48: + case 49: + case 126: + case 145: + case 146: + case 213: + PutText($"{type:X5}:{subtype}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); + PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); + break; + case 59: + case 87: + case 181: + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + width = _api.MemLib.ReadS16(curObj + 0x44); + height = _api.MemLib.ReadS16(curObj + 0x48); + DrawEccoOct(Xmid, Ymid, (width + height) >> 1, Color.Lime); + break; + case 71: + case 72: + case 158: + case 159: + case 165: + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); + break; + case 82: + case 83: + case 84: + case 85: + case 86: + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + width = _api.MemLib.ReadS16(curObj + 0x44); + height = _api.MemLib.ReadS16(curObj + 0x48); + DrawBoxMWH(Xmid, Ymid, width, height, Color.Red); + break; + case 210: + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + width = _api.MemLib.ReadS16(curObj + 0x44); + height = _api.MemLib.ReadS16(curObj + 0x48); + DrawBoxMWH(Xmid, Ymid, width, height, Color.Blue); + break; + case 107: + Xmid = (_api.MemLib.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; + Ymid = (_api.MemLib.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; + Xpos = (_api.MemLib.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; + Ypos = (_api.MemLib.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; + DrawBoxMWH(Xmid, Ymid, 64, 64, Color.Orange, 0); + DrawBoxMWH(Xpos, Ypos, 64, 64, Color.Orange, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + break; + case 110: //Gravity conrol points + case 179: + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63,_api.MemLib.ReadByte(curObj + 0x15) == 0 ? Color.Gray : Color.Red)); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); + int dir = _api.MemLib.ReadS8(curObj + 0x71) & 7; + int[] xtable = { 7, 4, -3, -10, -14, -11, -3, 4}; + int[] ytable = { 11, 4, 7, 4, -3, -11, -14, -11}; + Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; + Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawImage(".\\dll\\gravitometer_bg.png", Xmid - 15, Ymid - 15); + _api.GUILib.DrawImage(".\\dll\\gravitometer_fg.png", Xmid + xtable[dir], Ymid + ytable[dir]); + break; + case 176: + Xmid = (_api.MemLib.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; + Ymid = (_api.MemLib.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; + Xpos = (_api.MemLib.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; + Ypos = (_api.MemLib.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; + DrawEccoOct(Xmid, Ymid, 32, Color.Orange, 0); + DrawEccoOct(Xpos, Ypos, 32, Color.Orange, 0); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + break; + case 194: // Kill plane + Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; + Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Black, 127); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); + break; + default: + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); + Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); + Ypos = _api.MemLib.ReadS16(curObj + 0x30); + Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xmid = _api.MemLib.ReadS16(curObj + 0x24); + Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos -= _camX; Xpos2 -= _camX; + Ypos -= _camY; Ypos2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); + PutText($"{type:X5}:{subtype}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); + PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); + break; + } + } + else + { + Xpos = _api.MemLib.ReadS16(curObj + 0x2C); Xpos2= _api.MemLib.ReadS16(curObj + 0x34); Ypos = _api.MemLib.ReadS16(curObj + 0x30); Ypos2= _api.MemLib.ReadS16(curObj + 0x38); @@ -582,93 +2675,117 @@ namespace BizHawk.Client.EmuHawk Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); - } - PutText(type.ToString("X8"), Xmid, Ymid, 1, 1, 0, 0, Color.White, Color.Blue); - PutText(curObj.ToString("X8"), Xmid, Ymid, 1, 9, 0, 0, Color.White, Color.Blue); - curObj = _api.MemLib.ReadU24(curObj+1); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); + PutText($"{type:X5}:{_api.MemLib.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); + PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); + } + curObj = _api.MemLib.ReadU24(curObj+1); } - //Ecco body - Xpos = _api.MemLib.ReadS16(0xFFAA22); - Ypos = _api.MemLib.ReadS16(0xFFAA26); - Xpos2 = _api.MemLib.ReadS16(0xFFAA2A); - Ypos2 = _api.MemLib.ReadS16(0xFFAA2E); - Xmid = _api.MemLib.ReadS16(0xFFAA1A); - Ymid = _api.MemLib.ReadS16(0xFFAA1E); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - X = Xpos; - X2 = Xpos2; - Y = Ypos; - Y2 = Ypos2; - int X3 = (Xmid + (ushort) Xpos) >> 1; - int X4 = (Xmid + (ushort) Xpos2) >> 1; - int Y3 = (Ymid + (ushort) Ypos) >> 1; - int Y4 = (Ymid + (ushort) Ypos2) >> 1; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Magenta); - DrawBoxMWH(X, Y, 1, 1, Color.Magenta); - DrawBoxMWH(X2, Y2, 1, 1, Color.Magenta); - DrawBoxMWH(X3, Y3, 1, 1, Color.Magenta); - DrawBoxMWH(X4, Y4, 1, 1, Color.Magenta); - _api.GUILib.DrawPixel(Xmid, Ymid, Color.Blue); - _api.GUILib.DrawPixel(X, Y, Color.Blue); - _api.GUILib.DrawPixel(X2, Y2, Color.Blue); - _api.GUILib.DrawPixel(X3, Y3, Color.Blue); - _api.GUILib.DrawPixel(X4, Y4, Color.Blue); - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); //Ecco head Xpos = _api.MemLib.ReadS16(0xFFA8F8); Xpos2 = _api.MemLib.ReadS16(0xFFA900); Ypos = _api.MemLib.ReadS16(0xFFA8FC); Ypos2 = _api.MemLib.ReadS16(0xFFA904); + Xmid = _api.MemLib.ReadS16(0xFFA8F0); + Ymid = _api.MemLib.ReadS16(0xFFA8F4); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.White); + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.PowderBlue, 0); //Ecco tail Xpos = _api.MemLib.ReadS16(0xFFA978); Xpos2 = _api.MemLib.ReadS16(0xFFA980); Ypos = _api.MemLib.ReadS16(0xFFA97C); Ypos2 = _api.MemLib.ReadS16(0xFFA984); + Xmid = _api.MemLib.ReadS16(0xFFA970); + Ymid = _api.MemLib.ReadS16(0xFFA974); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; - _api.GUILib.DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.White); + Xmid -= _camX; Ymid -= _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.PowderBlue, 0); + //Ecco body + Xpos = _api.MemLib.ReadS32(0xFFAA22); + Ypos = _api.MemLib.ReadS32(0xFFAA26); + Xpos2 = _api.MemLib.ReadS32(0xFFAA2A); + Ypos2 = _api.MemLib.ReadS32(0xFFAA2E); + Xmid = _api.MemLib.ReadS16(0xFFAA1A); + Ymid = _api.MemLib.ReadS16(0xFFAA1E); + int Xvel = _api.MemLib.ReadS32(0xFFAA36); + if (_api.MemLib.ReadU32(0xFFA9D6) > 7) Xvel += _api.MemLib.ReadS32(0xFFA9D6); + if (_api.MemLib.ReadU32(0xFFAA3E) > 7) Xvel += _api.MemLib.ReadS32(0xFFAA3E); + int Yvel = _api.MemLib.ReadS32(0xFFAA3A); + if (_api.MemLib.ReadU32(0xFFA9DA) > 7) Yvel += _api.MemLib.ReadS32(0xFFA9DA); + if (_api.MemLib.ReadU32(0xFFAA42) > 7) Yvel += _api.MemLib.ReadS32(0xFFAA42); + int XV = ((Xpos + Xvel) >> 16) - _camX; + int YV = ((Ypos + Yvel) >> 16) - _camY; + int XV2 = ((Xpos2 + Xvel) >> 16) - _camX; + int YV2 = ((Ypos2 + Yvel) >> 16) - _camY; + X = Xpos >> 16; + X2 = Xpos2 >> 16; + Y = Ypos >> 16; + Y2 = Ypos2 >> 16; + X -= _camX; X2 -= _camX; + Y -= _camY; Y2 -= _camY; + Xmid -= _camX; Ymid -= _camY; + int X3 = (Xmid + X) >> 1; + int X4 = (Xmid + X2) >> 1; + int Y3 = (Ymid + Y) >> 1; + int Y4 = (Ymid + Y2) >> 1; + _api.GUILib.DrawLine(X, Y, Xmid, Ymid, Color.Green); + _api.GUILib.DrawLine(Xmid, Ymid, X2, Y2, Color.Green); + DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Red); + DrawBoxMWH(X, Y, 1, 1, Color.Lime); + DrawBoxMWH(X2, Y2, 1, 1, Color.Blue); + DrawBoxMWH(X3, Y3, 1, 1, Color.Yellow); + DrawBoxMWH(X4, Y4, 1, 1, Color.Yellow); + _api.GUILib.DrawLine(X, Y, XV, YV, Color.Orange); + _api.GUILib.DrawLine(X2, Y2, XV2, YV2, Color.Orange); // sonar if (_api.MemLib.ReadU8(0xFFAB77) != 0) { - Xmid = _api.MemLib.ReadS16(0xFFA9EC); + Xmid = _api.MemLib.ReadS32(0xFFA9EC); + Ymid = _api.MemLib.ReadS32(0xFFA9F0); + int Xvec = ((_api.MemLib.ReadS32(0xFFAA04) + Xmid) >> 16) - _camX; + int Yvec = ((_api.MemLib.ReadS32(0xFFAA08) + Ymid) >> 16) - _camY; + Xmid >>= 16; + Ymid >>= 16; + Xmid -= _camX; Ymid -= _camY; Width2 = _api.MemLib.ReadS16(0xFFA9FC); - Xmid -= _camX; - Ymid = _api.MemLib.ReadS16(0xFFA9F0); - Ymid -= _camY; Height2 = _api.MemLib.ReadS16(0xFFAA00); color = ((_api.MemLib.ReadU8(0xFFAA0C) != 0) ? Color.FromArgb(255, 0, 127) : Color.FromArgb(0, 0, 255)); DrawBoxMWH(Xmid, Ymid, Width2, Height2, color); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue); - _api.GUILib.DrawPixel(Xmid, Ymid, color); + DrawBoxMWH(Xmid, Ymid, 1, 1, color, 0); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } //Pulsar curObj = _api.MemLib.ReadU24(0xFFCFD1); - if (curObj != 0) + if ((curObj != 0) && ((_api.MemLib.ReadU32(curObj + 0xC) == 0xC9222) || (_api.MemLib.ReadU32(curObj + 0xC) == 0xC9456))) { - // sbyte Blah = _api.MemLib.ReadU8(CardBoard + 0x15); curObj += 0x26; - // if (!(Blah & 1)) - // CardBoard += 0x14; for (int l = 0; l < 4; l++) { if (_api.MemLib.ReadU16(curObj + 0x12) != 0) { - Xmid = _api.MemLib.ReadS16(curObj); - Ymid = _api.MemLib.ReadS16(curObj + 4); + Xmid = _api.MemLib.ReadS32(curObj); + Ymid = _api.MemLib.ReadS32(curObj + 4); + int Xvec = (Xmid + _api.MemLib.ReadS32(curObj + 8) >> 16) - _camX; + int Yvec = (Ymid + _api.MemLib.ReadS32(curObj + 0xC) >> 16) - _camY; + Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 0x30, 0x30, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue); - _api.GUILib.DrawPixel(Xmid, Ymid, Color.Red); + _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } curObj += 0x14; } } + + //Water Level + int waterLevel = _api.MemLib.ReadS16(0xFFA7B2); + _api.GUILib.DrawLine(0, waterLevel - _camY, _left + 320 + _right, waterLevel - _camY, Color.Aqua); + } void EccoAutofire(bool on) @@ -678,27 +2795,28 @@ namespace BizHawk.Client.EmuHawk uint mode = _api.MemLib.ReadU8(0xFFA555); int frameCount = _api.EmuLib.FrameCount(); int lagCount = _api.EmuLib.LagCount(); + _api.JoypadLib.Set("Start", on, 1); switch (mode) { case 0x00: if (on) { if (_api.MemLib.ReadU16(0xFFF342) == 0xFFFD) - _api.JoypadLib.Set("C", false, 1); - else _api.JoypadLib.Set("C", true, 1); + else + _api.JoypadLib.Set("C", false, 1); } break; case 0xE6: if (_api.MemLib.ReadU16(0xFFD5E8) == 0x00000002) { Dictionary buttons = new Dictionary(); - buttons["B"] = !(buttons["C"] = false); + buttons["B"] = buttons["C"] = true; _api.JoypadLib.Set(buttons, 1); } else { Dictionary buttons = new Dictionary(); - buttons["B"] = !(buttons["C"] = true); + buttons["B"] = buttons["C"] = false; _api.JoypadLib.Set(buttons, 1); } break; @@ -706,28 +2824,25 @@ namespace BizHawk.Client.EmuHawk charge = _api.MemLib.ReadU8(0xFFB19B); if (on) { - if ((charge == 1) || (_prevCharge == 1) || !(_prevOn || (_api.MemLib.ReadU8(0xFFB19B) != 0))) + if ((charge <= 1) && ((_api.MemLib.ReadU8(0xFFB1A6) == 0) || (_api.MemLib.ReadU8(0xFFB1A9) != 0))) _api.JoypadLib.Set("B", true, 1); - else + else if (charge > 1) _api.JoypadLib.Set("B", false, 1); - if ((_api.MemLib.ReadU16(0xFFB168) == 0x3800) && ((_api.MemLib.ReadU16(0xFFA7C8) % 2) != 0)) - _api.EmuLib.SetIsLagged(true); - _api.JoypadLib.Set("C", (_api.MemLib.ReadU16(0xFFA7C8) % 2) != 0, 1); + _api.JoypadLib.Set("C", (_api.MemLib.ReadU16(0xFFA7C8) % 2) == 0, 1); } - _prevCharge = charge; break; case 0x20: case 0x28: case 0xAC: if (on) { - _api.JoypadLib.Set("C", (_api.MemLib.ReadS8(0xFFAA6E) >= 11), 1); + if ((_api.MemLib.ReadU8(0xFFAB72) & 3) == 0) + _api.JoypadLib.Set("C", (_api.MemLib.ReadS8(0xFFAA6E) < 11), 1); } break; default: break; } - _prevOn = on; } public override void Init(IPluginAPI api) { @@ -741,7 +2856,9 @@ namespace BizHawk.Client.EmuHawk _mode = Modes.Ecco2; _camXAddr = 0xFFAD9C; _camYAddr = 0xFFAD9E; - EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); + _top = _bottom = 112; + _left = _right = 160; + EmuHawkPluginLibrary.SetGameExtraPadding(_left, _top, _right, _bottom); } else if ((gameName == "ECCO The Dolphin (J) [!]") || (gameName == "ECCO The Dolphin (UE) [!]")) @@ -750,7 +2867,9 @@ namespace BizHawk.Client.EmuHawk _mode = Modes.Ecco1; _camXAddr = 0xFFB836; _camYAddr = 0xFFB834; - EmuHawkPluginLibrary.SetGameExtraPadding(160,112,160,112); + _top = _bottom = 112; + _left = _right = 160; + EmuHawkPluginLibrary.SetGameExtraPadding(_left, _top, _right, _bottom); } else { @@ -758,41 +2877,564 @@ namespace BizHawk.Client.EmuHawk Running = false; } } + private Color BackdropColor() + { + uint color = _api.MemLib.ReadU16(0, "CRAM"); + int r = (int)(( color & 0x7) * 0x22); + int g = (int)(((color >> 3) & 0x7) * 0x22); + int b = (int)(((color >> 6) & 0x7) * 0x22); + return Color.FromArgb(r, g, b); + + } public override void PreFrameCallback() { + _api.GUILib.ClearText(); if (_mode != Modes.disabled) { - EccoAutofire(_api.JoypadLib.Get(1)["C"] != _api.JoypadLib.GetImmediate()["P1 C"]); + _camX = _api.MemLib.ReadS16(_camXAddr) - _left; + _camY = _api.MemLib.ReadS16(_camYAddr) - _top; + EccoAutofire(_api.JoypadLib.Get(1)["Start"]); + if (_dumpMap == 0) + { + Color bg = BackdropColor(); + _api.GUILib.DrawRectangle(0, 0, _left + 320 + _right, _top, bg, bg); + _api.GUILib.DrawRectangle(0, 0, _left, _top + 224 + _bottom, bg, bg); + _api.GUILib.DrawRectangle(_left + 320, 0, _left + 320 + _right, _top + 224 + _bottom, bg, bg); + _api.GUILib.DrawRectangle(0, _top + 224, _left + 320 + _right, _top + 224 + _bottom, bg, bg); + } + uint mode = _api.MemLib.ReadByte(0xFFA555); + switch (mode) + { + case 0x20: + case 0x28: + case 0xAC: + //EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); + if (_dumpMap <= 1) EccoDrawBoxes(); + // Uncomment the following block to enable mapdumping + /*if ((_api.MemLib.ReadU16(0xFFA7C8) > 1) && (_api.MemLib.ReadU16(0xFFA7C8) < 4)) + { + _dumpMap = 1; + _rowStateGuid = string.Empty; + _top = _bottom = _left = _right = 0; + EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); + }*/ + if (_dumpMap == 3) + { + var levelID = _api.MemLib.ReadS8(0xFFA7D0); + int[] nameGroupLengths = + { + 7,1,11,6, + 4,3,3,3, + 7,1,2,1, + 0,0,0,0 + }; + int[] nameStringPtrOffsets = + { + 0xECBD0, 0x106BC0, 0x10AF8C, 0x135A48, + 0x1558E8, 0x15F700, 0x16537C, 0x180B00, + 0x193920, 0x1B3ECC, 0x1D7A44, 0x1DBF70, + 0x2DF2, 0x2DF6, 0x2DFA, 0x2DFE + }; + int nameGroup = 0; + var i = levelID; + while ((i >= 0) && (nameGroup < nameGroupLengths.Length)) + { + i -= nameGroupLengths[nameGroup]; + if (i >= 0) nameGroup++; + } + string name = "map"; + if (i < 0) + { + i += nameGroupLengths[nameGroup]; + uint strOffset = _api.MemLib.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); + Console.WriteLine($"{i}"); + strOffset = _api.MemLib.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); + strOffset += 0x20; + List strTmp = new List(); + byte c; + do + { + c = (byte)_api.MemLib.ReadByte(strOffset++); + if (c != 0) + strTmp.Add(c); + } while (c != 0); + name = System.Text.Encoding.ASCII.GetString(strTmp.ToArray()); + TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; + name = textInfo.ToTitleCase(name).Replace(" ", string.Empty); + } + EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_top.png"); + _destX = _destY = 0; + EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); + _dumpMap++; + } + if (_dumpMap == 6) + { + var levelID = _api.MemLib.ReadS8(0xFFA7D0); + int[] nameGroupLengths = + { + 7,1,11,6, + 4,3,3,3, + 7,1,2,1, + 0,0,0,0 + }; + int[] nameStringPtrOffsets = + { + 0xECBD0, 0x106BC0, 0x10AF8C, 0x135A48, + 0x1558E8, 0x15F700, 0x16537C, 0x180B00, + 0x193920, 0x1B3ECC, 0x1D7A44, 0x1DBF70, + 0x2DF2, 0x2DF6, 0x2DFA, 0x2DFE + }; + int nameGroup = 0; + var i = levelID; + while ((i >= 0) && (nameGroup < nameGroupLengths.Length)) + { + i -= nameGroupLengths[nameGroup]; + if (i >= 0) nameGroup++; + } + string name = "map"; + if (i < 0) + { + i += nameGroupLengths[nameGroup]; + uint strOffset = _api.MemLib.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); + Console.WriteLine($"{i}"); + strOffset = _api.MemLib.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); + strOffset += 0x20; + List strTmp = new List(); + byte c; + do + { + c = (byte)_api.MemLib.ReadByte(strOffset++); + if (c != 0) + strTmp.Add(c); + } while (c != 0); + name = System.Text.Encoding.ASCII.GetString(strTmp.ToArray()); + TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; + name = textInfo.ToTitleCase(name).Replace(" ", string.Empty); + } + EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_bottom.png"); + _destX = _destY = 0; + _left = _right = 160; + _top = _bottom = 112; + EmuHawkPluginLibrary.SetGameExtraPadding(_left, _top, _right, _bottom); + _dumpMap = 0; + } + break; + case 0xF6: + EccoDraw3D(); + break; + default: + break; + } + _prevF = _api.MemLib.ReadU32(0xFFA524); } } public override void PostFrameCallback() { uint frame = _api.MemLib.ReadU32(0xFFA524); + if ((frame <= _prevF) && !_api.EmuLib.IsLagged()) + { + _api.EmuLib.SetIsLagged(true); + _api.EmuLib.SetLagCount(_api.EmuLib.LagCount() + 1); + } uint mode = _api.MemLib.ReadByte(0xFFA555); - switch (mode) { + _tickerY = 81; + string valueTicker = $"{_api.MemLib.ReadU32(0xFFA520)}:{_api.MemLib.ReadU32(0xFFA524)}:{_api.MemLib.ReadU16(0xFFA7C8)}:{mode:X2}"; + TickerText(valueTicker); + switch (mode) + { case 0x20: case 0x28: case 0xAC: - EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); - EccoDrawBoxes(); + valueTicker = $"{_api.MemLib.ReadS16(0xFFAD9C)}:{_api.MemLib.ReadS16(0xFFAD9E)}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFAA1A) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFAA1E) / 65536.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFAA32) / 65536.0:0.######}:{_api.MemLib.ReadU8(0xFFAA6D)}:{_api.MemLib.ReadU8(0xFFAA6E)}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFAA36) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFAA3A) / 65536.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFA9D6) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFA9DA) / 65536.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFAA3E) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFAA42) / 65536.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{(_api.MemLib.ReadS32(0xFFAA36) + _api.MemLib.ReadS32(0xFFA9D6) + _api.MemLib.ReadS32(0xFFAA3E)) / 65536.0:0.######}:" + + $"{(_api.MemLib.ReadS32(0xFFAA3A) + _api.MemLib.ReadS32(0xFFA9DA) + _api.MemLib.ReadS32(0xFFAA42)) / 65536.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadU8(0xFFAB72)}:{_api.MemLib.ReadU8(0xFFAB70)}:{(short)_api.MemLib.ReadS16(0xFFAA52):X4}:{(short)_api.MemLib.ReadS16(0xFFAA5A):X4}"; + TickerText(valueTicker); + switch (_api.MemLib.ReadU8(0xFFA7D0)) + { + case 1: + case 2: + case 3: + case 30: + case 46: + var globeFlags = _api.MemLib.ReadU32(0xFFD434) >> 1; + var globeFlags2 = _api.MemLib.ReadU32(0xFFD438) >> 1; + int i, j = i = 0; + while (globeFlags > 0) + { + globeFlags >>= 1; + i++; + } + while (globeFlags2 > 0) + { + globeFlags2 >>= 1; + j++; + } + TickerText($"{i}:{j}", Color.Blue); + break; + default: + break; + } + if (_dumpMap != 0) + { + _api.MemLib.WriteS16(0xFFAA16, 7); + _api.MemLib.WriteS16(0xFFAA18, 56); + int PlayerX = _api.MemLib.ReadS16(0xFFAA1A) - _camX; + int PlayerY = _api.MemLib.ReadS16(0xFFAA1E) - _camY; + if ((PlayerX < -64) || (PlayerX > 384) || (PlayerY < -64) || (PlayerY > 288)) + { + _api.MemLib.WriteByte(0xFFAA70, 0xC); + _api.MemLib.WriteS16(0xFFA7CA, 1); + } + else + { + _api.MemLib.WriteByte(0xFFAA70, 0x0); + _api.MemLib.WriteS16(0xFFA7CA, 0); + } + } + if (_dumpMap == 1) + { + int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); + int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); + var levelID = _api.MemLib.ReadByte(0xFFA7D0); + var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + s.DrawBGA = false; + s.DrawBGB = false; + s.DrawBGW = false; + s.DrawObj = false; + s.Backdrop = true; + _api.EmuLib.PutSettings(s); + if ((_camX == _destX) && (_camY == _destY)) + { + if ((_prevX != _camX) || (_prevY != _camY)) + { + if (_destX == 0) + { + if (_rowStateGuid != string.Empty) + { + _api.MemStateLib.DeleteState(_rowStateGuid); + } + _rowStateGuid = _api.MemStateLib.SaveCoreStateToMemory(); + } + _snapPast = 1; + } + else + { + _snapPast--; + } + if (_snapPast == 0) + { + EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_top.png"); + if (_destX >= levelWidth - 320) + { + if (_destY < levelHeight - 224) + { + if (_rowStateGuid != string.Empty) + { + _api.MemStateLib.LoadCoreStateFromMemory(_rowStateGuid); + } + _destX = 0; + _destY = Math.Min(_destY + 111, levelHeight - 224); + } + } + else + _destX = Math.Min(_destX + 159, levelWidth - 320); + if ((_prevX == _destX) && (_prevY == _destY)) + { + EmuHawkPluginLibrary.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); + _dumpMap++; + } + } + } + _api.MemLib.WriteS16(0xFFAD8C, _destX); + _api.MemLib.WriteS16(0xFFAD90, _destY); + } + else if (_dumpMap == 2) + { + if (_rowStateGuid != String.Empty) + _api.MemStateLib.DeleteState(_rowStateGuid); + _rowStateGuid = String.Empty; + int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); + int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); + EmuHawkPluginLibrary.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); + var levelID = _api.MemLib.ReadS8(0xFFA7D0); + var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + s.DrawBGA = false; + s.DrawBGB = false; + s.DrawBGW = false; + s.DrawObj = false; + s.Backdrop = true; + _api.EmuLib.PutSettings(s); + + var a = _api.GUILib.GetAttributes(); + a.SetColorKey(Color.FromArgb(0, 0x11, 0x22, 0x33), Color.FromArgb(0, 0x11, 0x22, 0x33)); + _api.GUILib.SetAttributes(a); + _api.GUILib.ToggleCompositingMode(); + + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_top.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); + for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) + { + var dx = (x == 0) ? 0 : 2; + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_top.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); + } + for (int y = ((levelHeight - 224) / 111) * 111; y >= 0; y -= 111) + { + var dy = (y == 0) ? 0 : 2; + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_top.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); + for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) + { + var dx = (x == 0) ? 0 : 2; + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_top.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); + } + } + + _api.GUILib.ToggleCompositingMode(); + _api.GUILib.SetAttributes(new System.Drawing.Imaging.ImageAttributes()); + _api.GUILib.DrawFinish(); + _dumpMap++; + } + else if (_dumpMap == 4) + { + int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); + int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); + var levelID = _api.MemLib.ReadByte(0xFFA7D0); + var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + s.DrawBGA = (levelID != 29); + s.DrawBGB = (levelID == 7); + s.DrawBGW = true; + s.DrawObj = true; + s.Backdrop = false; + _api.EmuLib.PutSettings(s); + if ((_camX == _destX) && (_camY == _destY)) + { + if ((_prevX != _camX) || (_prevY != _camY)) + { + if (_destX == 0) + { + if (_rowStateGuid != string.Empty) + { + _api.MemStateLib.DeleteState(_rowStateGuid); + } + _rowStateGuid = _api.MemStateLib.SaveCoreStateToMemory(); + } + _snapPast = 1; + } + else + { + _snapPast--; + } + if (_snapPast == 0) + { + EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_bottom.png"); + if (_destX >= levelWidth - 320) + { + if (_destY < levelHeight - 224) + { + if (_rowStateGuid != string.Empty) + { + _api.MemStateLib.LoadCoreStateFromMemory(_rowStateGuid); + } + _destX = 0; + _destY = Math.Min(_destY + 111, levelHeight - 224); + } + } + else + _destX = Math.Min(_destX + 159, levelWidth - 320); + if ((_prevX == _destX) && (_prevY == _destY)) + { + EmuHawkPluginLibrary.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); + _dumpMap++; + } + } + } + _api.MemLib.WriteS16(0xFFAD8C, _destX); + _api.MemLib.WriteS16(0xFFAD90, _destY); + } + else if (_dumpMap == 5) + { + if (_rowStateGuid != String.Empty) + _api.MemStateLib.DeleteState(_rowStateGuid); + _rowStateGuid = String.Empty; + int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); + int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); + var levelID = _api.MemLib.ReadS8(0xFFA7D0); + var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + s.DrawBGA = (levelID != 29); + s.DrawBGB = (levelID == 7); + s.DrawBGW = true; + s.DrawObj = true; + s.Backdrop = false; + _api.EmuLib.PutSettings(s); + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_bottom.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); + for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) + { + var dx = (x == 0) ? 0 : 2; + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_bottom.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); + } + for (int y = ((levelHeight - 224) / 111) * 111; y >= 0; y -= 111) + { + var dy = (y == 0) ? 0 : 2; + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_bottom.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); + for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) + { + var dx = (x == 0) ? 0 : 2; + _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_bottom.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); + } + } + _api.GUILib.DrawFinish(); + _dumpMap++; + } + _prevX = _camX; + _prevY = _camY; break; case 0xF6: - EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); - EccoDraw3D(); + valueTicker = $"{_api.MemLib.ReadS32(0xFFD5E0) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFD5E8) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFD5E4) / 2048.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFB13A) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB142) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB13E) / 2048.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadS32(0xFFB162) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB16A) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB166) / 2048.0:0.######}"; + TickerText(valueTicker); + valueTicker = $"{_api.MemLib.ReadU8(0xFFB19B)}:{_api.MemLib.ReadU8(0xFFB1A6)}:{_api.MemLib.ReadU8(0xFFB1A9)}"; + TickerText(valueTicker); + int SpawnZ = _api.MemLib.ReadS32(0xFFD5F0) + 0x180000; + int nextRingZ = SpawnZ; + while (((nextRingZ >> 17) & 0xF) != 0) + { + nextRingZ += 0x20000; + } + valueTicker = $"{_api.MemLib.ReadS32(0xFFD856) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFD85A) / 4096.0:0.######}:{(nextRingZ - 0x160000) / 2048.0:0.######}:{nextRingZ / 2048.0:0.######}"; + TickerText(valueTicker); + var levelId = -1 - _api.MemLib.ReadS16(0xFFA79E); + bool spawn = false; + bool firstRand = true; + int SpawnX, SpawnY, z; + int CamX = (_api.MemLib.ReadS32(0xFFD5E0) >> 0xC) - _left; + int CamY = (_api.MemLib.ReadS32(0xFFD5E8) >> 0xC) + _top; + int CamZ = (_api.MemLib.ReadS32(0xFFD5E4) >> 0xC) + _top; + while (!spawn) + { + var temp = (SpawnZ >> 17) & 0xFF; + var controlList = _api.MemLib.ReadS32(0x7B54 + (levelId << 2)); + temp = _api.MemLib.ReadS16(controlList + (temp << 1)); + var v = temp & 0xFF; + var num = (temp >> 8) + v; + temp = v; + spawn = (num > 2); + if (spawn) for (; temp < num; temp++) + { + switch (temp) + { + case 0: + case 1: + case 13: + // Nothing important spawns + break; + case 2: + // Jellyfish + SpawnX = _api.MemLib.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); + firstRand = false; + SpawnY = -0xC0000 + (EccoRand() << 3); + z = SpawnZ + 0x20000;// ? + valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; + TickerText(valueTicker); + SpawnX = 160 + ((SpawnX >> 0xC) - CamX); + SpawnY = 112 - ((SpawnY >> 0xC) - CamY); + z = _top + 112 - ((z >> 0xC) - CamZ); + DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); + DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); + break; + case 3: + // Eagle + SpawnX = _api.MemLib.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); + firstRand = false; + SpawnY = 0x50000; + z = SpawnZ - 0x40000 + 0x20000;// ? + valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; + TickerText(valueTicker); + SpawnX = 160 + ((SpawnX >> 0xC) - CamX); + SpawnY = 112 - ((SpawnY >> 0xC) - CamY); + z = _top + 112 - ((z >> 0xC) - CamZ); + DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); + DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); + break; + case 4: + // Shark + bool left = (EccoRand(firstRand) > 0x8000); + firstRand = false; + var xdiff = 0xC0000 + (EccoRand() << 3); + SpawnX = _api.MemLib.ReadS32(0xFFB13A) + (left ? -xdiff : xdiff); + SpawnY = Math.Min(_api.MemLib.ReadS32(0xFFB142), -0x10000) - (EccoRand() + 0x10000); + z = SpawnZ + 0x20000; + valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; + TickerText(valueTicker); + SpawnX = 160 + ((SpawnX >> 0xC) - CamX); + SpawnY = 112 - ((SpawnY >> 0xC) - CamY); + z = _top + 112 - ((z >> 0xC) - CamZ); + DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); + DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); + break; + case 5: + case 6: + case 7: + case 8: + // Vine + EccoRand(firstRand); + firstRand = false; + if ((temp & 1) == 1) EccoRand(); + EccoRand(); + break; + case 9: + case 10: + case 11: + case 12: + // Unknown, possibly just rand incrementation? + EccoRand(firstRand); + firstRand = false; + if ((temp & 1) == 1) EccoRand(); + break; + case 14: + // Shell + SpawnX = _api.MemLib.ReadS32(0xFFB13A) - 0x20000 + (EccoRand(firstRand) << 2); + firstRand = false; + SpawnY = -0x80000; + z = SpawnZ + 0x20000; + EccoRand(); + valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{(z - 0x80000) / 2048.0:0.######}"; + TickerText(valueTicker); + SpawnX = 160 + ((SpawnX >> 0xC) - CamX); + SpawnY = 112 - ((SpawnY >> 0xC) - CamY); + z = _top + 112 - ((z >> 0xC) - CamZ); + DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); + DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); + break; + } + } + SpawnZ += 0x20000; + } break; - default: - EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); - break; } - _camX = _api.MemLib.ReadS16(_camXAddr)-160; - _camY = _api.MemLib.ReadS16(_camYAddr)-112; - if (frame <= _prevF) - _api.EmuLib.SetIsLagged(true); - _prevF = frame; + _api.JoypadLib.Set("C", null, 1); + _api.JoypadLib.Set("Start", null, 1); + var color = _turnSignalColors[_api.MemLib.ReadS8(0xFFA7C9) & 7]; + _api.GUILib.DrawRectangle(_left - 48, _top - 112, 15, 15, color, color); } public override void LoadStateCallback(string name) { - _prevF = _api.MemLib.ReadU32(0xFFA524); + _api.GUILib.DrawNew("emu"); + PreFrameCallback(); + _api.GUILib.DrawFinish(); } } } From 59f30b4a79a0bc904cea91d06d43696cf768df58 Mon Sep 17 00:00:00 2001 From: upthorn Date: Wed, 5 Dec 2018 12:07:10 -0800 Subject: [PATCH 08/22] Allow signed display of fixed point values. --- BizHawk.Client.Common/tools/Watch/DWordWatch.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BizHawk.Client.Common/tools/Watch/DWordWatch.cs b/BizHawk.Client.Common/tools/Watch/DWordWatch.cs index 1e8c41f055..79a9ef03aa 100644 --- a/BizHawk.Client.Common/tools/Watch/DWordWatch.cs +++ b/BizHawk.Client.Common/tools/Watch/DWordWatch.cs @@ -217,9 +217,9 @@ namespace BizHawk.Client.Common case DisplayType.Hex: return val.ToHexString(8); case DisplayType.FixedPoint_20_12: - return $"{val / 4096.0:0.######}"; + return $"{(int)val / 4096.0:0.######}"; case DisplayType.FixedPoint_16_16: - return $"{val / 65536.0:0.######}"; + return $"{(int)val / 65536.0:0.######}"; case DisplayType.Float: var bytes = BitConverter.GetBytes(val); var _float = BitConverter.ToSingle(bytes, 0); From c50267fe96c66358c55069f19648f45eaf4db8a8 Mon Sep 17 00:00:00 2001 From: upthorn Date: Wed, 5 Dec 2018 12:07:53 -0800 Subject: [PATCH 09/22] GPGX trace no longer crashes when executing from M68K RAM. --- BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs index b6f867ace4..dfddf14bc7 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx64/GPGX.ITraceable.cs @@ -24,7 +24,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx var regs = DebuggableCore.GetCpuFlagsAndRegisters(); uint pc = (uint)regs["M68K PC"].Value; var length = 0; - var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc, out length); + var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc & 0xFFFFFF, out length); var traceInfo = new TraceInfo { From b343a19acc2e8d7a60388b26bf1d089f9a9e9abb Mon Sep 17 00:00:00 2001 From: upthorn Date: Thu, 20 Dec 2018 17:32:49 -0800 Subject: [PATCH 10/22] Commented out extraneous member. --- BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs index 258cd128e3..132ba4a2df 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs +++ b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs @@ -55,8 +55,8 @@ namespace BizHawk.Client.EmuHawk } // private FormsPluginLibrary FormsLibrary => (FormsLuaLibrary)Libraries[typeof(FormsLuaLibrary)]; - private EmulatorPluginLibrary EmulatorLuaLibrary => (EmulatorPluginLibrary)Libraries[typeof(EmulatorPluginLibrary)]; - public GUIPluginLibrary GuiLibrary => (GUIPluginLibrary)Libraries[typeof(GUIPluginLibrary)]; +// private EmulatorPluginLibrary EmuPluginLibrary => (EmulatorPluginLibrary)Libraries[typeof(EmulatorPluginLibrary)]; + private GUIPluginLibrary GuiLibrary => (GUIPluginLibrary)Libraries[typeof(GUIPluginLibrary)]; public void Restart(IEmulatorServiceProvider newServiceProvider) { From d3cb19e56b6ea4234da0c411e68934bf5e5ba82e Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 21 Dec 2018 22:35:38 -0800 Subject: [PATCH 11/22] Uncomment mapdumping code. --- .../Plugins/Example/Ecco2AssistantPlugin.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs b/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs index 75a58dcd79..e7ed248bfb 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs +++ b/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs @@ -2911,13 +2911,13 @@ namespace BizHawk.Client.EmuHawk //EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); if (_dumpMap <= 1) EccoDrawBoxes(); // Uncomment the following block to enable mapdumping - /*if ((_api.MemLib.ReadU16(0xFFA7C8) > 1) && (_api.MemLib.ReadU16(0xFFA7C8) < 4)) + if ((_api.MemLib.ReadU16(0xFFA7C8) > 1) && (_api.MemLib.ReadU16(0xFFA7C8) < 4)) { _dumpMap = 1; _rowStateGuid = string.Empty; _top = _bottom = _left = _right = 0; EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); - }*/ + } if (_dumpMap == 3) { var levelID = _api.MemLib.ReadS8(0xFFA7D0); From 8395193aee982cf968654ce4b4f0b81d04b09110 Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 21 Dec 2018 22:38:03 -0800 Subject: [PATCH 12/22] Allow alpha to matter in screenshots. --- Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs | 2 +- Bizware/BizHawk.Bizware.BizwareGL.SlimDX/IGL_SlimDX9.cs | 2 +- Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs index 349bc67819..7a8f02bc9d 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs @@ -860,7 +860,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK _rsBlendNormal = new CacheBlendState( true, BlendingFactorSrc.SrcAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.OneMinusSrcAlpha, - BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero); + BlendingFactorSrc.One, BlendEquationMode.Max, BlendingFactorDest.One); } CacheBlendState _rsBlendNoneVerbatim, _rsBlendNoneOpaque, _rsBlendNormal; diff --git a/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/IGL_SlimDX9.cs b/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/IGL_SlimDX9.cs index e437875303..5d97323759 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/IGL_SlimDX9.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.SlimDX/IGL_SlimDX9.cs @@ -368,7 +368,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX _rsBlendNormal = new CacheBlendState( true, gl.BlendingFactorSrc.SrcAlpha, gl.BlendEquationMode.FuncAdd, gl.BlendingFactorDest.OneMinusSrcAlpha, - gl.BlendingFactorSrc.One, gl.BlendEquationMode.FuncAdd, gl.BlendingFactorDest.Zero); + gl.BlendingFactorSrc.One, gl.BlendEquationMode.Max, gl.BlendingFactorDest.One); } CacheBlendState _rsBlendNoneVerbatim, _rsBlendNoneOpaque, _rsBlendNormal; diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs b/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs index df5fc3591a..6bfb577f7b 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs @@ -287,7 +287,7 @@ namespace BizHawk.Bizware.BizwareGL /// public void DiscardAlpha() { - HasAlpha = false; + //HasAlpha = false; } void LoadInternal(Stream stream, sd.Bitmap bitmap, BitmapLoadOptions options) From ce81b67b8c2c3bed5812735e453e8970ffc3fe29 Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 21 Dec 2018 22:39:19 -0800 Subject: [PATCH 13/22] Allow clientapi to modify GameExtraPadding, not just ClientExtraPadding --- BizHawk.Client.ApiHawk/Classes/ClientApi.cs | 61 ++++++++++++++++++--- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs index 767d755105..631ef23062 100644 --- a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs +++ b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs @@ -219,6 +219,53 @@ namespace BizHawk.Client.ApiHawk method.Invoke(clientMainFormInstance, new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false }); } + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + /// Top padding + /// Right padding + /// Bottom padding + public static void SetGameExtraPadding(int left, int top, int right, int bottom) + { + FieldInfo f = clientAssembly.GetType("BizHawk.Game.EmuHawk.GlobalWin").GetField("DisplayManager"); + object displayManager = f.GetValue(null); + f = f.FieldType.GetField("GameExtraPadding"); + f.SetValue(displayManager, new Padding(left, top, right, bottom)); + + MethodInfo resize = mainFormClass.GetMethod("FrameBufferResized"); + resize.Invoke(clientMainFormInstance, null); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + public static void SetGameExtraPadding(int left) + { + SetGameExtraPadding(left, 0, 0, 0); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + /// Top padding + public static void SetGameExtraPadding(int left, int top) + { + SetGameExtraPadding(left, top, 0, 0); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + /// Top padding + /// Right padding + public static void SetGameExtraPadding(int left, int top, int right) + { + SetGameExtraPadding(left, top, right, 0); + } /// /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements @@ -227,7 +274,7 @@ namespace BizHawk.Client.ApiHawk /// Top padding /// Right padding /// Bottom padding - public static void SetExtraPadding(int left, int top, int right, int bottom) + public static void SetClientExtraPadding(int left, int top, int right, int bottom) { FieldInfo f = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin").GetField("DisplayManager"); object displayManager = f.GetValue(null); @@ -242,9 +289,9 @@ namespace BizHawk.Client.ApiHawk /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements /// /// Left padding - public static void SetExtraPadding(int left) + public static void SetClientExtraPadding(int left) { - SetExtraPadding(left, 0, 0, 0); + SetClientExtraPadding(left, 0, 0, 0); } /// @@ -252,9 +299,9 @@ namespace BizHawk.Client.ApiHawk /// /// Left padding /// Top padding - public static void SetExtraPadding(int left, int top) + public static void SetClientExtraPadding(int left, int top) { - SetExtraPadding(left, top, 0, 0); + SetClientExtraPadding(left, top, 0, 0); } /// @@ -263,9 +310,9 @@ namespace BizHawk.Client.ApiHawk /// Left padding /// Top padding /// Right padding - public static void SetExtraPadding(int left, int top, int right) + public static void SetClientExtraPadding(int left, int top, int right) { - SetExtraPadding(left, top, right, 0); + SetClientExtraPadding(left, top, right, 0); } From aba1da071d220ab448e7556e3cf339d7c6c8b9f7 Mon Sep 17 00:00:00 2001 From: upthorn Date: Sat, 22 Dec 2018 10:40:30 -0800 Subject: [PATCH 14/22] Completely refactored PluginAPI to extend ApiHawk. Ecco2AssistantPlugin is now an external tool. --- .gitignore | 1 + .../BizHawk.Client.ApiHawk.csproj | 37 +- .../Classes/Api/EmuApi.cs | 94 +- .../Classes/Api/GameInfoApi.cs | 10 +- .../Classes/Api/JoypadApi.cs | 8 +- .../Classes/Api/MemApi.cs | 25 +- .../Classes/Api/MemApiBase.cs | 6 +- .../Classes/Api/MemEventsApi.cs | 6 +- .../Classes/Api/MemorySaveStateApi.cs | 6 +- .../Classes/Api/MovieApi.cs | 288 +++ .../Classes/Api}/PluginBase.cs | 6 +- .../Classes/Api/SqlApi.cs | 7 +- .../Classes/Api/UserDataApi.cs | 6 +- BizHawk.Client.ApiHawk/Classes/ApiInjector.cs | 79 + .../Classes/BasicApiProvider.cs | 83 + BizHawk.Client.ApiHawk/Classes/ClientApi.cs | 407 +++- .../Interfaces/Api/IApiContainer.cs | 10 + .../Interfaces/Api/IComm.cs | 35 + BizHawk.Client.ApiHawk/Interfaces/Api/IEmu.cs | 32 + .../Interfaces/Api/IExternalApi.cs | 10 + .../Interfaces/Api/IGameInfo.cs | 15 + BizHawk.Client.ApiHawk/Interfaces/Api/IGui.cs | 51 + .../Interfaces/Api/IInput.cs | 10 + .../Interfaces/Api/IJoypad.cs | 18 + BizHawk.Client.ApiHawk/Interfaces/Api/IMem.cs | 56 + .../Interfaces/Api/IMemEvents.cs | 12 + .../Interfaces/Api/IMemorySavestate.cs | 10 + .../Interfaces/Api/IMovie.cs | 27 + .../Interfaces/Api/ISaveState.cs | 10 + BizHawk.Client.ApiHawk/Interfaces/Api/ISql.cs | 10 + .../Interfaces/Api/ITool.cs | 16 + .../Interfaces/Api/IUserData.cs | 11 + .../Interfaces/IExternalApiProvider.cs | 46 + .../Interfaces}/IPlugin.cs | 4 +- .../BizHawk.Client.Common.csproj | 1 + .../OpenAdvanced.cs | 8 +- BizHawk.Client.Common/plugins/IPluginAPI.cs | 20 - .../plugins/PluginLibrary.Movie.cs | 263 --- .../plugins/PluginLibraryBase.cs | 29 - BizHawk.Client.EmuHawk/Api/ApiContainer.cs | 32 + .../Example/Ecco2AssistantPlugin.cs | 2104 +++++++++-------- .../Libraries/CommApi.cs} | 6 +- .../Api/Libraries/GUIApi.cs | 207 +- .../Libraries/InputApi.cs} | 5 +- .../Api/Libraries/PluginLibrary.cs | 52 + .../Libraries/SaveStateAPI.cs} | 6 +- .../Api/Libraries/ToolApi.cs | 162 ++ .../BizHawk.Client.EmuHawk.csproj | 17 +- BizHawk.Client.EmuHawk/GlobalWin.cs | 3 +- BizHawk.Client.EmuHawk/MainForm.cs | 16 +- .../Plugins/Libraries/PluginLibrary.Client.cs | 351 --- .../Plugins/Libraries/PluginLibrary.GUI.cs | 162 -- .../Plugins/Libraries/PluginLibrary.cs | 125 - BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs | 28 - BizHawk.Client.EmuHawk/tools/ToolBox.cs | 4 +- BizHawk.Client.EmuHawk/tools/ToolManager.cs | 8 + BizHawk.Common/BizHawk.Common.csproj | 2 +- 57 files changed, 2859 insertions(+), 2204 deletions(-) rename BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs => BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs (91%) rename BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs => BizHawk.Client.ApiHawk/Classes/Api/GameInfoApi.cs (85%) rename BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs => BizHawk.Client.ApiHawk/Classes/Api/JoypadApi.cs (97%) rename BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs => BizHawk.Client.ApiHawk/Classes/Api/MemApi.cs (95%) rename BizHawk.Client.Common/plugins/PluginMemoryBase.cs => BizHawk.Client.ApiHawk/Classes/Api/MemApiBase.cs (97%) rename BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs => BizHawk.Client.ApiHawk/Classes/Api/MemEventsApi.cs (89%) rename BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs => BizHawk.Client.ApiHawk/Classes/Api/MemorySaveStateApi.cs (87%) create mode 100644 BizHawk.Client.ApiHawk/Classes/Api/MovieApi.cs rename {BizHawk.Client.Common/plugins => BizHawk.Client.ApiHawk/Classes/Api}/PluginBase.cs (89%) rename BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs => BizHawk.Client.ApiHawk/Classes/Api/SqlApi.cs (95%) rename BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs => BizHawk.Client.ApiHawk/Classes/Api/UserDataApi.cs (84%) create mode 100644 BizHawk.Client.ApiHawk/Classes/ApiInjector.cs create mode 100644 BizHawk.Client.ApiHawk/Classes/BasicApiProvider.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IApiContainer.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IComm.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IEmu.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IExternalApi.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IGameInfo.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IGui.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IInput.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IJoypad.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IMem.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IMemEvents.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IMemorySavestate.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IMovie.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/ISaveState.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/ISql.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/ITool.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/Api/IUserData.cs create mode 100644 BizHawk.Client.ApiHawk/Interfaces/IExternalApiProvider.cs rename {BizHawk.Client.Common/plugins => BizHawk.Client.ApiHawk/Interfaces}/IPlugin.cs (73%) rename {BizHawk.Client.EmuHawk => BizHawk.Client.Common}/OpenAdvanced.cs (94%) delete mode 100644 BizHawk.Client.Common/plugins/IPluginAPI.cs delete mode 100644 BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs delete mode 100644 BizHawk.Client.Common/plugins/PluginLibraryBase.cs create mode 100644 BizHawk.Client.EmuHawk/Api/ApiContainer.cs rename BizHawk.Client.EmuHawk/{Plugins => Api}/Example/Ecco2AssistantPlugin.cs (51%) rename BizHawk.Client.EmuHawk/{Plugins/Libraries/PluginLibrary.Communications.cs => Api/Libraries/CommApi.cs} (95%) rename BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs => BizHawk.Client.EmuHawk/Api/Libraries/GUIApi.cs (65%) rename BizHawk.Client.EmuHawk/{Plugins/Libraries/PluginLibrary.Input.cs => Api/Libraries/InputApi.cs} (92%) create mode 100644 BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs rename BizHawk.Client.EmuHawk/{Plugins/Libraries/PluginLibrary.Savestate.cs => Api/Libraries/SaveStateAPI.cs} (84%) create mode 100644 BizHawk.Client.EmuHawk/Api/Libraries/ToolApi.cs delete mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs delete mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs delete mode 100644 BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs delete mode 100644 BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs diff --git a/.gitignore b/.gitignore index 2b540361b5..20ffa86c34 100644 --- a/.gitignore +++ b/.gitignore @@ -73,3 +73,4 @@ ExternalCoreProjects/Virtu/bin/*.* libsnes/vs2015/libsnes.VC.db waterbox/**/*.wbx waterbox/**/*.wbx.in +/BizHawkTool_template.zip diff --git a/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj b/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj index 9205707a7e..c99d27ef6f 100644 --- a/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj +++ b/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj @@ -37,6 +37,10 @@ + + False + ..\..\Users\uptho\Documents\BizHawk-2.3\dll\System.Data.SQLite.dll + @@ -48,6 +52,19 @@ + + + + + + + + + + + + + @@ -62,7 +79,25 @@ + + + + + + + + + + + + + + + + + + @@ -95,4 +130,4 @@ --> - + \ No newline at end of file diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs b/BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs similarity index 91% rename from BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs rename to BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs index b0ccf94061..3677007d2b 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Emu.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs @@ -2,6 +2,7 @@ using System.ComponentModel; using System.Collections.Generic; +using BizHawk.Client.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; using BizHawk.Emulation.Cores.Nintendo.NES; @@ -12,11 +13,32 @@ using BizHawk.Emulation.Cores.Sega.MasterSystem; using BizHawk.Emulation.Cores.WonderSwan; using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { [Description("A library for interacting with the currently loaded emulator core")] - public sealed class EmulatorPluginLibrary : PluginLibraryBase + public sealed class EmuApi : IEmu { + private static class EmuStatic + { + public static void DisplayVsync(bool enabled) + { + Global.Config.VSync = enabled; + } + public static string GetSystemId() + { + return Global.Game.System; + } + public static void LimitFramerate(bool enabled) + { + Global.Config.ClockThrottle = enabled; + } + + public static void MinimizeFrameskip(bool enabled) + { + Global.Config.AutoMinimizeSkipping = enabled; + } + + } [RequiredService] private IEmulator Emulator { get; set; } @@ -41,12 +63,12 @@ namespace BizHawk.Client.Common public Action FrameAdvanceCallback { get; set; } public Action YieldCallback { get; set; } - public EmulatorPluginLibrary() : base() + public EmuApi() { } - public static void DisplayVsync(bool enabled) + public void DisplayVsync(bool enabled) { - Global.Config.VSync = enabled; + EmuStatic.DisplayVsync(enabled); } public void FrameAdvance() @@ -166,9 +188,9 @@ namespace BizHawk.Client.Common } } - public static string GetSystemId() + public string GetSystemId() { - return Global.Game.System; + return EmuStatic.GetSystemId(); } public bool IsLagged() @@ -217,14 +239,39 @@ namespace BizHawk.Client.Common } } - public static void LimitFramerate(bool enabled) + public void LimitFramerate(bool enabled) { - Global.Config.ClockThrottle = enabled; + EmuStatic.LimitFramerate(enabled); } - public static void MinimizeFrameskip(bool enabled) + public void MinimizeFrameskip(bool enabled) { - Global.Config.AutoMinimizeSkipping = enabled; + EmuStatic.MinimizeFrameskip(enabled); + } + + public void Yield() + { + YieldCallback(); + } + + public string GetDisplayType() + { + if (RegionableCore != null) + { + return RegionableCore.Region.ToString(); + } + + return ""; + } + + public string GetBoardName() + { + if (BoardInfo != null) + { + return BoardInfo.BoardName; + } + + return ""; } public object GetSettings() { @@ -407,30 +454,5 @@ namespace BizHawk.Client.Common return true; } - - public void Yield() - { - YieldCallback(); - } - - public string GetDisplayType() - { - if (RegionableCore != null) - { - return RegionableCore.Region.ToString(); - } - - return ""; - } - - public string GetBoardName() - { - if (BoardInfo != null) - { - return BoardInfo.BoardName; - } - - return ""; - } } } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs b/BizHawk.Client.ApiHawk/Classes/Api/GameInfoApi.cs similarity index 85% rename from BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs rename to BizHawk.Client.ApiHawk/Classes/Api/GameInfoApi.cs index e74ea5f21b..ca74d09da6 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Gameinfo.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/GameInfoApi.cs @@ -1,16 +1,16 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using BizHawk.Client.Common; using BizHawk.Emulation.Common; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { - public sealed class GameInfoPluginLibrary : PluginLibraryBase + public sealed class GameInfoApi : IGameInfo { [OptionalService] private IBoardInfo BoardInfo { get; set; } - public GameInfoPluginLibrary() : base() + public GameInfoApi() { } public string GetRomName() diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs b/BizHawk.Client.ApiHawk/Classes/Api/JoypadApi.cs similarity index 97% rename from BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs rename to BizHawk.Client.ApiHawk/Classes/Api/JoypadApi.cs index 5eeb3ff1e6..0c049ed97c 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Joypad.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/JoypadApi.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; -namespace BizHawk.Client.Common +using BizHawk.Client.Common; + +namespace BizHawk.Client.ApiHawk { - public sealed class JoypadPluginLibrary : PluginLibraryBase + public sealed class JoypadApi : IJoypad { - public JoypadPluginLibrary() : base() + public JoypadApi() { } public Dictionary Get(int? controller = null) diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs b/BizHawk.Client.ApiHawk/Classes/Api/MemApi.cs similarity index 95% rename from BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs rename to BizHawk.Client.ApiHawk/Classes/Api/MemApi.cs index 543ea1780b..f54b282550 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Memory.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/MemApi.cs @@ -5,20 +5,16 @@ using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; using BizHawk.Common.BufferExtensions; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { - public sealed class MemoryPluginLibrary : PluginMemoryBase + public sealed class MemApi : MemApiBase, IMem { private MemoryDomain _currentMemoryDomain; private bool _isBigEndian = false; - public MemoryPluginLibrary() + public MemApi() : base() { } - public void SetBigEndian() - { - _isBigEndian = true; - } protected override MemoryDomain Domain { @@ -44,6 +40,11 @@ namespace BizHawk.Client.Common #region Unique Library Methods + public void SetBigEndian(bool enabled = true) + { + _isBigEndian = enabled; + } + public List GetMemoryDomainList() { var list = new List(); @@ -198,16 +199,16 @@ namespace BizHawk.Client.Common return (sbyte)ReadUnsignedByte(addr, domain); } - public void WriteS8(long addr, uint value, string domain = null) - { - WriteUnsignedByte(addr, value, domain); - } - public uint ReadU8(long addr, string domain = null) { return (byte)ReadUnsignedByte(addr, domain); } + public void WriteS8(long addr, int value, string domain = null) + { + WriteSigned(addr, value, 1, domain); + } + public void WriteU8(long addr, uint value, string domain = null) { WriteUnsignedByte(addr, value, domain); diff --git a/BizHawk.Client.Common/plugins/PluginMemoryBase.cs b/BizHawk.Client.ApiHawk/Classes/Api/MemApiBase.cs similarity index 97% rename from BizHawk.Client.Common/plugins/PluginMemoryBase.cs rename to BizHawk.Client.ApiHawk/Classes/Api/MemApiBase.cs index 21bf8b89e0..bc5c328d66 100644 --- a/BizHawk.Client.Common/plugins/PluginMemoryBase.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/MemApiBase.cs @@ -3,12 +3,12 @@ using System.Collections.Generic; using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { /// /// Base class for the Memory and MainMemory plugin libraries /// - public abstract class PluginMemoryBase : PluginLibraryBase + public abstract class MemApiBase : IExternalApi { [RequiredService] protected IEmulator Emulator { get; set; } @@ -18,7 +18,7 @@ namespace BizHawk.Client.Common protected abstract MemoryDomain Domain { get; } - protected PluginMemoryBase() : base() + protected MemApiBase() { } protected IMemoryDomains DomainList diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs b/BizHawk.Client.ApiHawk/Classes/Api/MemEventsApi.cs similarity index 89% rename from BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs rename to BizHawk.Client.ApiHawk/Classes/Api/MemEventsApi.cs index 9816e9344d..5848df5fc3 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.MemoryEvents.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/MemEventsApi.cs @@ -3,14 +3,14 @@ using BizHawk.Emulation.Common; using BizHawk.Emulation.Common.IEmulatorExtensions; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { - public sealed class MemoryEventsPluginLibrary : PluginLibraryBase + public sealed class MemEventsApi : IMemEvents { [RequiredService] private IDebuggable DebuggableCore { get; set; } - public MemoryEventsPluginLibrary () : base() + public MemEventsApi () : base() { } public void AddReadCallback(Action cb, uint address, string domain) diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs b/BizHawk.Client.ApiHawk/Classes/Api/MemorySaveStateApi.cs similarity index 87% rename from BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs rename to BizHawk.Client.ApiHawk/Classes/Api/MemorySaveStateApi.cs index 90950d6f73..b22eaa7540 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.MemorySavestate.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/MemorySaveStateApi.cs @@ -4,11 +4,11 @@ using System.IO; using BizHawk.Emulation.Common; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { - public sealed class MemorySavestatePluginLibrary : PluginLibraryBase + public sealed class MemorySaveStateApi : IMemorySaveState { - public MemorySavestatePluginLibrary() : base() + public MemorySaveStateApi() { } [RequiredService] diff --git a/BizHawk.Client.ApiHawk/Classes/Api/MovieApi.cs b/BizHawk.Client.ApiHawk/Classes/Api/MovieApi.cs new file mode 100644 index 0000000000..0b74cfd5cc --- /dev/null +++ b/BizHawk.Client.ApiHawk/Classes/Api/MovieApi.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using System.IO; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.ApiHawk +{ + public sealed class MovieApi : IMovie + { + private static class MoviePluginStatic + { + public static string Filename() + { + return Global.MovieSession.Movie.Filename; + } + + public static bool GetReadOnly() + { + return Global.MovieSession.ReadOnly; + } + + public static ulong GetRerecordCount() + { + return Global.MovieSession.Movie.Rerecords; + } + + public static bool GetRerecordCounting() + { + return Global.MovieSession.Movie.IsCountingRerecords; + } + + public static bool IsLoaded() + { + return Global.MovieSession.Movie.IsActive; + } + + public static double Length() + { + return Global.MovieSession.Movie.FrameCount; + } + + public static string Mode() + { + if (Global.MovieSession.Movie.IsFinished) + { + return "FINISHED"; + } + + if (Global.MovieSession.Movie.IsPlaying) + { + return "PLAY"; + } + + if (Global.MovieSession.Movie.IsRecording) + { + return "RECORD"; + } + + return "INACTIVE"; + } + + public static void SetReadOnly(bool readOnly) + { + Global.MovieSession.ReadOnly = readOnly; + } + + public static void SetRerecordCount(double count) + { + // Lua numbers are always double, integer precision holds up + // to 53 bits, so throw an error if it's bigger than that. + const double PrecisionLimit = 9007199254740992d; + + if (count > PrecisionLimit) + { + throw new Exception("Rerecord count exceeds Lua integer precision."); + } + + Global.MovieSession.Movie.Rerecords = (ulong)count; + } + + public static void SetRerecordCounting(bool counting) + { + Global.MovieSession.Movie.IsCountingRerecords = counting; + } + + public static void Stop() + { + Global.MovieSession.Movie.Stop(); + } + + public static double GetFps() + { + if (Global.MovieSession.Movie.IsActive) + { + var movie = Global.MovieSession.Movie; + var system = movie.HeaderEntries[HeaderKeys.PLATFORM]; + var pal = movie.HeaderEntries.ContainsKey(HeaderKeys.PAL) && + movie.HeaderEntries[HeaderKeys.PAL] == "1"; + + return new PlatformFrameRates()[system, pal]; + } + + return 0.0; + } + + } + public MovieApi() + { } + + public bool StartsFromSavestate() + { + return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSavestate; + } + + public bool StartsFromSaveram() + { + return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSaveRam; + } + + public Dictionary GetInput(int frame) + { + if (!Global.MovieSession.Movie.IsActive) + { + Console.WriteLine("No movie loaded"); + return null; + } + + var input = new Dictionary(); + var adapter = Global.MovieSession.Movie.GetInputState(frame); + + if (adapter == null) + { + Console.WriteLine("Can't get input of the last frame of the movie. Use the previous frame"); + return null; + } + + foreach (var button in adapter.Definition.BoolButtons) + { + input[button] = adapter.IsPressed(button); + } + + foreach (var button in adapter.Definition.FloatControls) + { + input[button] = adapter.GetFloat(button); + } + + return input; + } + + public string GetInputAsMnemonic(int frame) + { + if (Global.MovieSession.Movie.IsActive && frame < Global.MovieSession.Movie.InputLogLength) + { + var lg = Global.MovieSession.LogGeneratorInstance(); + lg.SetSource(Global.MovieSession.Movie.GetInputState(frame)); + return lg.GenerateLogEntry(); + } + + return ""; + } + + public void Save(string filename = "") + { + if (!Global.MovieSession.Movie.IsActive) + { + return; + } + + if (!string.IsNullOrEmpty(filename)) + { + filename += "." + Global.MovieSession.Movie.PreferredExtension; + var test = new FileInfo(filename); + if (test.Exists) + { + Console.WriteLine($"File {filename} already exists, will not overwrite"); + return; + } + + Global.MovieSession.Movie.Filename = filename; + } + + Global.MovieSession.Movie.Save(); + } + + public Dictionary GetHeader() + { + var table = new Dictionary(); + if (Global.MovieSession.Movie.IsActive) + { + foreach (var kvp in Global.MovieSession.Movie.HeaderEntries) + { + table[kvp.Key] = kvp.Value; + } + } + + return table; + } + + public List GetComments() + { + var list = new List(Global.MovieSession.Movie.Comments.Count); + if (Global.MovieSession.Movie.IsActive) + { + for (int i = 0; i < Global.MovieSession.Movie.Comments.Count; i++) + { + list[i] = Global.MovieSession.Movie.Comments[i]; + } + } + + return list; + } + + public List GetSubtitles() + { + var list = new List(Global.MovieSession.Movie.Subtitles.Count); + if (Global.MovieSession.Movie.IsActive) + { + for (int i = 0; i < Global.MovieSession.Movie.Subtitles.Count; i++) + { + list[i] = Global.MovieSession.Movie.Subtitles[i].ToString(); + } + } + + return list; + } + + public string Filename() + { + return MoviePluginStatic.Filename(); + } + + public bool GetReadOnly() + { + return MoviePluginStatic.GetReadOnly(); + } + + public ulong GetRerecordCount() + { + return MoviePluginStatic.GetRerecordCount(); + } + + public bool GetRerecordCounting() + { + return MoviePluginStatic.GetRerecordCounting(); + } + + public bool IsLoaded() + { + return MoviePluginStatic.IsLoaded(); + } + + public double Length() + { + return MoviePluginStatic.Length(); + } + + public string Mode() + { + return MoviePluginStatic.Mode(); + } + + public void SetReadOnly(bool readOnly) + { + MoviePluginStatic.SetReadOnly(readOnly); + } + + public void SetRerecordCount(double count) + { + MoviePluginStatic.SetRerecordCount(count); + } + + public void SetRerecordCounting(bool counting) + { + MoviePluginStatic.SetRerecordCounting(counting); + } + + public void Stop() + { + MoviePluginStatic.Stop(); + } + + public double GetFps() + { + return MoviePluginStatic.GetFps(); + } + } +} diff --git a/BizHawk.Client.Common/plugins/PluginBase.cs b/BizHawk.Client.ApiHawk/Classes/Api/PluginBase.cs similarity index 89% rename from BizHawk.Client.Common/plugins/PluginBase.cs rename to BizHawk.Client.ApiHawk/Classes/Api/PluginBase.cs index 7ef2f4453d..24bf62c727 100644 --- a/BizHawk.Client.Common/plugins/PluginBase.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/PluginBase.cs @@ -1,6 +1,6 @@ using BizHawk.Emulation.Common; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { public abstract class PluginBase : IPlugin { @@ -13,7 +13,7 @@ namespace BizHawk.Client.Common /// or register memory callbacks in /// their Init function. /// - protected IPluginAPI _api; + protected IApiContainer _api; public PluginBase() { } @@ -41,7 +41,7 @@ namespace BizHawk.Client.Common public virtual void LoadStateCallback(string name) { } public virtual void InputPollCallback() { } public virtual void ExitCallback() { } - public virtual void Init (IPluginAPI api) + public virtual void Init (IApiContainer api) { _api = api; Running = true; diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs b/BizHawk.Client.ApiHawk/Classes/Api/SqlApi.cs similarity index 95% rename from BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs rename to BizHawk.Client.ApiHawk/Classes/Api/SqlApi.cs index dae76333af..6a18d507af 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.SQL.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/SqlApi.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data.SQLite; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { - public sealed class SQLPluginLibrary : PluginLibraryBase + public sealed class SqlApi : ISql { - public SQLPluginLibrary() : base() + public SqlApi() : base() { } SQLiteConnection m_dbConnection; @@ -125,6 +125,5 @@ namespace BizHawk.Client.Common return sqlEX.Message; } } - } } diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs b/BizHawk.Client.ApiHawk/Classes/Api/UserDataApi.cs similarity index 84% rename from BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs rename to BizHawk.Client.ApiHawk/Classes/Api/UserDataApi.cs index 27d2dc5af4..735fe397b9 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.UserData.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/UserDataApi.cs @@ -3,11 +3,11 @@ using System.ComponentModel; using BizHawk.Client.Common; -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { - public sealed class UserDataPluginLibrary : PluginLibraryBase + public sealed class UserDataApi : IUserData { - public UserDataPluginLibrary() : base() + public UserDataApi() : base() { } public void Set(string name, object value) diff --git a/BizHawk.Client.ApiHawk/Classes/ApiInjector.cs b/BizHawk.Client.ApiHawk/Classes/ApiInjector.cs new file mode 100644 index 0000000000..811807659f --- /dev/null +++ b/BizHawk.Client.ApiHawk/Classes/ApiInjector.cs @@ -0,0 +1,79 @@ +using System; +using System.Linq; + +using BizHawk.Common.ReflectionExtensions; + +namespace BizHawk.Client.ApiHawk +{ + /// + /// injects Apis into other classes + /// + public static class ApiInjector + { + /// + /// clears all Apis from a target + /// + public static void ClearApis(object target) + { + Type targetType = target.GetType(); + object[] tmp = new object[1]; + + foreach (var propinfo in + targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute)) + .Concat(targetType.GetPropertiesWithAttrib(typeof(OptionalApiAttribute)))) + { + propinfo.GetSetMethod(true).Invoke(target, tmp); + } + } + + /// + /// Feeds the target its required Apis. + /// + /// false if update failed + public static bool UpdateApis(IExternalApiProvider source, object target) + { + Type targetType = target.GetType(); + object[] tmp = new object[1]; + + foreach (var propinfo in targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute))) + { + tmp[0] = source.GetApi(propinfo.PropertyType); + if (tmp[0] == null) + { + return false; + } + + propinfo.GetSetMethod(true).Invoke(target, tmp); + } + + foreach (var propinfo in targetType.GetPropertiesWithAttrib(typeof(OptionalApiAttribute))) + { + tmp[0] = source.GetApi(propinfo.PropertyType); + propinfo.GetSetMethod(true).Invoke(target, tmp); + } + + return true; + } + + /// + /// Determines whether a target is available, considering its dependencies + /// and the Apis provided by the emulator core. + /// + public static bool IsAvailable(IExternalApiProvider source, Type targetType) + { + return targetType.GetPropertiesWithAttrib(typeof(RequiredApiAttribute)) + .Select(pi => pi.PropertyType) + .All(source.HasApi); + } + } + + [AttributeUsage(AttributeTargets.Property)] + public class RequiredApiAttribute : Attribute + { + } + + [AttributeUsage(AttributeTargets.Property)] + public class OptionalApiAttribute : Attribute + { + } +} diff --git a/BizHawk.Client.ApiHawk/Classes/BasicApiProvider.cs b/BizHawk.Client.ApiHawk/Classes/BasicApiProvider.cs new file mode 100644 index 0000000000..75da59a6d4 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Classes/BasicApiProvider.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BizHawk.Client.ApiHawk +{ + /// + /// A generic implementation of IExternalApi provider that provides + /// this functionality to any core. + /// The provider will scan an IExternal and register all IExternalApis + /// that the core object itself implements. In addition it provides + /// a Register() method to allow the core to pass in any additional Apis + /// + /// + public class BasicApiProvider : IExternalApiProvider + { + private readonly Dictionary _Apis = new Dictionary(); + + public BasicApiProvider(IApiContainer container) + { + // simplified logic here doesn't scan for possible Apis; just adds what it knows is implemented by the PluginApi + // this removes the possibility of automagically picking up a Api in a nested class, (find the type, then + // find the field), but we're going to keep such logic out of the basic provider. Anything the passed + // container doesn't implement directly needs to be added with Register() + // this also fully allows apis that are not IExternalApi + var libs = container.Libraries; + + _Apis = libs; + } + + /// + /// the client can call this to register an additional Api + /// + /// The to register + public void Register(T api) + where T : IExternalApi + { + if (api == null) + { + throw new ArgumentNullException(nameof(api)); + } + + _Apis[typeof(T)] = api; + } + + public T GetApi() + where T : IExternalApi + { + return (T)GetApi(typeof(T)); + } + + public object GetApi(Type t) + { + IExternalApi Api; + KeyValuePair[] k = _Apis.Where(kvp => t.IsAssignableFrom(kvp.Key)).ToArray(); + if (k.Length > 0) + { + return k[0].Value; + } + + return null; + } + + public bool HasApi() + where T : IExternalApi + { + return HasApi(typeof(T)); + } + + public bool HasApi(Type t) + { + return _Apis.ContainsKey(t); + } + + public IEnumerable AvailableApis + { + get + { + return _Apis.Select(d => d.Key); + } + } + } +} diff --git a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs index 767d755105..8756885f54 100644 --- a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs +++ b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs @@ -5,6 +5,7 @@ using System.Reflection; using System.Threading.Tasks; using System.Windows.Forms; using BizHawk.Client.Common; +using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.PCEngine; using BizHawk.Emulation.Cores.Sega.MasterSystem; @@ -21,6 +22,9 @@ namespace BizHawk.Client.ApiHawk { #region Fields + private static IEmulator Emulator; + private static IVideoProvider VideoProvider; + private static readonly Assembly clientAssembly; private static readonly object clientMainFormInstance; private static readonly Type mainFormClass; @@ -68,24 +72,57 @@ namespace BizHawk.Client.ApiHawk mainFormClass = clientAssembly.GetType("BizHawk.Client.EmuHawk.MainForm"); } + public static void UpdateEmulatorAndVP(IEmulator emu = null) + { + Emulator = emu; + VideoProvider = Emulation.Common.IEmulatorExtensions.Extensions.AsVideoProviderOrDefault(emu); + } + #endregion #region Methods + #region Helpers + + private static void InvokeMainFormMethod(string name, dynamic[] paramList = null) + { + List typeList = new List(); + MethodInfo method; + if (paramList != null) + { + foreach (var obj in paramList) + { + typeList.Add(obj.GetType()); + } + method = mainFormClass.GetMethod(name, typeList.ToArray()); + } + else method = mainFormClass.GetMethod(name); + method.Invoke(clientMainFormInstance, paramList); + } + + private static object GetMainFormField(string name) + { + return mainFormClass.GetField(name); + } + + private static void SetMainFormField(string name, object value) + { + mainFormClass.GetField(name).SetValue(clientMainFormInstance, value); + } + + #endregion + #region Public /// /// THE FrameAdvance stuff /// public static void DoFrameAdvance() { - MethodInfo method = mainFormClass.GetMethod("FrameAdvance"); - method.Invoke(clientMainFormInstance, null); + InvokeMainFormMethod("FrameAdvance", null); - method = mainFormClass.GetMethod("StepRunLoop_Throttle", BindingFlags.NonPublic | BindingFlags.Instance); - method.Invoke(clientMainFormInstance, null); + InvokeMainFormMethod("StepRunLoop_Throttle", null); - method = mainFormClass.GetMethod("Render", BindingFlags.NonPublic | BindingFlags.Instance); - method.Invoke(clientMainFormInstance, null); + InvokeMainFormMethod("Render", null); } /// @@ -124,8 +161,7 @@ namespace BizHawk.Client.ApiHawk /// Savetate friendly name public static void LoadState(string name) { - MethodInfo method = mainFormClass.GetMethod("LoadState"); - method.Invoke(clientMainFormInstance, new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false, false }); + InvokeMainFormMethod("LoadState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false, false }); } @@ -194,12 +230,11 @@ namespace BizHawk.Client.ApiHawk /// /// Raise when a rom is successfully Loaded /// - public static void OnRomLoaded() + public static void OnRomLoaded(IEmulator emu) { - if (RomLoaded != null) - { - RomLoaded(null, EventArgs.Empty); - } + Emulator = emu; + VideoProvider = Emulation.Common.IEmulatorExtensions.Extensions.AsVideoProviderOrDefault(emu); + RomLoaded?.Invoke(null, EventArgs.Empty); allJoypads = new List(RunningSystem.MaxControllers); for (int i = 1; i <= RunningSystem.MaxControllers; i++) @@ -215,11 +250,9 @@ namespace BizHawk.Client.ApiHawk /// Savetate friendly name public static void SaveState(string name) { - MethodInfo method = mainFormClass.GetMethod("SaveState"); - method.Invoke(clientMainFormInstance, new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false }); + InvokeMainFormMethod("SaveState", new object[] { Path.Combine(PathManager.GetSaveStatePath(Global.Game), string.Format("{0}.{1}", name, "State")), name, false }); } - /// /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements /// @@ -227,24 +260,23 @@ namespace BizHawk.Client.ApiHawk /// Top padding /// Right padding /// Bottom padding - public static void SetExtraPadding(int left, int top, int right, int bottom) + public static void SetGameExtraPadding(int left, int top, int right, int bottom) { FieldInfo f = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin").GetField("DisplayManager"); object displayManager = f.GetValue(null); - f = f.FieldType.GetField("ClientExtraPadding"); + f = f.FieldType.GetField("GameExtraPadding"); f.SetValue(displayManager, new Padding(left, top, right, bottom)); - MethodInfo resize = mainFormClass.GetMethod("FrameBufferResized"); - resize.Invoke(clientMainFormInstance, null); + InvokeMainFormMethod("FrameBufferResized"); } /// /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements /// /// Left padding - public static void SetExtraPadding(int left) + public static void SetGameExtraPadding(int left) { - SetExtraPadding(left, 0, 0, 0); + SetGameExtraPadding(left, 0, 0, 0); } /// @@ -252,9 +284,9 @@ namespace BizHawk.Client.ApiHawk /// /// Left padding /// Top padding - public static void SetExtraPadding(int left, int top) + public static void SetGameExtraPadding(int left, int top) { - SetExtraPadding(left, top, 0, 0); + SetGameExtraPadding(left, top, 0, 0); } /// @@ -263,9 +295,56 @@ namespace BizHawk.Client.ApiHawk /// Left padding /// Top padding /// Right padding - public static void SetExtraPadding(int left, int top, int right) + public static void SetGameExtraPadding(int left, int top, int right) { - SetExtraPadding(left, top, right, 0); + SetGameExtraPadding(left, top, right, 0); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + /// Top padding + /// Right padding + /// Bottom padding + public static void SetClientExtraPadding(int left, int top, int right, int bottom) + { + FieldInfo f = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin").GetField("DisplayManager"); + object displayManager = f.GetValue(null); + f = f.FieldType.GetField("ClientExtraPadding"); + f.SetValue(displayManager, new Padding(left, top, right, bottom)); + + InvokeMainFormMethod("FrameBufferResized"); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + public static void SetClientExtraPadding(int left) + { + SetClientExtraPadding(left, 0, 0, 0); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + /// Top padding + public static void SetClientExtraPadding(int left, int top) + { + SetClientExtraPadding(left, top, 0, 0); + } + + /// + /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements + /// + /// Left padding + /// Top padding + /// Right padding + public static void SetClientExtraPadding(int left, int top, int right) + { + SetClientExtraPadding(left, top, right, 0); } @@ -327,8 +406,7 @@ namespace BizHawk.Client.ApiHawk /// public static void UnpauseEmulation() { - MethodInfo method = mainFormClass.GetMethod("UnpauseEmulator"); - method.Invoke(clientMainFormInstance, null); + InvokeMainFormMethod("UnpauseEmulator", null); } #endregion Public @@ -375,6 +453,275 @@ namespace BizHawk.Client.ApiHawk } } + public static void CloseEmulator() + { + InvokeMainFormMethod("CloseEmulator"); + } + + public static void CloseEmulatorWithCode(int exitCode) + { + InvokeMainFormMethod("CloseEmulator", new object[] {exitCode}); + } + + public static int BorderHeight() + { + var point = new System.Drawing.Point(0, 0); + Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin"); + FieldInfo f = t.GetField("DisplayManager"); + object displayManager = f.GetValue(null); + MethodInfo m = t.GetMethod("TransFormPoint"); + point = (System.Drawing.Point) m.Invoke(displayManager, new object[] { point }); + return point.Y; + } + + public static int BorderWidth() + { + var point = new System.Drawing.Point(0, 0); + Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin"); + FieldInfo f = t.GetField("DisplayManager"); + object displayManager = f.GetValue(null); + MethodInfo m = t.GetMethod("TransFormPoint"); + point = (System.Drawing.Point)m.Invoke(displayManager, new object[] { point }); + return point.X; + } + + public static int BufferHeight() + { + return VideoProvider.BufferHeight; + } + + public static int BufferWidth() + { + return VideoProvider.BufferWidth; + } + + public static void ClearAutohold() + { + InvokeMainFormMethod("ClearHolds"); + } + + public static void CloseRom() + { + InvokeMainFormMethod("CloseRom"); + } + + public static void DisplayMessages(bool value) + { + Global.Config.DisplayMessages = value; + } + + public static void EnableRewind(bool enabled) + { + InvokeMainFormMethod("EnableRewind", new object[] {enabled}); + } + + public static void FrameSkip(int numFrames) + { + if (numFrames > 0) + { + Global.Config.FrameSkip = numFrames; + InvokeMainFormMethod("FrameSkipMessage"); + } + else + { + Console.WriteLine("Invalid frame skip value"); + } + } + + public static int GetTargetScanlineIntensity() + { + return Global.Config.TargetScanlineFilterIntensity; + } + + public static int GetWindowSize() + { + return Global.Config.TargetZoomFactors[Emulator.SystemId]; + } + + public static void SetSoundOn(bool enable) + { + Global.Config.SoundEnabled = enable; + } + + public static bool GetSoundOn() + { + return Global.Config.SoundEnabled; + } + + public static bool IsPaused() + { + return (bool) GetMainFormField("EmulatorPaused"); + } + + public static bool IsTurbo() + { + return (bool)GetMainFormField("IsTurboing"); + } + + public static bool IsSeeking() + { + return (bool)GetMainFormField("IsSeeking"); + } + + public static void OpenRom(string path) + { + var ioa = OpenAdvancedSerializer.ParseWithLegacy(path); + Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin.MainForm.LoadRomArgs"); + object o = Activator.CreateInstance(t); + t.GetField("OpenAdvanced").SetValue(o, ioa); + + InvokeMainFormMethod("LoadRom", new object[] {path, o}); + } + + public static void Pause() + { + InvokeMainFormMethod("PauseEmulator"); + } + + public static void PauseAv() + { + SetMainFormField("PauseAvi", true); + } + + public static void RebootCore() + { + InvokeMainFormMethod("RebootCore"); + } + + public static void SaveRam() + { + InvokeMainFormMethod("FlushSaveRAM"); + } + + public static int ScreenHeight() + { + Type t = GetMainFormField("PresentationPanel").GetType(); + object o = GetMainFormField("PresentationPanel"); + o = t.GetField("NativeSize").GetValue(o); + t = t.GetField("NativeSize").GetType(); + + return (int) t.GetField("Height").GetValue(o); + } + + public static void Screenshot(string path = null) + { + if (path == null) + { + InvokeMainFormMethod("TakeScreenshot"); + } + else + { + InvokeMainFormMethod("TakeScreenshot", new object[] {path}); + } + } + + public static void ScreenshotToClipboard() + { + InvokeMainFormMethod("TakeScreenshotToClipboard"); + } + + public static void SetTargetScanlineIntensity(int val) + { + Global.Config.TargetScanlineFilterIntensity = val; + } + + public static void SetScreenshotOSD(bool value) + { + Global.Config.Screenshot_CaptureOSD = value; + } + + public static int ScreenWidth() + { + Type t = GetMainFormField("PresentationPanel").GetType(); + object o = GetMainFormField("PresentationPanel"); + o = t.GetField("NativeSize").GetValue(o); + t = t.GetField("NativeSize").GetType(); + + return (int) t.GetField("Width").GetValue(o); + } + + public static void SetWindowSize(int size) + { + if (size == 1 || size == 2 || size == 3 || size == 4 || size == 5 || size == 10) + { + Global.Config.TargetZoomFactors[Emulator.SystemId] = size; + InvokeMainFormMethod("FrameBufferResized"); + Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin"); + FieldInfo f = t.GetField("OSD"); + object osd = f.GetValue(null); + t = f.GetType(); + MethodInfo m = t.GetMethod("AddMessage"); + m.Invoke(osd, new Object[] { "Window size set to " + size + "x" }); + } + else + { + Console.WriteLine("Invalid window size"); + } + } + + public static void SpeedMode(int percent) + { + if (percent > 0 && percent < 6400) + { + InvokeMainFormMethod("ClickSpeedItem", new object[] {percent}); + } + else + { + Console.WriteLine("Invalid speed value"); + } + } + + public static void TogglePause() + { + InvokeMainFormMethod("TogglePause"); + } + + public static int TransformPointX(int x) + { + var point = new System.Drawing.Point(x, 0); + Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin"); + FieldInfo f = t.GetField("DisplayManager"); + object displayManager = f.GetValue(null); + MethodInfo m = t.GetMethod("TransFormPoint"); + point = (System.Drawing.Point)m.Invoke(displayManager, new object[] { point }); + return point.X; + } + + public static int TransformPointY(int y) + { + var point = new System.Drawing.Point(0, y); + Type t = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin"); + FieldInfo f = t.GetField("DisplayManager"); + object displayManager = f.GetValue(null); + MethodInfo m = t.GetMethod("TransFormPoint"); + point = (System.Drawing.Point)m.Invoke(displayManager, new object[] { point }); + return point.Y; + } + + public static void Unpause() + { + InvokeMainFormMethod("UnpauseEmulator"); + } + + public static void UnpauseAv() + { + SetMainFormField("PauseAvi", false); + } + + public static int Xpos() + { + object o = GetMainFormField("DesktopLocation"); + Type t = mainFormClass.GetField("DesktopLocation").GetType(); + return (int)t.GetField("X").GetValue(o); + } + + public static int Ypos() + { + object o = GetMainFormField("DesktopLocation"); + Type t = mainFormClass.GetField("DesktopLocation").GetType(); + return (int)t.GetField("Y").GetValue(o); + } + #endregion #region Properties @@ -427,11 +774,11 @@ namespace BizHawk.Client.ApiHawk } else { - return SystemInfo.DualGB; + return SystemInfo.DualGB; } default: - return SystemInfo.FindByCoreSystem(SystemIdConverter.Convert(Global.Emulator.SystemId)); + return SystemInfo.FindByCoreSystem(SystemIdConverter.Convert(Global.Emulator.SystemId)); } } } diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IApiContainer.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IApiContainer.cs new file mode 100644 index 0000000000..ec169fee9d --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IApiContainer.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + public interface IApiContainer + { + Dictionary Libraries { get; set; } + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IComm.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IComm.cs new file mode 100644 index 0000000000..9ef8a5e0c0 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IComm.cs @@ -0,0 +1,35 @@ +namespace BizHawk.Client.ApiHawk +{ + public interface IComm : IExternalApi + { + #region Sockets + string SocketServerScreenShot(); + string SocketServerScreenShotResponse(); + string SocketServerSend(string SendString); + string SocketServerResponse(); + bool SocketServerSuccessful(); + void SocketServerSetTimeout(int timeout); + #endregion + + #region MemoryMappedFiles + void MmfSetFilename(string filename); + string MmfSetFilename(); + int MmfScreenshot(); + int MmfWrite(string mmf_filename, string outputString); + string MmfRead(string mmf_filename, int expectedSize); + #endregion + + #region HTTP + string HttpTest(); + string HttpTestGet(); + string HttpGet(string url); + string HttpPost(string url, string payload); + string HttpPostScreenshot(); + void HttpSetTimeout(int timeout); + void HttpSetPostUrl(string url); + void HttpSetGetUrl(string url); + string HttpGetPostUrl(); + string HttpGetGetUrl(); + #endregion + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IEmu.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IEmu.cs new file mode 100644 index 0000000000..51136126ac --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IEmu.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + public interface IEmu : IExternalApi + { + Action FrameAdvanceCallback { get; set; } + Action YieldCallback { get; set; } + void DisplayVsync(bool enabled); + void FrameAdvance(); + int FrameCount(); + object Disassemble(uint pc, string name = ""); + ulong? GetRegister(string name); + Dictionary GetRegisters(); + void SetRegister(string register, int value); + long TotalExecutedycles(); + string GetSystemId(); + bool IsLagged(); + void SetIsLagged(bool value = true); + int LagCount(); + void SetLagCount(int count); + void LimitFramerate(bool enabled); + void MinimizeFrameskip(bool enabled); + void Yield(); + string GetDisplayType(); + string GetBoardName(); + object GetSettings(); + bool PutSettings(object settings); + void SetRenderPlanes(params bool[] param); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IExternalApi.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IExternalApi.cs new file mode 100644 index 0000000000..8dc7c9da03 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IExternalApi.cs @@ -0,0 +1,10 @@ +namespace BizHawk.Client.ApiHawk +{ + /// + /// This interface specifies that a client exposes a given interface, such as , + /// for use by external tools. + /// + public interface IExternalApi + { + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IGameInfo.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IGameInfo.cs new file mode 100644 index 0000000000..814a6d268c --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IGameInfo.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + public interface IGameInfo : IExternalApi + { + string GetRomName(); + string GetRomHash(); + bool InDatabase(); + string GetStatus(); + bool IsStatusBad(); + string GetBoardType(); + Dictionary GetOptions(); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IGui.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IGui.cs new file mode 100644 index 0000000000..03e3247e51 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IGui.cs @@ -0,0 +1,51 @@ +using System.Drawing; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace BizHawk.Client.ApiHawk +{ + public interface IGui : IExternalApi + { + #region Gui API + void ToggleCompositingMode(); + ImageAttributes GetAttributes(); + void SetAttributes(ImageAttributes a); + void DrawNew(string name, bool? clear = true); + void DrawFinish(); + bool HasGUISurface { get; } + #endregion + + #region Helpers + void SetPadding(int all); + void SetPadding(int x, int y); + void SetPadding(int l, int t, int r, int b); + Padding GetPadding(); + #endregion + + void AddMessage(string message); + void ClearGraphics(); + void ClearText(); + void SetDefaultForegroundColor(Color color); + void SetDefaultBackgroundColor(Color color); + void SetDefaultTextBackground(Color color); + void SetDefaultPixelFont(string fontfamily); + void DrawBezier(Point p1, Point p2, Point p3, Point p4, Color? color = null); + void DrawBeziers(Point[] points, Color? color = null); + void DrawBox(int x, int y, int x2, int y2, Color? line = null, Color? background = null); + void DrawEllipse(int x, int y, int width, int height, Color? line = null, Color? background = null); + void DrawIcon(string path, int x, int y, int? width = null, int? height = null); + void DrawImage(string path, int x, int y, int? width = null, int? height = null, bool cache = true); + void ClearImageCache(); + void DrawImageRegion(string path, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int? dest_width = null, int? dest_height = null); + void DrawLine(int x1, int y1, int x2, int y2, Color? color = null); + void DrawAxis(int x, int y, int size, Color? color = null); + void DrawPie(int x, int y, int width, int height, int startangle, int sweepangle, Color? line = null, Color? background = null); + void DrawPixel(int x, int y, Color? color = null); + void DrawPolygon(Point[] points, Color? line = null, Color? background = null); + void DrawRectangle(int x, int y, int width, int height, Color? line = null, Color? background = null); + void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null, + string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null); + void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null); + void Text(int x, int y, string message, Color? forecolor = null, string anchor = null); + } +} \ No newline at end of file diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IInput.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IInput.cs new file mode 100644 index 0000000000..507bb024bf --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IInput.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + public interface IInput : IExternalApi + { + Dictionary Get(); + Dictionary GetMouse(); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IJoypad.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IJoypad.cs new file mode 100644 index 0000000000..1a8ce3340a --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IJoypad.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + public interface IJoypad : IExternalApi + { + Dictionary Get(int? controller = null); + + // TODO: what about float controls? + Dictionary GetImmediate(); + void SetFromMnemonicStr(string inputLogEntry); + void Set(Dictionary buttons, int? controller = null); + void Set(string button, bool? state = null, int? controller = null); + void SetAnalog(Dictionary controls, object controller = null); + void SetAnalog(string control, float? value = null, object controller = null); + + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IMem.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IMem.cs new file mode 100644 index 0000000000..7c8961ac5f --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IMem.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + public interface IMem : IExternalApi + { + void SetBigEndian(bool enabled = true); + + #region Domains + List GetMemoryDomainList(); + uint GetMemoryDomainSize(string name = ""); + string GetCurrentMemoryDomain(); + uint GetCurrentMemoryDomainSize(); + bool UseMemoryDomain(string domain); + string HashRegion(long addr, int count, string domain = null); + #endregion + #region Read + #region Special and Legacy Methods + uint ReadByte(long addr, string domain = null); + List ReadByteRange(long addr, int length, string domain = null); + float ReadFloat(long addr, string domain = null); + #endregion + #region Signed + int ReadS8(long addr, string domain = null); + int ReadS16(long addr, string domain = null); + int ReadS24(long addr, string domain = null); + int ReadS32(long addr, string domain = null); + #endregion + #region Unsigned + uint ReadU8(long addr, string domain = null); + uint ReadU16(long addr, string domain = null); + uint ReadU24(long addr, string domain = null); + uint ReadU32(long addr, string domain = null); + #endregion + #endregion + #region Write + #region Special and Legacy Methods + void WriteByte(long addr, uint value, string domain = null); + void WriteByteRange(long addr, List memoryblock, string domain = null); + void WriteFloat(long addr, double value, string domain = null); + #endregion + #region Signed + void WriteS8(long addr, int value, string domain = null); + void WriteS16(long addr, int value, string domain = null); + void WriteS24(long addr, int value, string domain = null); + void WriteS32(long addr, int value, string domain = null); + #endregion + #region Unigned + void WriteU8(long addr, uint value, string domain = null); + void WriteU16(long addr, uint value, string domain = null); + void WriteU24(long addr, uint value, string domain = null); + void WriteU32(long addr, uint value, string domain = null); + #endregion + #endregion + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IMemEvents.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IMemEvents.cs new file mode 100644 index 0000000000..b8650a9139 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IMemEvents.cs @@ -0,0 +1,12 @@ +using System; + +namespace BizHawk.Client.ApiHawk +{ + public interface IMemEvents : IExternalApi + { + void AddReadCallback(Action cb, uint address, string domain); + void AddWriteCallback(Action cb, uint address, string domain); + void AddExecCallback(Action cb, uint address, string domain); + void RemoveMemoryCallback(Action cb); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IMemorySavestate.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IMemorySavestate.cs new file mode 100644 index 0000000000..e3444c7bb5 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IMemorySavestate.cs @@ -0,0 +1,10 @@ +namespace BizHawk.Client.ApiHawk +{ + public interface IMemorySaveState : IExternalApi + { + string SaveCoreStateToMemory(); + void LoadCoreStateFromMemory(string identifier); + void DeleteState(string identifier); + void ClearInMemoryStates(); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IMovie.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IMovie.cs new file mode 100644 index 0000000000..c983ec1df1 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IMovie.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +namespace BizHawk.Client.ApiHawk +{ + public interface IMovie : IExternalApi + { + bool StartsFromSavestate(); + bool StartsFromSaveram(); + string Filename(); + Dictionary GetInput(int frame); + string GetInputAsMnemonic(int frame); + bool GetReadOnly(); + ulong GetRerecordCount(); + bool GetRerecordCounting(); + bool IsLoaded(); + double Length(); + string Mode(); + void Save(string filename = ""); + void SetReadOnly(bool readOnly); + void SetRerecordCount(double count); + void SetRerecordCounting(bool counting); + void Stop(); + double GetFps(); + Dictionary GetHeader(); + List GetComments(); + List GetSubtitles(); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/ISaveState.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/ISaveState.cs new file mode 100644 index 0000000000..8f595610fe --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/ISaveState.cs @@ -0,0 +1,10 @@ +namespace BizHawk.Client.ApiHawk +{ + public interface ISaveState : IExternalApi + { + void Load(string path); + void LoadSlot(int slotNum); + void Save(string path); + void SaveSlot(int slotNum); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/ISql.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/ISql.cs new file mode 100644 index 0000000000..99407ac1c2 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/ISql.cs @@ -0,0 +1,10 @@ +namespace BizHawk.Client.ApiHawk +{ + public interface ISql : IExternalApi + { + string CreateDatabase(string name); + string OpenDatabase(string name); + string WriteCommand(string query = ""); + dynamic ReadCommand(string query = ""); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/ITool.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/ITool.cs new file mode 100644 index 0000000000..ce4cdce516 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/ITool.cs @@ -0,0 +1,16 @@ +using System; +namespace BizHawk.Client.ApiHawk +{ + public interface ITool : IExternalApi + { + Type GetTool(string name); + object CreateInstance(string name); + void OpenCheats(); + void OpenHexEditor(); + void OpenRamWatch(); + void OpenRamSearch(); + void OpenTasStudio(); + void OpenToolBox(); + void OpenTraceLogger(); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/Api/IUserData.cs b/BizHawk.Client.ApiHawk/Interfaces/Api/IUserData.cs new file mode 100644 index 0000000000..234a7d4695 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/Api/IUserData.cs @@ -0,0 +1,11 @@ +namespace BizHawk.Client.ApiHawk +{ + public interface IUserData : IExternalApi + { + void Set(string name, object value); + object Get(string key); + void Clear(); + bool Remove(string key); + bool ContainsKey(string key); + } +} diff --git a/BizHawk.Client.ApiHawk/Interfaces/IExternalApiProvider.cs b/BizHawk.Client.ApiHawk/Interfaces/IExternalApiProvider.cs new file mode 100644 index 0000000000..d44299f7b1 --- /dev/null +++ b/BizHawk.Client.ApiHawk/Interfaces/IExternalApiProvider.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace BizHawk.Client.ApiHawk +{ + /// + /// This interface defines the mechanism by which External tools can retrieve + /// from a client implementation + /// An implementation should collect all available IExternalApi instances. + /// This interface defines only the external interaction. This interface does not specify the means + /// by which a api provider will be populated with available apis. However, an implementation + /// by design must provide this mechanism + /// + /// + public interface IExternalApiProvider + { + /// e + /// Returns whether or not T is available + /// + /// The to check + bool HasApi() where T : IExternalApi; + + /// + /// Returns whether or not t is available + /// + bool HasApi(Type t); + + /// + /// Returns an instance of T if T is available + /// Else returns null + /// + /// The requested + T GetApi() where T : IExternalApi; + + /// + /// Returns an instance of t if t is available + /// Else returns null + /// + object GetApi(Type t); + + /// + /// Gets a list of all currently registered Apis available to be retrieved + /// + IEnumerable AvailableApis { get; } + } +} diff --git a/BizHawk.Client.Common/plugins/IPlugin.cs b/BizHawk.Client.ApiHawk/Interfaces/IPlugin.cs similarity index 73% rename from BizHawk.Client.Common/plugins/IPlugin.cs rename to BizHawk.Client.ApiHawk/Interfaces/IPlugin.cs index 9220e90dbd..444ecec8b2 100644 --- a/BizHawk.Client.Common/plugins/IPlugin.cs +++ b/BizHawk.Client.ApiHawk/Interfaces/IPlugin.cs @@ -1,4 +1,4 @@ -namespace BizHawk.Client.Common +namespace BizHawk.Client.ApiHawk { interface IPlugin { @@ -7,6 +7,6 @@ void SaveStateCallback(string name); void LoadStateCallback(string name); void InputPollCallback(); - void Init(IPluginAPI api); + void Init(IApiContainer api); } } diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index f3bcc12f20..84c1eed24d 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -260,6 +260,7 @@ + diff --git a/BizHawk.Client.EmuHawk/OpenAdvanced.cs b/BizHawk.Client.Common/OpenAdvanced.cs similarity index 94% rename from BizHawk.Client.EmuHawk/OpenAdvanced.cs rename to BizHawk.Client.Common/OpenAdvanced.cs index 9a9cfc1c91..b26bff967e 100644 --- a/BizHawk.Client.EmuHawk/OpenAdvanced.cs +++ b/BizHawk.Client.Common/OpenAdvanced.cs @@ -10,7 +10,7 @@ using Newtonsoft.Json; //this file contains some cumbersome self-"serialization" in order to gain a modicum of control over what the serialized output looks like //I don't want them to look like crufty json -namespace BizHawk.Client.EmuHawk +namespace BizHawk.Client.Common { public interface IOpenAdvanced { @@ -74,7 +74,7 @@ namespace BizHawk.Client.EmuHawk } } - class OpenAdvanced_Libretro : IOpenAdvanced, IOpenAdvancedLibretro + public class OpenAdvanced_Libretro : IOpenAdvanced, IOpenAdvancedLibretro { public OpenAdvanced_Libretro() { @@ -103,7 +103,7 @@ namespace BizHawk.Client.EmuHawk public string CorePath { get { return token.CorePath; } set { token.CorePath = value; } } } - class OpenAdvanced_LibretroNoGame : IOpenAdvanced, IOpenAdvancedLibretro + public class OpenAdvanced_LibretroNoGame : IOpenAdvanced, IOpenAdvancedLibretro { //you might think ideally we'd fetch the libretro core name from the core info inside it //but that would involve spinning up excess libretro core instances, which probably isnt good for stability, no matter how much we wish otherwise, not to mention slow. @@ -140,7 +140,7 @@ namespace BizHawk.Client.EmuHawk public string CorePath { get { return _corePath; } set { _corePath = value; } } } - class OpenAdvanced_OpenRom : IOpenAdvanced + public class OpenAdvanced_OpenRom : IOpenAdvanced { public OpenAdvanced_OpenRom() {} diff --git a/BizHawk.Client.Common/plugins/IPluginAPI.cs b/BizHawk.Client.Common/plugins/IPluginAPI.cs deleted file mode 100644 index 175df3af92..0000000000 --- a/BizHawk.Client.Common/plugins/IPluginAPI.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace BizHawk.Client.Common -{ - public interface IPluginAPI - { - EmulatorPluginLibrary EmuLib { get; } - GameInfoPluginLibrary GameInfoLib { get; } - GUIDrawPluginBase GUILib { get; } - JoypadPluginLibrary JoypadLib { get; } - MemoryPluginLibrary MemLib { get; } - MemoryEventsPluginLibrary MemEventsLib { get; } - MemorySavestatePluginLibrary MemStateLib { get; } - MoviePluginLibrary MovieLib { get; } - SQLPluginLibrary SQLLib { get; } - UserDataPluginLibrary UserDataLib { get; } - Dictionary Libraries { get; } - } -} diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs b/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs deleted file mode 100644 index ac9552d9cd..0000000000 --- a/BizHawk.Client.Common/plugins/PluginLibrary.Movie.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; - -namespace BizHawk.Client.Common -{ - public sealed class MoviePluginLibrary : PluginLibraryBase - { - public MoviePluginLibrary() : base() - { } - - [LuaMethodExample("if ( movie.startsfromsavestate( ) ) then\r\n\tconsole.log( \"Returns whether or not the movie is a savestate-anchored movie\" );\r\nend;")] - [LuaMethod("startsfromsavestate", "Returns whether or not the movie is a savestate-anchored movie")] - public bool StartsFromSavestate() - { - return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSavestate; - } - - [LuaMethodExample("if ( movie.startsfromsaveram( ) ) then\r\n\tconsole.log( \"Returns whether or not the movie is a saveram-anchored movie\" );\r\nend;")] - [LuaMethod("startsfromsaveram", "Returns whether or not the movie is a saveram-anchored movie")] - public bool StartsFromSaveram() - { - return Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.StartsFromSaveRam; - } - - [LuaMethodExample("local stmovfil = movie.filename( );")] - [LuaMethod("filename", "Returns the file name including path of the currently loaded movie")] - public static string Filename() - { - return Global.MovieSession.Movie.Filename; - } - - [LuaMethodExample("local nlmovget = movie.getinput( 500 );")] - [LuaMethod("getinput", "Returns a table of buttons pressed on a given frame of the loaded movie")] - public Dictionary GetInput(int frame) - { - if (!Global.MovieSession.Movie.IsActive) - { - Console.WriteLine("No movie loaded"); - return null; - } - - var input = new Dictionary(); - var adapter = Global.MovieSession.Movie.GetInputState(frame); - - if (adapter == null) - { - Console.WriteLine("Can't get input of the last frame of the movie. Use the previous frame"); - return null; - } - - foreach (var button in adapter.Definition.BoolButtons) - { - input[button] = adapter.IsPressed(button); - } - - foreach (var button in adapter.Definition.FloatControls) - { - input[button] = adapter.GetFloat(button); - } - - return input; - } - - [LuaMethodExample("local stmovget = movie.getinputasmnemonic( 500 );")] - [LuaMethod("getinputasmnemonic", "Returns the input of a given frame of the loaded movie in a raw inputlog string")] - public string GetInputAsMnemonic(int frame) - { - if (Global.MovieSession.Movie.IsActive && frame < Global.MovieSession.Movie.InputLogLength) - { - var lg = Global.MovieSession.LogGeneratorInstance(); - lg.SetSource(Global.MovieSession.Movie.GetInputState(frame)); - return lg.GenerateLogEntry(); - } - - return ""; - } - - [LuaMethodExample("if ( movie.getreadonly( ) ) then\r\n\tconsole.log( \"Returns true if the movie is in read-only mode, false if in read+write\" );\r\nend;")] - [LuaMethod("getreadonly", "Returns true if the movie is in read-only mode, false if in read+write")] - public static bool GetReadOnly() - { - return Global.MovieSession.ReadOnly; - } - - [LuaMethodExample("local ulmovget = movie.getrerecordcount();")] - [LuaMethod("getrerecordcount", "Gets the rerecord count of the current movie.")] - public static ulong GetRerecordCount() - { - return Global.MovieSession.Movie.Rerecords; - } - - [LuaMethodExample("if ( movie.getrerecordcounting( ) ) then\r\n\tconsole.log( \"Returns whether or not the current movie is incrementing rerecords on loadstate\" );\r\nend;")] - [LuaMethod("getrerecordcounting", "Returns whether or not the current movie is incrementing rerecords on loadstate")] - public static bool GetRerecordCounting() - { - return Global.MovieSession.Movie.IsCountingRerecords; - } - - [LuaMethodExample("if ( movie.isloaded( ) ) then\r\n\tconsole.log( \"Returns true if a movie is loaded in memory ( play, record, or finished modes ), false if not ( inactive mode )\" );\r\nend;")] - [LuaMethod("isloaded", "Returns true if a movie is loaded in memory (play, record, or finished modes), false if not (inactive mode)")] - public static bool IsLoaded() - { - return Global.MovieSession.Movie.IsActive; - } - - [LuaMethodExample("local domovlen = movie.length( );")] - [LuaMethod("length", "Returns the total number of frames of the loaded movie")] - public static double Length() - { - return Global.MovieSession.Movie.FrameCount; - } - - [LuaMethodExample("local stmovmod = movie.mode( );")] - [LuaMethod("mode", "Returns the mode of the current movie. Possible modes: \"PLAY\", \"RECORD\", \"FINISHED\", \"INACTIVE\"")] - public static string Mode() - { - if (Global.MovieSession.Movie.IsFinished) - { - return "FINISHED"; - } - - if (Global.MovieSession.Movie.IsPlaying) - { - return "PLAY"; - } - - if (Global.MovieSession.Movie.IsRecording) - { - return "RECORD"; - } - - return "INACTIVE"; - } - - [LuaMethodExample("movie.save( \"C:\\moviename.ext\" );")] - [LuaMethod("save", "Saves the current movie to the disc. If the filename is provided (no extension or path needed), the movie is saved under the specified name to the current movie directory. The filename may contain a subdirectory, it will be created if it doesn't exist. Existing files won't get overwritten.")] - public void Save(string filename = "") - { - if (!Global.MovieSession.Movie.IsActive) - { - return; - } - - if (!string.IsNullOrEmpty(filename)) - { - filename += "." + Global.MovieSession.Movie.PreferredExtension; - var test = new FileInfo(filename); - if (test.Exists) - { - Console.WriteLine($"File {filename} already exists, will not overwrite"); - return; - } - - Global.MovieSession.Movie.Filename = filename; - } - - Global.MovieSession.Movie.Save(); - } - - [LuaMethodExample("movie.setreadonly( false );")] - [LuaMethod("setreadonly", "Sets the read-only state to the given value. true for read only, false for read+write")] - public static void SetReadOnly(bool readOnly) - { - Global.MovieSession.ReadOnly = readOnly; - } - - [LuaMethodExample("movie.setrerecordcount( 20.0 );")] - [LuaMethod("setrerecordcount", "Sets the rerecord count of the current movie.")] - public static void SetRerecordCount(double count) - { - // Lua numbers are always double, integer precision holds up - // to 53 bits, so throw an error if it's bigger than that. - const double PrecisionLimit = 9007199254740992d; - - if (count > PrecisionLimit) - { - throw new Exception("Rerecord count exceeds Lua integer precision."); - } - - Global.MovieSession.Movie.Rerecords = (ulong)count; - } - - [LuaMethodExample("movie.setrerecordcounting( true );")] - [LuaMethod("setrerecordcounting", "Sets whether or not the current movie will increment the rerecord counter on loadstate")] - public static void SetRerecordCounting(bool counting) - { - Global.MovieSession.Movie.IsCountingRerecords = counting; - } - - [LuaMethodExample("movie.stop( );")] - [LuaMethod("stop", "Stops the current movie")] - public static void Stop() - { - Global.MovieSession.Movie.Stop(); - } - - [LuaMethodExample("local domovget = movie.getfps( );")] - [LuaMethod("getfps", "If a movie is loaded, gets the frames per second used by the movie to determine the movie length time")] - public static double GetFps() - { - if (Global.MovieSession.Movie.IsActive) - { - var movie = Global.MovieSession.Movie; - var system = movie.HeaderEntries[HeaderKeys.PLATFORM]; - var pal = movie.HeaderEntries.ContainsKey(HeaderKeys.PAL) && - movie.HeaderEntries[HeaderKeys.PAL] == "1"; - - return new PlatformFrameRates()[system, pal]; - } - - return 0.0; - } - - [LuaMethodExample("local nlmovget = movie.getheader( );")] - [LuaMethod("getheader", "If a movie is active, will return the movie header as a lua table")] - public Dictionary GetHeader() - { - var table = new Dictionary(); - if (Global.MovieSession.Movie.IsActive) - { - foreach (var kvp in Global.MovieSession.Movie.HeaderEntries) - { - table[kvp.Key] = kvp.Value; - } - } - - return table; - } - - [LuaMethodExample("local nlmovget = movie.getcomments( );")] - [LuaMethod("getcomments", "If a movie is active, will return the movie comments as a lua table")] - public List GetComments() - { - var list = new List(Global.MovieSession.Movie.Comments.Count); - if (Global.MovieSession.Movie.IsActive) - { - for (int i = 0; i < Global.MovieSession.Movie.Comments.Count; i++) - { - list[i] = Global.MovieSession.Movie.Comments[i]; - } - } - - return list; - } - - [LuaMethodExample("local nlmovget = movie.getsubtitles( );")] - [LuaMethod("getsubtitles", "If a movie is active, will return the movie subtitles as a lua table")] - public List GetSubtitles() - { - var list = new List(Global.MovieSession.Movie.Subtitles.Count); - if (Global.MovieSession.Movie.IsActive) - { - for (int i = 0; i < Global.MovieSession.Movie.Subtitles.Count; i++) - { - list[i] = Global.MovieSession.Movie.Subtitles[i].ToString(); - } - } - - return list; - } - } -} diff --git a/BizHawk.Client.Common/plugins/PluginLibraryBase.cs b/BizHawk.Client.Common/plugins/PluginLibraryBase.cs deleted file mode 100644 index 17485c7103..0000000000 --- a/BizHawk.Client.Common/plugins/PluginLibraryBase.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Drawing; - -namespace BizHawk.Client.Common -{ - public abstract class PluginLibraryBase - { - protected PluginLibraryBase() { } - - protected static Color? ToColor(object o) - { - if (o == null) - { - return null; - } - - if (o.GetType() == typeof(double)) - { - return Color.FromArgb((int)(long)(double)o); - } - - if (o.GetType() == typeof(string)) - { - return Color.FromName(o.ToString()); - } - - return null; - } - } -} diff --git a/BizHawk.Client.EmuHawk/Api/ApiContainer.cs b/BizHawk.Client.EmuHawk/Api/ApiContainer.cs new file mode 100644 index 0000000000..6a7b7102a3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Api/ApiContainer.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; + +using BizHawk.Client.ApiHawk; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class ApiContainer : IApiContainer + { + public IComm Comm => (IComm)Libraries[typeof(CommApi)]; + public IEmu Emu => (IEmu)Libraries[typeof(EmuApi)]; + public IGameInfo GameInfo => (IGameInfo)Libraries[typeof(GameInfoApi)]; + public IGui Gui => (IGui)Libraries[typeof(GuiApi)]; + public IInput Input => (IInput)Libraries[typeof(InputApi)]; + public IJoypad Joypad => (IJoypad)Libraries[typeof(JoypadApi)]; + public IMem Mem => (IMem)Libraries[typeof(MemApi)]; + public IMemEvents MemEvents => (IMemEvents)Libraries[typeof(MemEventsApi)]; + public IMemorySaveState MemorySaveState => (IMemorySaveState)Libraries[typeof(MemorySaveStateApi)]; + public IMovie Movie => (IMovie)Libraries[typeof(MovieApi)]; + public ISaveState SaveState => (ISaveState)Libraries[typeof(SaveStateApi)]; + public ISql Sql => (ISql)Libraries[typeof(SqlApi)]; + public ITool Tool => (ITool)Libraries[typeof(ToolApi)]; + public IUserData UserData => (IUserData)Libraries[typeof(UserDataApi)]; + public Dictionary Libraries { get; set; } + public ApiContainer(Dictionary libs) + { + Libraries = libs; + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs b/BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs similarity index 51% rename from BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs rename to BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs index e7ed248bfb..8764258e3d 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Example/Ecco2AssistantPlugin.cs +++ b/BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs @@ -4,13 +4,31 @@ using System.Globalization; using System.Drawing; using System.Linq; -using BizHawk.Client.Common; +using BizHawk.Client.ApiHawk; using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; namespace BizHawk.Client.EmuHawk { public sealed class Ecco2AssistantPlugin : PluginBase { + [RequiredApi] + private IMem Mem {get; set;} + + [RequiredApi] + private IGui Gui { get; set; } + + [RequiredApi] + private IJoypad Joy { get; set; } + + [RequiredApi] + private IEmu Emu { get; set; } + + [RequiredApi] + private IGameInfo GI { get; set; } + + [RequiredApi] + private IMemorySaveState MemSS { get; set; } + public override string Name => "Ecco 2 Assistant"; public override string Description => "Displays a hud with hitboxes, etc. Assists with maintaining maximum speed."; @@ -36,7 +54,6 @@ namespace BizHawk.Client.EmuHawk private int _destY = 0; private int _snapPast = 0; private string _rowStateGuid = string.Empty; - private EmuHawkPluginLibrary _clientLib; private Color[] _turnSignalColors = { Color.FromArgb(_signalAlpha, 127, 127, 0), @@ -53,7 +70,7 @@ namespace BizHawk.Client.EmuHawk { if (refresh) { - _rseed = (int)(_api.MemLib.ReadU16(0xFFE2F8)); + _rseed = (int)(Mem.ReadU16(0xFFE2F8)); } bool odd = (_rseed & 1) != 0; _rseed >>= 1; @@ -73,7 +90,7 @@ namespace BizHawk.Client.EmuHawk }; Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawPolygon(rhombus, color, fillColor); + Gui.DrawPolygon(rhombus, color, fillColor); } private void DrawEccoRhomb_scaled(int x, int y, int width, int height, int rscale, int bscale, int lscale, int tscale, Color color, int fillAlpha = 63) { @@ -85,7 +102,7 @@ namespace BizHawk.Client.EmuHawk }; Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawPolygon(rhombus, color, fillColor); + Gui.DrawPolygon(rhombus, color, fillColor); } private void DrawEccoOct(int x, int y, int r, Color color, int fillAlpha = 63) { @@ -102,7 +119,7 @@ namespace BizHawk.Client.EmuHawk }; Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawPolygon(octagon, color, fillColor); + Gui.DrawPolygon(octagon, color, fillColor); } private void DrawEccoOct_scaled(int x, int y, int xscale, int yscale, int r, Color color, int fillAlpha = 63) { @@ -123,7 +140,7 @@ namespace BizHawk.Client.EmuHawk }; Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawPolygon(octagon, color, fillColor); + Gui.DrawPolygon(octagon, color, fillColor); } private Point? Intersection(Point start1, Point end1, Point start2, Point end2) { @@ -203,7 +220,7 @@ namespace BizHawk.Client.EmuHawk my /= finalShape.ToArray().Length; Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawPolygon(finalShape.OrderBy(p => Math.Atan2(p.Y - my, p.X - mX)).ToArray(), color, fillColor); + Gui.DrawPolygon(finalShape.OrderBy(p => Math.Atan2(p.Y - my, p.X - mX)).ToArray(), color, fillColor); } private void DrawEccoTriangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color, int fillAlpha = 63) { @@ -215,23 +232,23 @@ namespace BizHawk.Client.EmuHawk new Point(x3, y3) }; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawPolygon(triPoints, color, fillColor); + Gui.DrawPolygon(triPoints, color, fillColor); } private void DrawBoxMWH(int x, int y, int w, int h, Color color, int fillAlpha = 63) { Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawRectangle(x - w, y - h, w << 1, h << 1, color, fillColor); + Gui.DrawRectangle(x - w, y - h, w << 1, h << 1, color, fillColor); } private void DrawBox(int x, int y, int x2, int y2, Color color, int fillAlpha = 63) { Color? fillColor = null; if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - _api.GUILib.DrawBox(x, y, x2, y2, color, fillColor); + Gui.DrawBox(x, y, x2, y2, color, fillColor); } private void Print_Text(string message, int x, int y, Color color) { - _api.GUILib.DrawText(x, y, message, color, null); + Gui.DrawText(x, y, message, color, null); } private void PutText(string message, int x, int y, int xl, int yl, int xh, int yh, Color bg, Color fg) { @@ -253,24 +270,24 @@ namespace BizHawk.Client.EmuHawk private void TickerText(string message, Color? fg = null) { if (_dumpMap == 0) - _api.GUILib.Text(1, _tickerY, message, fg); + Gui.Text(1, _tickerY, message, fg); _tickerY += 16; } private void EccoDraw3D() { - int CamX = (_api.MemLib.ReadS32(0xFFD5E0) >> 0xC) - _left; - int CamY = (_api.MemLib.ReadS32(0xFFD5E8) >> 0xC) + _top; - int CamZ = (_api.MemLib.ReadS32(0xFFD5E4) >> 0xC) + _top; - uint curObj = _api.MemLib.ReadU24(0xFFD4C1); + int CamX = (Mem.ReadS32(0xFFD5E0) >> 0xC) - _left; + int CamY = (Mem.ReadS32(0xFFD5E8) >> 0xC) + _top; + int CamZ = (Mem.ReadS32(0xFFD5E4) >> 0xC) + _top; + uint curObj = Mem.ReadU24(0xFFD4C1); while (curObj != 0) { - int Xpos = (_api.MemLib.ReadS32(curObj + 0x6) >> 0xC); - int Ypos = (_api.MemLib.ReadS32(curObj + 0xE) >> 0xC); - int Zpos = (_api.MemLib.ReadS32(curObj + 0xA) >> 0xC); + int Xpos = (Mem.ReadS32(curObj + 0x6) >> 0xC); + int Ypos = (Mem.ReadS32(curObj + 0xE) >> 0xC); + int Zpos = (Mem.ReadS32(curObj + 0xA) >> 0xC); int Xmid = 160 + (Xpos - CamX); int Ymid = 112 - (Ypos - CamY); int Zmid = _top + 112 - (Zpos - CamZ); - uint type = _api.MemLib.ReadU32(curObj + 0x5A); + uint type = Mem.ReadU32(curObj + 0x5A); int width, height, depth = height = width = 0; if (type == 0xD4AB8) // 3D poison Bubble { @@ -285,23 +302,23 @@ namespace BizHawk.Client.EmuHawk else if (type == 0xD817E)// 3D Ring { depth = 8; - if (_api.MemLib.ReadU32(0xFFB166) < 0x1800) depth = 4; + if (Mem.ReadU32(0xFFB166) < 0x1800) depth = 4; int radius = 32; width = radius; - DrawEccoOct(Xmid, Ymid, radius, (_api.MemLib.ReadS16(curObj + 0x62) == 0) ? Color.Orange : Color.Gray); + DrawEccoOct(Xmid, Ymid, radius, (Mem.ReadS16(curObj + 0x62) == 0) ? Color.Orange : Color.Gray); DrawBoxMWH(Xmid, Zmid, width, depth, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Red, 0); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x6) / 4096.0:0.######}:{_api.MemLib.ReadS32(curObj + 0xE) / 4096.0:0.######}:{_api.MemLib.ReadS32(curObj + 0xA) / 2048.0:0.######}:{_api.MemLib.ReadByte(curObj + 0x72)}",Color.Lime); + TickerText($"{Mem.ReadS32(curObj + 0x6) / 4096.0:0.######}:{Mem.ReadS32(curObj + 0xE) / 4096.0:0.######}:{Mem.ReadS32(curObj + 0xA) / 2048.0:0.######}:{Mem.ReadByte(curObj + 0x72)}",Color.Lime); } else if (type == 0xD49CC) // Vines collisions are based on draw position, which is a fucking pain in the ass to calculate { - int Xvel = (_api.MemLib.ReadS32(curObj + 0x3A) - _api.MemLib.ReadS32(curObj + 0x6)); - int Zvel = (_api.MemLib.ReadS32(curObj + 0x3E) - _api.MemLib.ReadS32(curObj + 0xA)); - int dx = _api.MemLib.ReadS32(0xFFD5E0) - _api.MemLib.ReadS32(0xFFD5C8) >> 3; - int dy = _api.MemLib.ReadS32(0xFFD5E8) - _api.MemLib.ReadS32(0xFFD600) >> 3; - int dz = _api.MemLib.ReadS32(0xFFD5E4) - _api.MemLib.ReadS32(0xFFD5CC); - var chargeCount = _api.MemLib.ReadByte(0xFFB19B); + int Xvel = (Mem.ReadS32(curObj + 0x3A) - Mem.ReadS32(curObj + 0x6)); + int Zvel = (Mem.ReadS32(curObj + 0x3E) - Mem.ReadS32(curObj + 0xA)); + int dx = Mem.ReadS32(0xFFD5E0) - Mem.ReadS32(0xFFD5C8) >> 3; + int dy = Mem.ReadS32(0xFFD5E8) - Mem.ReadS32(0xFFD600) >> 3; + int dz = Mem.ReadS32(0xFFD5E4) - Mem.ReadS32(0xFFD5CC); + var chargeCount = Mem.ReadByte(0xFFB19B); if (chargeCount == 0) { dz >>= 2; @@ -314,7 +331,7 @@ namespace BizHawk.Client.EmuHawk { dz >>= 4; } - if (_api.MemLib.ReadByte(curObj + 0x64) == 0) + if (Mem.ReadByte(curObj + 0x64) == 0) { Xvel >>= 0xA; Zvel >>= 9; @@ -324,21 +341,21 @@ namespace BizHawk.Client.EmuHawk Xvel >>= 9; Zvel >>= 0xA; } - Xvel += _api.MemLib.ReadS32(curObj + 0x2E); - Zvel += _api.MemLib.ReadS32(curObj + 0x32); - Zpos = (_api.MemLib.ReadS32(curObj + 0x26) + dz - _api.MemLib.ReadS32(0xFFD5E4)) >> 0xB; + Xvel += Mem.ReadS32(curObj + 0x2E); + Zvel += Mem.ReadS32(curObj + 0x32); + Zpos = (Mem.ReadS32(curObj + 0x26) + dz - Mem.ReadS32(0xFFD5E4)) >> 0xB; if ((Zpos < 0x600) && (Zpos > 0)) { Zpos += 0x20; int Xcur, Xmax, Ycur, Ymax; - int Zpos2 = (_api.MemLib.ReadS32(curObj + 0xA) + Zvel + dz - _api.MemLib.ReadS32(0xFFD5E4)) >> 0xB; + int Zpos2 = (Mem.ReadS32(curObj + 0xA) + Zvel + dz - Mem.ReadS32(0xFFD5E4)) >> 0xB; Zpos2 = Math.Max(Zpos2 + 0x20, 1); - if (_api.MemLib.ReadS16(curObj + 0x62) != 0) + if (Mem.ReadS16(curObj + 0x62) != 0) { - Xmid = _api.MemLib.ReadS32(curObj + 0x6) + dx + Xvel - _api.MemLib.ReadS32(0xFFD5E0); + Xmid = Mem.ReadS32(curObj + 0x6) + dx + Xvel - Mem.ReadS32(0xFFD5E0); if (Math.Abs(Xmid) > 0x400000) continue; - Xpos = _api.MemLib.ReadS32(curObj + 0x22) + dx - _api.MemLib.ReadS32(0xFFD5E0); + Xpos = Mem.ReadS32(curObj + 0x22) + dx - Mem.ReadS32(0xFFD5E0); if (Math.Abs(Xpos) > 0x400000) continue; Xcur = (Xmid << 2) / Zpos2 + (Xmid >> 5) + 0xA000 + (Xmid >> 5); @@ -349,9 +366,9 @@ namespace BizHawk.Client.EmuHawk Xcur = 0; Xmax = 256; } - Ymid = _api.MemLib.ReadS32(0xFFD5E8) + dy - _api.MemLib.ReadS32(curObj + 0xE); + Ymid = Mem.ReadS32(0xFFD5E8) + dy - Mem.ReadS32(curObj + 0xE); Ycur = ((Ymid << 3) / Zpos2) + 0x6000; - Ypos = _api.MemLib.ReadS32(0xFFD5E8) + dy - _api.MemLib.ReadS32(curObj + 0x2A); + Ypos = Mem.ReadS32(0xFFD5E8) + dy - Mem.ReadS32(curObj + 0x2A); Ymax = ((Ypos << 3) / Zpos) + 0x6000; dx = Xmax - Xcur; dy = Ymax - Ycur; @@ -423,8 +440,8 @@ namespace BizHawk.Client.EmuHawk } } } - Xcur += _api.MemLib.ReadS8(0x2CC8 + ang) << 6; - Ycur += _api.MemLib.ReadS8(0x2BC8 + ang) << 6; + Xcur += Mem.ReadS8(0x2CC8 + ang) << 6; + Ycur += Mem.ReadS8(0x2BC8 + ang) << 6; var dSml = Math.Abs(dx); var dBig = Math.Abs(dy); if (dBig < dSml) @@ -438,7 +455,7 @@ namespace BizHawk.Client.EmuHawk dx /= i; dy /= i; - Zmid = (_api.MemLib.ReadS32(curObj + 0xA) + _api.MemLib.ReadS32(curObj + 0x26)) >> 1; + Zmid = (Mem.ReadS32(curObj + 0xA) + Mem.ReadS32(curObj + 0x26)) >> 1; Zmid >>= 0xC; Zmid = 112 + _top - (Zmid - CamZ); do @@ -449,14 +466,14 @@ namespace BizHawk.Client.EmuHawk Xcur += dx; Ycur += dy; } while (i >= 0); - DrawBoxMWH((_api.MemLib.ReadS32(0xFFB1AA) >> 8) + _left, (_api.MemLib.ReadS32(0xFFB1AE) >> 8) + _top, 1, 1, Color.Lime, 0); + DrawBoxMWH((Mem.ReadS32(0xFFB1AA) >> 8) + _left, (Mem.ReadS32(0xFFB1AE) >> 8) + _top, 1, 1, Color.Lime, 0); } } else if ((type == 0xD3B40) || (type == 0xD3DB2)) // 3D Shark and Jellyfish { - width = (_api.MemLib.ReadS32(curObj + 0x12) >> 0xC); - height = (_api.MemLib.ReadS32(curObj + 0x1A) >> 0xC); - depth = (_api.MemLib.ReadS32(curObj + 0x16) >> 0xC); + width = (Mem.ReadS32(curObj + 0x12) >> 0xC); + height = (Mem.ReadS32(curObj + 0x1A) >> 0xC); + depth = (Mem.ReadS32(curObj + 0x16) >> 0xC); DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); DrawBoxMWH(Xmid, Zmid, width, depth, Color.Blue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); @@ -502,7 +519,7 @@ namespace BizHawk.Client.EmuHawk DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Red); } } - curObj = _api.MemLib.ReadU24(curObj+1); + curObj = Mem.ReadU24(curObj+1); } } private void EccoDrawBoxes() @@ -511,8 +528,8 @@ namespace BizHawk.Client.EmuHawk int Width2, Height2; //Ecco HP and Air int i = 0; - int HP = _api.MemLib.ReadS16(0xFFAA16) << 3; - int air = _api.MemLib.ReadS16(0xFFAA18); + int HP = Mem.ReadS16(0xFFAA16) << 3; + int air = Mem.ReadS16(0xFFAA18); Color color; int off = 0; for (int j = 0; j < air; j++) @@ -522,66 +539,66 @@ namespace BizHawk.Client.EmuHawk i++; off += 448; } color = Color.FromArgb(j >> 2, j >> 2, j >> 2); - _api.GUILib.DrawLine(_left - 32, j - off, _left - 17, j - off, color); + Gui.DrawLine(_left - 32, j - off, _left - 17, j - off, color); } for (int j = 0; j < HP; j += 8) { color = Color.FromArgb(Math.Max(0x38 - (j >> 3),0), 0, Math.Min(j >> 1,255)); - _api.GUILib.DrawRectangle(_left - 16, j, 15, 7, color, color); + Gui.DrawRectangle(_left - 16, j, 15, 7, color, color); } //Asterite - uint type = _api.MemLib.ReadU32(0xFFD440); + uint type = Mem.ReadU32(0xFFD440); uint curObj = 0; int Xpos, Xpos2, Ypos, Ypos2, Xmid, Ymid, X, X2, Y, Y2; Xpos = Ypos = Xpos2 = Ypos2 = Xmid = Ymid = X = X2 = Y = Y2 = 0; if (type == 0xB119A) { - curObj = _api.MemLib.ReadU24(_api.MemLib.ReadU24(0xFFD429)+5); + curObj = Mem.ReadU24(Mem.ReadU24(0xFFD429)+5); while (curObj != 0) { - Xpos = _api.MemLib.ReadS16(curObj + 0x3C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x24); - Ypos = _api.MemLib.ReadS16(curObj + 0x40); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x3C); + Xpos2 = Mem.ReadS16(curObj + 0x24); + Ypos = Mem.ReadS16(curObj + 0x40); + Ypos2 = Mem.ReadS16(curObj + 0x28); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; - if (_api.MemLib.ReadU8(curObj + 0x71) != 0) + if (Mem.ReadU8(curObj + 0x71) != 0) { DrawEccoOct(Xpos, Ypos, 48, Color.Blue, 16); DrawEccoOct(Xpos2, Ypos2, 48, Color.Blue, 16); } - curObj = _api.MemLib.ReadU24(curObj + 5); + curObj = Mem.ReadU24(curObj + 5); } - if ((_api.MemLib.ReadU8(0xFFA7D0) == 30)) + if ((Mem.ReadU8(0xFFA7D0) == 30)) { - curObj = _api.MemLib.ReadU24(0xFFD425); - if ((curObj != 0) && (_api.MemLib.ReadU32(curObj + 8) != 0)) + curObj = Mem.ReadU24(0xFFD425); + if ((curObj != 0) && (Mem.ReadU32(curObj + 8) != 0)) { - Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; + Ypos = Mem.ReadS16(curObj + 0x20) - _camY; DrawEccoOct(Xpos, Ypos, 20, Color.Orange); } } } else if (type == 0xB2CB8) { - curObj = _api.MemLib.ReadU24(_api.MemLib.ReadU24(0xFFD429) + 5); + curObj = Mem.ReadU24(Mem.ReadU24(0xFFD429) + 5); while (curObj != 0) { - Xpos = _api.MemLib.ReadS16(curObj + 0x3C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x24); - Ypos = _api.MemLib.ReadS16(curObj + 0x40); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x3C); + Xpos2 = Mem.ReadS16(curObj + 0x24); + Ypos = Mem.ReadS16(curObj + 0x40); + Ypos2 = Mem.ReadS16(curObj + 0x28); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; - if (_api.MemLib.ReadU8(curObj + 0x71) != 0) + if (Mem.ReadU8(curObj + 0x71) != 0) { - if (_api.MemLib.ReadByte(0xFFA7D0) != 0x1F) + if (Mem.ReadByte(0xFFA7D0) != 0x1F) { DrawEccoOct(Xpos, Ypos, 40, Color.Lime); DrawEccoOct(Xpos2, Ypos2, 40, Color.Lime); @@ -589,23 +606,23 @@ namespace BizHawk.Client.EmuHawk DrawEccoOct(Xpos, Ypos, 48, Color.Blue, 16); DrawEccoOct(Xpos2, Ypos2, 48, Color.Blue, 16); } - curObj = _api.MemLib.ReadU24(curObj + 5); + curObj = Mem.ReadU24(curObj + 5); } } //aqua tubes - curObj = _api.MemLib.ReadU24(0xFFCFC5); + curObj = Mem.ReadU24(0xFFCFC5); while (curObj != 0) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2= _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2= _api.MemLib.ReadS16(curObj + 0x38); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2= Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2= Mem.ReadS16(curObj + 0x38); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; // displayed = false; - type = _api.MemLib.ReadU8(curObj + 0x7E); + type = Mem.ReadU8(curObj + 0x7E); switch (type) { case 0x15: @@ -639,7 +656,7 @@ namespace BizHawk.Client.EmuHawk new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), new Point(Xpos2, Ymid) }; - _api.GUILib.DrawPolygon(trapPoints, Color.Purple, Color.FromArgb(63, Color.Purple)); + Gui.DrawPolygon(trapPoints, Color.Purple, Color.FromArgb(63, Color.Purple)); break; default: DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Purple); @@ -647,22 +664,22 @@ namespace BizHawk.Client.EmuHawk PutText(type.ToString("X2"), Xmid, Ymid, 1, 1, -1, -1, Color.Red, Color.Blue); break; } - curObj = _api.MemLib.ReadU24(curObj+1); + curObj = Mem.ReadU24(curObj+1); } //walls - curObj = _api.MemLib.ReadU24(0xFFCFC1); + curObj = Mem.ReadU24(0xFFCFC1); while (curObj != 0) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24); - Xmid = _api.MemLib.ReadS16(curObj + 0x28); - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2= _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2= _api.MemLib.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS16(curObj + 0x24); + Xmid = Mem.ReadS16(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2= Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2= Mem.ReadS16(curObj + 0x38); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - int colltype = _api.MemLib.ReadS8(curObj + 0x7E); + int colltype = Mem.ReadS8(curObj + 0x7E); switch (colltype) { case 0x10: @@ -674,25 +691,25 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Xpos2 = Xmid; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.PowderBlue); + Gui.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.PowderBlue); break; case 0x12: Xmid = (Xpos + Xpos2) >> 1; Xpos = Xmid; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos, Ypos2, Color.PowderBlue); + Gui.DrawLine(Xpos, Ypos, Xpos, Ypos2, Color.PowderBlue); break; case 0x13: Ymid = (Ypos + Ypos2) >> 1; Ypos = Ymid; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.PowderBlue); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.PowderBlue); break; case 0x14: Ymid = (Ypos + Ypos2) >> 1; Ypos2 = Ymid; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.PowderBlue); + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.PowderBlue); break; case 0x15: case 0x16: @@ -702,7 +719,7 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); + Gui.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); break; case 0x1A: case 0x1B: @@ -712,7 +729,7 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); + Gui.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); break; case 0x1F: case 0x20: @@ -722,7 +739,7 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.FromArgb(63,Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); + Gui.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); break; case 0x24: case 0x25: @@ -732,17 +749,17 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.FromArgb(63,Color.Yellow)); - _api.GUILib.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); + Gui.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); break; case 0x29: DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); - _api.GUILib.DrawLine(Xpos , Ypos, Xpos , Ypos2, Color.Black); - _api.GUILib.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.Black); + Gui.DrawLine(Xpos , Ypos, Xpos , Ypos2, Color.Black); + Gui.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.Black); break; case 0x2A: DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); break; case 0x2B: Xmid = (Xpos + Xpos2) >> 1; @@ -754,45 +771,45 @@ namespace BizHawk.Client.EmuHawk new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), new Point(Xpos2, Ymid) }; - _api.GUILib.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); - //_api.GUILib.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.Yellow); + Gui.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); + //Gui.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.Yellow); break; default: - DrawEccoRhomb_scaled(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); + DrawEccoRhomb_scaled(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); break; } - curObj = _api.MemLib.ReadU24(curObj+1); + curObj = Mem.ReadU24(curObj+1); } //inanimate objects - curObj = _api.MemLib.ReadU24(0xFFCFBD); + curObj = Mem.ReadU24(0xFFCFBD); while (curObj != 0) { - type = _api.MemLib.ReadU32(curObj + 0xC); - int colltype = _api.MemLib.ReadS8(curObj + 0x7E); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - int Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - int Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + type = Mem.ReadU32(curObj + 0xC); + int colltype = Mem.ReadS8(curObj + 0x7E); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + int Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + int Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; if (type == 0x9CE3A) //Remnant Stars { - uint subObj = _api.MemLib.ReadU24(curObj + 0x5); - uint anim = _api.MemLib.ReadU16(curObj + 0x6C); + uint subObj = Mem.ReadU24(curObj + 0x5); + uint anim = Mem.ReadU16(curObj + 0x6C); if ((anim <= 7) && (subObj == 0xFFA9D4)) { DrawEccoRhomb(Xmid, Ymid, 96, Color.Red); - PutText($"{((7 - anim) * 4) - ((_api.MemLib.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Lime, Color.Blue); + PutText($"{((7 - anim) * 4) - ((Mem.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Lime, Color.Blue); } } else if ((type == 0x9CC06) || (type == 0x9CA10)) { - Xvec = ((_api.MemLib.ReadS32(curObj + 0x24) + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((_api.MemLib.ReadS32(curObj + 0x28) + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xvec = ((Mem.ReadS32(curObj + 0x24) + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Mem.ReadS32(curObj + 0x28) + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; } else if (type == 0x9B5D8) { @@ -801,27 +818,27 @@ namespace BizHawk.Client.EmuHawk } else if (type == 0xC0152) // Vortex Future Vertical Gate { - Xvec = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Yvec = (_api.MemLib.ReadS32(curObj + 0x20) + _api.MemLib.ReadS32(curObj + 0x60) >> 16) - _camY; - _api.GUILib.DrawLine(Xmid, 0, Xmid, 448, Color.PowderBlue); + Xvec = Mem.ReadS16(curObj + 0x1C) - _camX; + Yvec = (Mem.ReadS32(curObj + 0x20) + Mem.ReadS32(curObj + 0x60) >> 16) - _camY; + Gui.DrawLine(Xmid, 0, Xmid, 448, Color.PowderBlue); DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); } else if (type == 0xC3330) // City Of Forever Horizontal Gate Slave { - Xvec = (_api.MemLib.ReadS32(curObj + 0x1C) + _api.MemLib.ReadS32(curObj + 0x5C) >> 16) - _camX; - Yvec = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + Xvec = (Mem.ReadS32(curObj + 0x1C) + Mem.ReadS32(curObj + 0x5C) >> 16) - _camX; + Yvec = Mem.ReadS16(curObj + 0x20) - _camY; DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); } else if (type == 0xC35B0) // City Of Forever Horizontal Gate Master { - var mode = _api.MemLib.ReadByte(curObj + 0x15); + var mode = Mem.ReadByte(curObj + 0x15); var tmpx = Xpos; - Xpos = _api.MemLib.ReadS32(curObj + 0x1C); - Xvec = (Xpos + _api.MemLib.ReadS32(curObj + 0x5C) >> 16) - _camX; + Xpos = Mem.ReadS32(curObj + 0x1C); + Xvec = (Xpos + Mem.ReadS32(curObj + 0x5C) >> 16) - _camX; Xpos >>= 16; Xpos -= _camX; - Yvec = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + Yvec = Mem.ReadS16(curObj + 0x20) - _camY; if ((mode == 1) || (mode == 3)) { DrawEccoOct(Xpos, Yvec, 128, Color.Orange); @@ -832,35 +849,35 @@ namespace BizHawk.Client.EmuHawk } else if (type == 0xC343A) // City Of Forever Vertical Gate { - var mode = _api.MemLib.ReadByte(curObj + 0x15); + var mode = Mem.ReadByte(curObj + 0x15); if ((mode == 1) || (mode == 3)) { DrawEccoOct(Xmid, Ymid, 128, Color.Orange); } - Xvec = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Yvec = (_api.MemLib.ReadS32(curObj + 0x20) + _api.MemLib.ReadS32(curObj + 0x60) >> 16) - _camY; + Xvec = Mem.ReadS16(curObj + 0x1C) - _camX; + Yvec = (Mem.ReadS32(curObj + 0x20) + Mem.ReadS32(curObj + 0x60) >> 16) - _camY; DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); } else if (type == 0xA579A) // Antigrav Ball { - DrawEccoOct(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x4C), (_api.MemLib.ReadU16(0xFFA7C8) & 7) == 7 ? Color.Blue : Color.Gray); + DrawEccoOct(Xmid, Ymid, Mem.ReadS16(curObj + 0x4C), (Mem.ReadU16(0xFFA7C8) & 7) == 7 ? Color.Blue : Color.Gray); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); Xpos = Ypos = Xpos2 = Ypos2 = _camX - 128; } else if (type == 0xDF4E2) // Moray Abyss Conch Shell { - Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; - DrawBox(Xpos - 96, 0 - _camY, Xpos + 96, _api.MemLib.ReadS16(0xFFA7AC) - _camY - 64, Color.Orange, 0); - var mode = _api.MemLib.ReadByte(curObj + 0x15); - var modeTimer = _api.MemLib.ReadS16(curObj + 0x6E); - var Xvel1 = _api.MemLib.ReadS32(curObj + 0x54) / 65536.0; - var Yvel1 = _api.MemLib.ReadS32(curObj + 0x58) / 65536.0; - var Xvel2 = _api.MemLib.ReadS32(curObj + 0x5C) / 65536.0; - var Yvel2 = _api.MemLib.ReadS32(curObj + 0x60) / 65536.0; - TickerText($"{mode}:{modeTimer}:{_api.MemLib.ReadS16(0xFFA7AC) - 64 - Ymid - _camY}", Color.Red); + Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; + Ypos = Mem.ReadS16(curObj + 0x20) - _camY; + DrawBox(Xpos - 96, 0 - _camY, Xpos + 96, Mem.ReadS16(0xFFA7AC) - _camY - 64, Color.Orange, 0); + var mode = Mem.ReadByte(curObj + 0x15); + var modeTimer = Mem.ReadS16(curObj + 0x6E); + var Xvel1 = Mem.ReadS32(curObj + 0x54) / 65536.0; + var Yvel1 = Mem.ReadS32(curObj + 0x58) / 65536.0; + var Xvel2 = Mem.ReadS32(curObj + 0x5C) / 65536.0; + var Yvel2 = Mem.ReadS32(curObj + 0x60) / 65536.0; + TickerText($"{mode}:{modeTimer}:{Mem.ReadS16(0xFFA7AC) - 64 - Ymid - _camY}", Color.Red); TickerText($"{Xvel1:0.######}:{Yvel1:0.######}", Color.Red); TickerText($"{Xvel2:0.######}:{Yvel2:0.######}", Color.Red); TickerText($"{Xvel1 + Xvel2:0.######}:{Yvel1 + Yvel2:0.######}", Color.Red); @@ -882,8 +899,8 @@ namespace BizHawk.Client.EmuHawk break; case 1: DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Orange, 0); - Xpos2 = _api.MemLib.ReadS32(0xFFAA1A) - _api.MemLib.ReadS32(curObj + 0x24); - Ypos2 = _api.MemLib.ReadS32(0xFFAA1E) - _api.MemLib.ReadS32(curObj + 0x28); + Xpos2 = Mem.ReadS32(0xFFAA1A) - Mem.ReadS32(curObj + 0x24); + Ypos2 = Mem.ReadS32(0xFFAA1E) - Mem.ReadS32(curObj + 0x28); var dSml = Math.Abs(Xpos2); var dBig = Math.Abs(Ypos2); if (dBig < dSml) @@ -895,11 +912,11 @@ namespace BizHawk.Client.EmuHawk var rad = (dBig + (dSml >> 1) - (dSml >> 3)) / 65536.0; Xpos2 = (int)(Xpos2 * (256.0 / (rad+1))) >> 20; Ypos2 = (int)(Ypos2 * (256.0 / (rad+1))) >> 20; - _api.GUILib.DrawLine(Xmid, Ymid, Xmid + Xpos2, Ymid + Ypos2, Color.Gray); + Gui.DrawLine(Xmid, Ymid, Xmid + Xpos2, Ymid + Ypos2, Color.Gray); TickerText($"{Xpos2 / 512.0:0.######}:{Ypos2 / 512.0:0.######}", Color.Red); break; case 2: - TickerText($"{_api.MemLib.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); + TickerText($"{Mem.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); break; } } @@ -908,10 +925,10 @@ namespace BizHawk.Client.EmuHawk || (type == 0xA6C4A) || (type == 0xAB65A) || (type == 0x9F2EC)) { } else { - PutText($"{type:X5}:{_api.MemLib.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.Lime, Color.Blue); + PutText($"{type:X5}:{Mem.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.Lime, Color.Blue); PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.Lime, Color.Blue); } - colltype = _api.MemLib.ReadS8(curObj + 0x7E); + colltype = Mem.ReadS8(curObj + 0x7E); switch (colltype) { case 0x10: @@ -947,7 +964,7 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); + Gui.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); break; case 0x1A: case 0x1B: @@ -957,7 +974,7 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); + Gui.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); break; case 0x1F: case 0x20: @@ -967,7 +984,7 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); + Gui.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); break; case 0x24: case 0x25: @@ -977,12 +994,12 @@ namespace BizHawk.Client.EmuHawk Xmid = (Xpos + Xpos2) >> 1; Ymid = (Ypos + Ypos2) >> 1; DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); - _api.GUILib.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); + Gui.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); break; case 0x2A: DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); break; case 0x2B: Xmid = (Xpos + Xpos2) >> 1; @@ -994,70 +1011,70 @@ namespace BizHawk.Client.EmuHawk new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), new Point(Xpos2, Ymid) }; - _api.GUILib.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); + Gui.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); break; case 0x2C: break; default: - DrawEccoRhomb_scaled(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); + DrawEccoRhomb_scaled(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); break; } - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - curObj = _api.MemLib.ReadU24(curObj+1); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + curObj = Mem.ReadU24(curObj+1); } //animate objects if (_mode == Modes.Ecco2) - curObj = _api.MemLib.ReadU24(0xFFCFB9); + curObj = Mem.ReadU24(0xFFCFB9); else - curObj = _api.MemLib.ReadU24(0xFFD829); + curObj = Mem.ReadU24(0xFFD829); while (curObj != 0) { type = 0; switch (_mode) { case Modes.Ecco2: { - uint flags = _api.MemLib.ReadU16(curObj + 0x10); + uint flags = Mem.ReadU16(curObj + 0x10); int Xvec = 0; int Yvec = 0; //if ((flags & 0x2000) || !(flags & 2)); - HP = _api.MemLib.ReadS8(curObj + 0x7B); - type = _api.MemLib.ReadU32(curObj + 0xC); + HP = Mem.ReadS8(curObj + 0x7B); + type = Mem.ReadU32(curObj + 0xC); if ((type == 0xA1FE6) || (type == 0xA208E) // Chain link creatures such as vortex worm, magic arm, etc || (type == 0xA2288) || (type == 0xA27A4) || (type == 0xA2BB0) || (type == 0xA2C50)) { uint subObj = curObj; while (subObj != 0) { - Xpos = _api.MemLib.ReadS32(subObj + 0x24); - Ypos = _api.MemLib.ReadS32(subObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(subObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(subObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(subObj + 0x24); + Ypos = Mem.ReadS32(subObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(subObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(subObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - if (_api.MemLib.ReadS16(subObj + 0x44) == _api.MemLib.ReadS16(subObj + 0x48)) + if (Mem.ReadS16(subObj + 0x44) == Mem.ReadS16(subObj + 0x48)) { - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.Cyan, 0); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.Cyan, 0); } else { - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.Lime, 0); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x48), Color.Blue, 0); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.Lime, 0); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x48), Color.Blue, 0); } DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - subObj = _api.MemLib.ReadU24(subObj + 5); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + subObj = Mem.ReadU24(subObj + 5); } if (HP > 2) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); } } @@ -1069,43 +1086,43 @@ namespace BizHawk.Client.EmuHawk uint subObj = curObj; while (subObj != 0) { - Xpos = _api.MemLib.ReadS32(subObj + 0x24); - Ypos = _api.MemLib.ReadS32(subObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(subObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(subObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(subObj + 0x24); + Ypos = Mem.ReadS32(subObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(subObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(subObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - if (_api.MemLib.ReadS16(subObj + 0x44) == _api.MemLib.ReadS16(subObj + 0x48)) + if (Mem.ReadS16(subObj + 0x44) == Mem.ReadS16(subObj + 0x48)) { - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.White, 0); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.White, 0); } else { - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x44), Color.Lime, 0); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x48), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(subObj + 0x48), Color.Magenta, 0); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.Lime, 0); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x48), Color.FromArgb(255, 0, 127)); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x48), Color.Magenta, 0); } DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); if (type == 0xBA66E) { DrawEccoOct(Xpos, Ypos, 32, Color.Blue, 16); if (subObj == curObj) { - var mode = _api.MemLib.ReadByte(subObj + 0x15); - TickerText($"{_api.MemLib.ReadByte(subObj + 0x14)}:{mode}:{_api.MemLib.ReadByte(subObj + 0x70)}", Color.Red); - TickerText($"{_api.MemLib.ReadS32(subObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); - TickerText($"{_api.MemLib.ReadS32(subObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(subObj + 0x50) / 65536.0:0.######}", Color.Red); + var mode = Mem.ReadByte(subObj + 0x15); + TickerText($"{Mem.ReadByte(subObj + 0x14)}:{mode}:{Mem.ReadByte(subObj + 0x70)}", Color.Red); + TickerText($"{Mem.ReadS32(subObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); + TickerText($"{Mem.ReadS32(subObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(subObj + 0x50) / 65536.0:0.######}", Color.Red); switch (mode) { case 0: case 2: case 4: - Xpos2 = _api.MemLib.ReadS32(0xFFAA22) - _api.MemLib.ReadS32(subObj + 0x24); - Ypos2 = _api.MemLib.ReadS32(0xFFAA26) - _api.MemLib.ReadS32(subObj + 0x28); + Xpos2 = Mem.ReadS32(0xFFAA22) - Mem.ReadS32(subObj + 0x24); + Ypos2 = Mem.ReadS32(0xFFAA26) - Mem.ReadS32(subObj + 0x28); var dSml = Math.Abs(Xpos2); var dBig = Math.Abs(Ypos2); if (dBig < dSml) @@ -1117,7 +1134,7 @@ namespace BizHawk.Client.EmuHawk var rad = (dBig + (dSml >> 1) - (dSml >> 3)) / 65536.0; Xpos2 = (int)(Xpos2 * (256.0 / (rad + 1))) >> 20; Ypos2 = (int)(Ypos2 * (256.0 / (rad + 1))) >> 20; - _api.GUILib.DrawLine(Xpos, Ypos, Xpos + Xpos2, Ypos + Ypos2, Color.Red); + Gui.DrawLine(Xpos, Ypos, Xpos + Xpos2, Ypos + Ypos2, Color.Red); break; default: break; @@ -1125,13 +1142,13 @@ namespace BizHawk.Client.EmuHawk } } } - else if ((type == 0xBA52E) && (subObj == _api.MemLib.ReadU24(curObj + 0x1D))) + else if ((type == 0xBA52E) && (subObj == Mem.ReadU24(curObj + 0x1D))) { - DrawEccoOct(Xpos, Ypos, 32, (_api.MemLib.ReadByte(subObj + 0x70) == 0) ? Color.Blue : Color.Gray, 16); - var mode = _api.MemLib.ReadByte(curObj + 0x15); - TickerText($"{_api.MemLib.ReadByte(curObj + 0x14)}:{mode}:{_api.MemLib.ReadS16(curObj + 0x6E)}:{_api.MemLib.ReadByte(subObj + 0x70)}", Color.Red); - TickerText($"{_api.MemLib.ReadS32(subObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); + DrawEccoOct(Xpos, Ypos, 32, (Mem.ReadByte(subObj + 0x70) == 0) ? Color.Blue : Color.Gray, 16); + var mode = Mem.ReadByte(curObj + 0x15); + TickerText($"{Mem.ReadByte(curObj + 0x14)}:{mode}:{Mem.ReadS16(curObj + 0x6E)}:{Mem.ReadByte(subObj + 0x70)}", Color.Red); + TickerText($"{Mem.ReadS32(subObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); + TickerText($"{Mem.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); } else if (type == 0xE0988) { @@ -1139,44 +1156,44 @@ namespace BizHawk.Client.EmuHawk } if (HP > 2) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); } - subObj = _api.MemLib.ReadU24(subObj + 5); + subObj = Mem.ReadU24(subObj + 5); } } else if (type == 0xB7DF4) { - Xpos = _api.MemLib.ReadS32(curObj + 0x24); - Ypos = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(curObj + 0x24); + Ypos = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; DrawEccoOct(Xpos, Ypos, 26, Color.PowderBlue); DrawEccoOct(Xpos, Ypos, 26, Color.White); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec); } else if (type == 0xE47EE) { - uint subObj = _api.MemLib.ReadU24(curObj + 5); + uint subObj = Mem.ReadU24(curObj + 5); while (subObj != 0) { - Xpos = _api.MemLib.ReadS32(subObj + 0x1C); - Ypos = _api.MemLib.ReadS32(subObj + 0x20); - Xvec = ((Xpos + _api.MemLib.ReadS32(subObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(subObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(subObj + 0x1C); + Ypos = Mem.ReadS32(subObj + 0x20); + Xvec = ((Xpos + Mem.ReadS32(subObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(subObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, ((_api.MemLib.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.White); - DrawEccoOct(Xpos, Ypos, ((_api.MemLib.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.Yellow, 0); + DrawEccoOct(Xpos, Ypos, ((Mem.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.White); + DrawEccoOct(Xpos, Ypos, ((Mem.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.Yellow, 0); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - subObj = _api.MemLib.ReadU24(subObj + 5); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + subObj = Mem.ReadU24(subObj + 5); } } else if (type == 0xDBE64) // Medusa Boss @@ -1185,21 +1202,21 @@ namespace BizHawk.Client.EmuHawk uint next; do { - next = _api.MemLib.ReadU24(subObj + 5); + next = Mem.ReadU24(subObj + 5); if (next != 0) subObj = next; } while (next != 0); - Xpos = _api.MemLib.ReadS16(subObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(subObj + 0x34); - Ypos = _api.MemLib.ReadS16(subObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(subObj + 0x38); + Xpos = Mem.ReadS16(subObj + 0x2C); + Xpos2 = Mem.ReadS16(subObj + 0x34); + Ypos = Mem.ReadS16(subObj + 0x30); + Ypos2 = Mem.ReadS16(subObj + 0x38); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; DrawEccoOct(Xpos, Ypos, 32, Color.Red); DrawEccoOct(Xpos2, Ypos2, 32, Color.Red); - Xpos = _api.MemLib.ReadS32(curObj + 0x24); - Ypos = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(curObj + 0x24); + Ypos = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; @@ -1212,86 +1229,86 @@ namespace BizHawk.Client.EmuHawk new Point(Xpos + octOff, Ypos - octOff), new Point(Xpos + 60, Ypos) }; - _api.GUILib.DrawPolygon(hemiOctPoints, Color.Cyan, Color.FromArgb(0x3F, Color.Cyan)); + Gui.DrawPolygon(hemiOctPoints, Color.Cyan, Color.FromArgb(0x3F, Color.Cyan)); for (int l = 0; l < 4; l++) { - _api.GUILib.DrawLine(hemiOctPoints[l].X, hemiOctPoints[l].Y, hemiOctPoints[l + 1].X, hemiOctPoints[l + 1].Y, Color.Cyan); + Gui.DrawLine(hemiOctPoints[l].X, hemiOctPoints[l].Y, hemiOctPoints[l + 1].X, hemiOctPoints[l + 1].Y, Color.Cyan); } DrawBoxMWH(Xpos, Ypos + 12, 52, 12, Color.Cyan); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); } else if (type == 0xDCEE0) // Globe Holder boss { uint subObj; - var mode = _api.MemLib.ReadByte(curObj + 0x15); + var mode = Mem.ReadByte(curObj + 0x15); if (mode < 4) { - subObj = _api.MemLib.ReadU24(curObj + 9); + subObj = Mem.ReadU24(curObj + 9); while (subObj != 0) { - Xmid = _api.MemLib.ReadS32(subObj + 0x24); - Ymid = _api.MemLib.ReadS32(subObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(subObj + 0x54) + _api.MemLib.ReadS32(subObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(subObj + 0x58) + _api.MemLib.ReadS32(subObj + 0x60)) >> 16) - _camY; + Xmid = Mem.ReadS32(subObj + 0x24); + Ymid = Mem.ReadS32(subObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(subObj + 0x54) + Mem.ReadS32(subObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(subObj + 0x58) + Mem.ReadS32(subObj + 0x60)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawEccoOct(Xmid, Ymid, 12, Color.Orange); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - var next = _api.MemLib.ReadU24(subObj + 9); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + var next = Mem.ReadU24(subObj + 9); if ((next == 0) && ((mode & 1) != 0)) { - DrawEccoOct(Xmid, Ymid, _api.MemLib.ReadS16(subObj + 0x3C), Color.Orange); + DrawEccoOct(Xmid, Ymid, Mem.ReadS16(subObj + 0x3C), Color.Orange); } - subObj = _api.MemLib.ReadU24(subObj + 9); + subObj = Mem.ReadU24(subObj + 9); } - subObj = _api.MemLib.ReadU24(curObj + 5); + subObj = Mem.ReadU24(curObj + 5); while (subObj != 0) { - Xmid = _api.MemLib.ReadS32(subObj + 0x24); - Ymid = _api.MemLib.ReadS32(subObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(subObj + 0x54) + _api.MemLib.ReadS32(subObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(subObj + 0x58) + _api.MemLib.ReadS32(subObj + 0x60)) >> 16) - _camY; + Xmid = Mem.ReadS32(subObj + 0x24); + Ymid = Mem.ReadS32(subObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(subObj + 0x54) + Mem.ReadS32(subObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(subObj + 0x58) + Mem.ReadS32(subObj + 0x60)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawEccoOct(Xmid, Ymid, 12, Color.Orange); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - var next = _api.MemLib.ReadU24(subObj + 5); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + var next = Mem.ReadU24(subObj + 5); if ((next == 0) && ((mode & 2) != 0)) { - DrawEccoOct(Xmid, Ymid, _api.MemLib.ReadS16(subObj + 0x3C), Color.Orange); + DrawEccoOct(Xmid, Ymid, Mem.ReadS16(subObj + 0x3C), Color.Orange); } - subObj = _api.MemLib.ReadU24(subObj + 5); + subObj = Mem.ReadU24(subObj + 5); } } - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - int Xtmp = _api.MemLib.ReadS32(curObj + 0x2C); - int Ytmp = _api.MemLib.ReadS32(curObj + 0x30); - int Xtmp2 = _api.MemLib.ReadS32(curObj + 0x34); - int Ytmp2 = _api.MemLib.ReadS32(curObj + 0x38); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + int Xtmp = Mem.ReadS32(curObj + 0x2C); + int Ytmp = Mem.ReadS32(curObj + 0x30); + int Xtmp2 = Mem.ReadS32(curObj + 0x34); + int Ytmp2 = Mem.ReadS32(curObj + 0x38); Xpos = (Xtmp >> 16) - _camX; Xpos2 = (Xtmp2 >> 16) - _camX; Ypos = (Ytmp >> 16) - _camY; Ypos2 = (Ytmp2 >> 16) - _camY; - Xvec = ((_api.MemLib.ReadS32(curObj + 0x24) + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((_api.MemLib.ReadS32(curObj + 0x28) + +_api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xvec = ((Mem.ReadS32(curObj + 0x24) + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Mem.ReadS32(curObj + 0x28) + +Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); if (mode < 7) { double overlap = 0; - DrawEccoOct(Xmid, Ymid, 0x5C, _api.MemLib.ReadByte(curObj + 0x7C) == 0 ? Color.Blue : Color.Gray); + DrawEccoOct(Xmid, Ymid, 0x5C, Mem.ReadByte(curObj + 0x7C) == 0 ? Color.Blue : Color.Gray); DrawEccoOct(Xmid, Ymid, 0x5C, Color.Cyan, 0); - Xvec = (_api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)); - Yvec = (_api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)); - subObj = _api.MemLib.ReadU24(curObj + 0x69); + Xvec = (Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)); + Yvec = (Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)); + subObj = Mem.ReadU24(curObj + 0x69); if (subObj != 0) { - Xpos = _api.MemLib.ReadS32(subObj + 0x2C); - Ypos = _api.MemLib.ReadS32(subObj + 0x30); - Xpos2 = _api.MemLib.ReadS32(subObj + 0x34); - Ypos2 = _api.MemLib.ReadS32(subObj + 0x38); + Xpos = Mem.ReadS32(subObj + 0x2C); + Ypos = Mem.ReadS32(subObj + 0x30); + Xpos2 = Mem.ReadS32(subObj + 0x34); + Ypos2 = Mem.ReadS32(subObj + 0x38); while ((Xtmp > Xpos) && (Xtmp2 < Xpos2) && (Ytmp > Ypos) && (Ytmp2 < Ypos2) && ((Xvec != 0) || (Yvec != 0))) { Xtmp += Xvec; Xtmp2 += Xvec; @@ -1304,19 +1321,19 @@ namespace BizHawk.Client.EmuHawk Ypos -= _camY; Ypos2 -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, (overlap >= 6) ? Color.Orange : Color.White, 0); } - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, (overlap >= 6) ? Color.Orange : Color.White, (overlap >= 6) ? 63 : 0); if (mode < 4) { - Xmid = _api.MemLib.ReadS16(curObj + 0x4C) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x50) - _camY; + Xmid = Mem.ReadS16(curObj + 0x4C) - _camX; + Ymid = Mem.ReadS16(curObj + 0x50) - _camY; if ((mode & 1) == 0) DrawEccoOct(Xmid, Ymid - 0xAE, 32, Color.Orange); if ((mode & 2) == 0) DrawEccoOct(Xmid, Ymid + 0xAE, 32, Color.Orange); } - TickerText($"{mode}:{_api.MemLib.ReadByte(curObj + 0x7F)}:{_api.MemLib.ReadByte(curObj + 0x6D)}:{_api.MemLib.ReadByte(curObj + 0x7C)}", Color.Red); + TickerText($"{mode}:{Mem.ReadByte(curObj + 0x7F)}:{Mem.ReadByte(curObj + 0x6D)}:{Mem.ReadByte(curObj + 0x7C)}", Color.Red); } else if (mode == 8) { @@ -1325,15 +1342,15 @@ namespace BizHawk.Client.EmuHawk } else if (type == 0xE1BA2) // Vortex Queen Boss { - var vulnCount = _api.MemLib.ReadByte(curObj + 0x7F); - var state = _api.MemLib.ReadByte(curObj + 0x7C); - var stateCounter = _api.MemLib.ReadU16(curObj + 0x6E); - var mode = _api.MemLib.ReadU16(curObj + 0x64); - var modeCounter = _api.MemLib.ReadU16(curObj + 0x66); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x40); - Xvec = Xmid + _api.MemLib.ReadS32(curObj + 0x54); - Yvec = Ymid + _api.MemLib.ReadS32(curObj + 0x58); + var vulnCount = Mem.ReadByte(curObj + 0x7F); + var state = Mem.ReadByte(curObj + 0x7C); + var stateCounter = Mem.ReadU16(curObj + 0x6E); + var mode = Mem.ReadU16(curObj + 0x64); + var modeCounter = Mem.ReadU16(curObj + 0x66); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x40); + Xvec = Xmid + Mem.ReadS32(curObj + 0x54); + Yvec = Ymid + Mem.ReadS32(curObj + 0x58); Xvec >>= 16; Yvec >>= 16; Xmid >>= 16; Ymid >>= 16; Xvec -= _camX; Yvec -= _camY; @@ -1350,35 +1367,35 @@ namespace BizHawk.Client.EmuHawk new Point(Xmid - hexOff.X, Ymid + 32), new Point(Xmid + hexOff.X, Ymid + 32) }; - _api.GUILib.DrawPolygon(roundedRect, Color.Orange, Color.FromArgb(63, Color.Orange)); + Gui.DrawPolygon(roundedRect, Color.Orange, Color.FromArgb(63, Color.Orange)); } DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - TickerText($"{state:X2}:{stateCounter}:{mode}:{modeCounter}:{_api.MemLib.ReadByte(curObj + 0x70) & 0xF}", Color.Red); - var subObj = _api.MemLib.ReadU24(curObj + 0x5); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + TickerText($"{state:X2}:{stateCounter}:{mode}:{modeCounter}:{Mem.ReadByte(curObj + 0x70) & 0xF}", Color.Red); + var subObj = Mem.ReadU24(curObj + 0x5); var tongueMode = mode; - mode = _api.MemLib.ReadByte(subObj + 0x15); - modeCounter = _api.MemLib.ReadU16(subObj + 0x6E); - Xmid = _api.MemLib.ReadS32(subObj + 0x24); - Ymid = _api.MemLib.ReadS32(subObj + 0x40); - Xvec = (Xmid + _api.MemLib.ReadS32(subObj + 0x5C) >> 16) - _camX; - Yvec = (Ymid + _api.MemLib.ReadS32(subObj + 0x60) >> 16) - _camY; + mode = Mem.ReadByte(subObj + 0x15); + modeCounter = Mem.ReadU16(subObj + 0x6E); + Xmid = Mem.ReadS32(subObj + 0x24); + Ymid = Mem.ReadS32(subObj + 0x40); + Xvec = (Xmid + Mem.ReadS32(subObj + 0x5C) >> 16) - _camX; + Yvec = (Ymid + Mem.ReadS32(subObj + 0x60) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; Ymid -= 32; Yvec -= 32; - var levelHeight = _api.MemLib.ReadS16(0xFFA7AC) - _camY; + var levelHeight = Mem.ReadS16(0xFFA7AC) - _camY; switch (mode) { case 0: DrawBox(Xmid - 32, Ymid - ((state == 5) ? 0x60 : 0x70), Xmid + 32, Ymid - 16, Color.Red); break; case 2: - Ypos = _api.MemLib.ReadS16(subObj + 0x50) - _camY; - _api.GUILib.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); + Ypos = Mem.ReadS16(subObj + 0x50) - _camY; + Gui.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); break; case 3: - modeCounter = _api.MemLib.ReadByte(subObj + 0x7C); + modeCounter = Mem.ReadByte(subObj + 0x7C); break; case 5: Point[] throatShape = @@ -1390,7 +1407,7 @@ namespace BizHawk.Client.EmuHawk new Point(Xmid + 48, Ymid + 60), new Point(Xmid + 48, levelHeight) }; - _api.GUILib.DrawPolygon(throatShape, Color.Red, Color.FromArgb(63, Color.Red)); + Gui.DrawPolygon(throatShape, Color.Red, Color.FromArgb(63, Color.Red)); DrawEccoOct(Xmid, Ymid, 24, Color.Red); DrawEccoOct(Xmid, Ymid, 24, Color.White, 0); break; @@ -1401,41 +1418,41 @@ namespace BizHawk.Client.EmuHawk } if (tongueMode == 7) { - uint subObj2 = _api.MemLib.ReadU24(0xFFCFCD); + uint subObj2 = Mem.ReadU24(0xFFCFCD); while (subObj2 != 0) { - if (_api.MemLib.ReadU16(subObj2 + 0x10) == 0xFF) + if (Mem.ReadU16(subObj2 + 0x10) == 0xFF) { - Xpos = _api.MemLib.ReadS16(subObj2 + 0x24) - _camX; - Ypos = _api.MemLib.ReadS16(subObj2 + 0x28) - _camY; - Xpos2 = ((_api.MemLib.ReadS32(subObj2 + 0x24) + _api.MemLib.ReadS32(subObj2 + 0x54)) >> 16) - _camX; - Ypos2 = ((_api.MemLib.ReadS32(subObj2 + 0x28) + _api.MemLib.ReadS32(subObj2 + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(subObj2 + 0x24) - _camX; + Ypos = Mem.ReadS16(subObj2 + 0x28) - _camY; + Xpos2 = ((Mem.ReadS32(subObj2 + 0x24) + Mem.ReadS32(subObj2 + 0x54)) >> 16) - _camX; + Ypos2 = ((Mem.ReadS32(subObj2 + 0x28) + Mem.ReadS32(subObj2 + 0x58)) >> 16) - _camY; DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); } - subObj2 = _api.MemLib.ReadU24(subObj2 + 1); + subObj2 = Mem.ReadU24(subObj2 + 1); } } - Ypos = _api.MemLib.ReadS16(subObj + 0x50) - _camY; - _api.GUILib.DrawLine(Xmid - 48, Ypos - 94, Xmid + 48, Ypos - 94, Color.Orange); - _api.GUILib.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); + Ypos = Mem.ReadS16(subObj + 0x50) - _camY; + Gui.DrawLine(Xmid - 48, Ypos - 94, Xmid + 48, Ypos - 94, Color.Orange); + Gui.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); break; default: break; } - if ((mode < 7) || ((mode == 7) && (_api.MemLib.ReadU24(0xFFCFC9) != 0))) + if ((mode < 7) || ((mode == 7) && (Mem.ReadU24(0xFFCFC9) != 0))) { - if (_api.MemLib.ReadByte(subObj + 0x70) == 0) + if (Mem.ReadByte(subObj + 0x70) == 0) { DrawEccoOct(Xmid, Ymid, 32, Color.Red); DrawBox(Xmid - 48, Ymid + 32, Xmid + 48, levelHeight, Color.Red); } - Ypos = _api.MemLib.ReadS16(subObj + 0x50) - _camY - 94; - _api.GUILib.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); + Ypos = Mem.ReadS16(subObj + 0x50) - _camY - 94; + Gui.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); } - if (_api.MemLib.ReadS32(subObj + 0xC) == 0xE17B4) + if (Mem.ReadS32(subObj + 0xC) == 0xE17B4) { Point[] shapePoints = { @@ -1446,31 +1463,31 @@ namespace BizHawk.Client.EmuHawk new Point(Xmid + 48, Ymid + 60), new Point(Xmid + 48, levelHeight) }; - _api.GUILib.DrawPolygon(shapePoints, Color.Red, Color.FromArgb(63, Color.Red)); + Gui.DrawPolygon(shapePoints, Color.Red, Color.FromArgb(63, Color.Red)); DrawEccoOct(Xmid, Ymid, 24, Color.Red); DrawEccoOct(Xmid, Ymid, 24, Color.White, 0); } - Ypos = (_api.MemLib.ReadS16(subObj + 0x50) - _camY) - 264; + Ypos = (Mem.ReadS16(subObj + 0x50) - _camY) - 264; DrawBoxMWH(160 + _left, Ypos, 320, 12, (32 < stateCounter) && (stateCounter < 160) ? Color.Brown : Color.Gray); if ((32 < stateCounter) && (stateCounter < 160)) { DrawBoxMWH(_left + 160, Ypos, 320, 12, Color.White, 0); } DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); TickerText($"{mode:X2}:{modeCounter}:{HP}:{vulnCount}", Color.Red); HP = 0; } else if (type == 0xA5BD2) // Telekinetic future dolphins { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; @@ -1479,66 +1496,66 @@ namespace BizHawk.Client.EmuHawk DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); DrawEccoOct(Xmid, Ymid, 4, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0x9F5B0) || (type == 0x9F4DC) || (type == 0x9F6A0)) // Falling rock, breaks barriers { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); if (type == 0x9F6A0) { - int width = _api.MemLib.ReadS16(curObj + 0x44) << 1; + int width = Mem.ReadS16(curObj + 0x44) << 1; DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); } - TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); + TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); } else if (type == 0xA3B18) { - Xpos = _api.MemLib.ReadS32(curObj + 0x24); - Ypos = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(curObj + 0x24); + Ypos = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(curObj + 0x44), Color.Yellow); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(curObj + 0x44), Color.Yellow); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); } else if (type == 0xA4018) { - Xpos = _api.MemLib.ReadS32(curObj + 0x24); - Ypos = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS32(curObj + 0x24); + Ypos = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, _api.MemLib.ReadS16(curObj + 0x44), Color.Gray); + DrawEccoOct(Xpos, Ypos, Mem.ReadS16(curObj + 0x44), Color.Gray); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); } else if (type == 0xA091E) // Blue Whale { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; Xpos = Xmid; Ypos = Ymid; @@ -1548,39 +1565,39 @@ namespace BizHawk.Client.EmuHawk DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x30, Color.Red, 31); DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x20, Color.Red, 31); DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x10, Color.Red, 31); - if (_api.MemLib.ReadByte(curObj + 0x7F) == 0) + if (Mem.ReadByte(curObj + 0x7F) == 0) { - Xpos += (_api.MemLib.ReadS16(curObj + 0x6E) == 0) ? -278 : 162; - Ypos += 44 - _api.MemLib.ReadS16(curObj + 0x48); + Xpos += (Mem.ReadS16(curObj + 0x6E) == 0) ? -278 : 162; + Ypos += 44 - Mem.ReadS16(curObj + 0x48); DrawEccoOct(Xpos, Ypos, 32, Color.Blue); } DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xE66D8) //Vortex Larva { - uint subObj = _api.MemLib.ReadU24(curObj + 5); + uint subObj = Mem.ReadU24(curObj + 5); while (subObj != 0) { - Xpos = _api.MemLib.ReadS16(subObj + 0x1C); - Ypos = _api.MemLib.ReadS16(subObj + 0x20); - Xpos2 = _api.MemLib.ReadS16(subObj + 0x24); - Ypos2 = _api.MemLib.ReadS16(subObj + 0x28); + Xpos = Mem.ReadS16(subObj + 0x1C); + Ypos = Mem.ReadS16(subObj + 0x20); + Xpos2 = Mem.ReadS16(subObj + 0x24); + Ypos2 = Mem.ReadS16(subObj + 0x28); Xpos -= _camX; Ypos -= _camY; Xpos2 -= _camX; Ypos2 -= _camY; DrawEccoOct(Xpos, Ypos, 30, Color.White, 32); DrawEccoOct(Xpos, Ypos, 30, Color.Yellow, 0); DrawEccoOct(Xpos2, Ypos2, 30, Color.White, 32); DrawEccoOct(Xpos2, Ypos2, 30, Color.Yellow, 0); - subObj = _api.MemLib.ReadU24(subObj + 5); + subObj = Mem.ReadU24(subObj + 5); } - Xpos = _api.MemLib.ReadS32(curObj + 0x24); - Ypos = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x72) - _camX; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x76) - _camY; + Xpos = Mem.ReadS32(curObj + 0x24); + Ypos = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos2 = Mem.ReadS16(curObj + 0x72) - _camX; + Ypos2 = Mem.ReadS16(curObj + 0x76) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; DrawEccoOct(Xpos, Ypos, 0xB0, Color.Yellow); @@ -1588,112 +1605,112 @@ namespace BizHawk.Client.EmuHawk DrawEccoOct(Xpos, Ypos, 0x70, Color.Red); DrawEccoOct(Xpos, Ypos, 0x38, Color.White); DrawEccoOct(Xpos, Ypos, 0x38, Color.Red, 0); - DrawEccoOct(Xpos, Ypos, 48, Color.Blue, ((_api.MemLib.ReadByte(curObj + 0x7B) > 2) && (_api.MemLib.ReadByte(curObj + 0x14) != 0)) ? 63 : 0); + DrawEccoOct(Xpos, Ypos, 48, Color.Blue, ((Mem.ReadByte(curObj + 0x7B) > 2) && (Mem.ReadByte(curObj + 0x14) != 0)) ? 63 : 0); DrawEccoOct(Xpos2, Ypos2, 32, Color.Orange); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); - TickerText($"{_api.MemLib.ReadByte(curObj + 0x14):X2}:{_api.MemLib.ReadByte(curObj + 0x7B):X2}:{_api.MemLib.ReadS16(curObj + 0x6E):D2}", Color.Red); - TickerText($"{ _api.MemLib.ReadByte(curObj + 0x7C):X2}:{_api.MemLib.ReadS16(curObj + 0x18):D3}", Color.Red); - TickerText($"{(_api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C))/65536.0:0.######}:{(_api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) / 65536.0:0.######}", Color.Red); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + TickerText($"{Mem.ReadByte(curObj + 0x14):X2}:{Mem.ReadByte(curObj + 0x7B):X2}:{Mem.ReadS16(curObj + 0x6E):D2}", Color.Red); + TickerText($"{ Mem.ReadByte(curObj + 0x7C):X2}:{Mem.ReadS16(curObj + 0x18):D3}", Color.Red); + TickerText($"{(Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C))/65536.0:0.######}:{(Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) / 65536.0:0.######}", Color.Red); } else if (type == 0x9CE3A) //Remnant Stars { - flags = _api.MemLib.ReadU16(curObj + 0x10); - uint subObj = _api.MemLib.ReadU24(curObj + 0x5); - uint anim = _api.MemLib.ReadU16(curObj + 0x6C); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); + flags = Mem.ReadU16(curObj + 0x10); + uint subObj = Mem.ReadU24(curObj + 0x5); + uint anim = Mem.ReadU16(curObj + 0x6C); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; if ((anim <= 7) && (subObj == 0xFFA9D4)) { DrawEccoRhomb(Xmid, Ymid, 96, Color.Red); - PutText($"{((7 - anim) * 4) - ((_api.MemLib.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Blue, Color.Red); + PutText($"{((7 - anim) * 4) - ((Mem.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Blue, Color.Red); } } else if (type == 0xA997C) // Vortex Soldier { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = (Xmid + _api.MemLib.ReadS32(curObj + 0x54) >> 16) - _camX; - Yvec = (Ymid + _api.MemLib.ReadS32(curObj + 0x58) >> 16) - _camY; - Xvec += _api.MemLib.ReadS16(curObj + 0x64); - Yvec += _api.MemLib.ReadS16(curObj + 0x66); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = (Xmid + Mem.ReadS32(curObj + 0x54) >> 16) - _camX; + Yvec = (Ymid + Mem.ReadS32(curObj + 0x58) >> 16) - _camY; + Xvec += Mem.ReadS16(curObj + 0x64); + Yvec += Mem.ReadS16(curObj + 0x66); Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - if (_api.MemLib.ReadByte(curObj + 0x7A) == 0) + if (Mem.ReadByte(curObj + 0x7A) == 0) { DrawRectRhombusIntersection(new Point(Xmid, Ymid + 6), new Point(Xmid, Ymid), 50, 44, 64, Color.Red); } DrawRectRhombusIntersection(new Point(Xmid, Ymid - 25), new Point(Xmid, Ymid), 38, 47, 64, Color.Red); - DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.Blue, 16); + DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.Blue, 16); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xA6C4A) || (type == 0xC43D4)) // Barrier Glyphs { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - var subType = _api.MemLib.ReadByte(curObj + 0x13); - if ((_api.MemLib.ReadU8(curObj + 0x7A) == 0) && (_api.MemLib.ReadU8(0xFFA7B5) != 0) + var subType = Mem.ReadByte(curObj + 0x13); + if ((Mem.ReadU8(curObj + 0x7A) == 0) && (Mem.ReadU8(0xFFA7B5) != 0) && ((type != 0xA6C4A) || (subType == 0x14) || (subType == 0x97))) { DrawEccoOct(Xmid, Ymid, 70, Color.Red); } - DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.Blue); - DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.PowderBlue, 0); + DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.Blue); + DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.PowderBlue, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xB4F46) || (type == 0xB4E1C) || (type == 0xB4C18) || (type == 0xB4ACC) || (type == 0xB4B72)) // Guiding Orca/Dolphin { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - int Xdst = _api.MemLib.ReadS16(curObj + 0x64); + int Xdst = Mem.ReadS16(curObj + 0x64); Xdst <<= 7; Xdst = Xdst + 0x40 - _camX; - int Ydst = _api.MemLib.ReadS16(curObj + 0x66); + int Ydst = Mem.ReadS16(curObj + 0x66); Ydst <<= 7; Ydst = Ydst + 0x40 - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - _api.GUILib.DrawLine(Xmid, Ymid, Xdst, Ydst, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xdst, Ydst, Color.Orange); DrawBoxMWH(Xdst, Ydst, 64, 64, Color.Orange); - TickerText($"{_api.MemLib.ReadS16(curObj + 0x24)}:{_api.MemLib.ReadS16(curObj + 0x28)}:{_api.MemLib.ReadByte(curObj + 0x7D)}:{_api.MemLib.ReadByte(curObj + 0x7A)}", Color.Lime); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x72) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x76) / 65536.0:0.######}", Color.Lime); + TickerText($"{Mem.ReadS16(curObj + 0x24)}:{Mem.ReadS16(curObj + 0x28)}:{Mem.ReadByte(curObj + 0x7D)}:{Mem.ReadByte(curObj + 0x7A)}", Color.Lime); + TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); + TickerText($"{Mem.ReadS32(curObj + 0x72) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x76) / 65536.0:0.######}", Color.Lime); } else if (type == 0xB5938) // Lost Orca { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; //DrawBoxMWH(Xmid, Ymid, 64, 32, Color.Lime); - if (_api.MemLib.ReadU16(curObj + 0x6E) == 0) + if (Mem.ReadU16(curObj + 0x6E) == 0) { - if (_api.MemLib.ReadByte(curObj + 0x7D) == 0) + if (Mem.ReadByte(curObj + 0x7D) == 0) { DrawBox(Xmid + 8, Ymid - 32, Xmid + 64, Ymid + 32, Color.Red); } @@ -1702,87 +1719,87 @@ namespace BizHawk.Client.EmuHawk DrawBox(Xmid - 64, Ymid - 32, Xmid - 8, Ymid + 32, Color.Red); } } - _api.GUILib.DrawLine(Xpos - 80, Ymid, Xpos + 80, Ymid, Color.Green); + Gui.DrawLine(Xpos - 80, Ymid, Xpos + 80, Ymid, Color.Green); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xB552A) || (type == 0xB5C42) || (type == 0xB5AFE)) // Following Orca, Returning Orca, & Idling Orca { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xB624A) // Orca Mother { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; - int height = _api.MemLib.ReadS16(curObj + 0x48) + 32; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; + int height = Mem.ReadS16(curObj + 0x48) + 32; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 80, 32, Color.Red, 31); - DrawBoxMWH(Xmid, Ymid, _api.MemLib.ReadS16(curObj + 0x44), _api.MemLib.ReadS16(curObj + 0x48), Color.Blue); + DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.Blue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - if (_api.MemLib.ReadS32(0xFFAB7E) != 0) + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + if (Mem.ReadS32(0xFFAB7E) != 0) { DrawEccoOct(Xmid, Ymid, 0x50, Color.Red, 31); } } else if (type == 0xC047E) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; var width = 2; var height = 2; - if (_api.MemLib.ReadByte(curObj + 0x15) == 0) + if (Mem.ReadByte(curObj + 0x15) == 0) { - width = _api.MemLib.ReadS16(curObj + 0x44); - height = _api.MemLib.ReadS16(curObj + 0x48); + width = Mem.ReadS16(curObj + 0x44); + height = Mem.ReadS16(curObj + 0x48); } DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); } else if (type == 0xC056E) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - var width = _api.MemLib.ReadS16(curObj + 0x44); - var height = _api.MemLib.ReadS16(curObj + 0x48); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + var width = Mem.ReadS16(curObj + 0x44); + var height = Mem.ReadS16(curObj + 0x48); DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); } else if (type == 0xC4208) // Broken Glyph Base { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - var width = _api.MemLib.ReadS16(curObj + 0x44); - var height = _api.MemLib.ReadS16(curObj + 0x48); + var width = Mem.ReadS16(curObj + 0x44); + var height = Mem.ReadS16(curObj + 0x48); DrawBoxMWH(Xmid, Ymid, width, height, Color.PowderBlue); - if (_api.MemLib.ReadByte(curObj + 0x15) == 0) + if (Mem.ReadByte(curObj + 0x15) == 0) { DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 80, 80, 120, Color.Orange); } DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xAC242) // Broken Glyph Top repairing { - uint subObj = _api.MemLib.ReadU24(curObj + 0x5); - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - Xpos = _api.MemLib.ReadS16(subObj + 0x24) - _camX; - Ypos = _api.MemLib.ReadS16(subObj + 0x28) - _camY; - var width = _api.MemLib.ReadS16(curObj + 0x44); - var height = _api.MemLib.ReadS16(curObj + 0x48); + uint subObj = Mem.ReadU24(curObj + 0x5); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + Xpos = Mem.ReadS16(subObj + 0x24) - _camX; + Ypos = Mem.ReadS16(subObj + 0x28) - _camY; + var width = Mem.ReadS16(curObj + 0x44); + var height = Mem.ReadS16(curObj + 0x48); DrawBoxMWH(Xmid, Ymid, width, height, Color.Gray); Point[] rhombPoints = { @@ -1791,98 +1808,98 @@ namespace BizHawk.Client.EmuHawk new Point(Xpos + 3, Ypos), new Point(Xpos, Ypos + 3) }; - _api.GUILib.DrawPolygon(rhombPoints, Color.Orange, Color.FromArgb(63, Color.Orange)); + Gui.DrawPolygon(rhombPoints, Color.Orange, Color.FromArgb(63, Color.Orange)); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); } else if (type == 0xBE9C8) // Broken Glyph Top free { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xD9C0E) || (type == 0xDA9EA)) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawBoxMWH(Xmid, Ymid, 0xA0, 0x70, Color.Red); } else if ((type == 0xBF204) || (type == 0xDA2C0)) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xAF9CC) // Mirror Dolphin { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX + (_api.MemLib.ReadByte(curObj + 0x15) == 0 ? 27 : -27); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54) + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58) + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x1C) - _camX + (Mem.ReadByte(curObj + 0x15) == 0 ? 27 : -27); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - var width = _api.MemLib.ReadS16(curObj + 0x44); - var height = _api.MemLib.ReadS16(curObj + 0x48); + var width = Mem.ReadS16(curObj + 0x44); + var height = Mem.ReadS16(curObj + 0x48); DrawBoxMWH(Xmid, Ymid, width, height, Color.Blue, 31); - if (_api.MemLib.ReadByte(curObj + 0x13) != 0xAC) + if (Mem.ReadByte(curObj + 0x13) != 0xAC) { DrawBoxMWH(Xmid, Ymid, 96, 96, Color.Orange); } - _api.GUILib.DrawLine(Xpos, 0, Xpos, 448, Color.Red); + Gui.DrawLine(Xpos, 0, Xpos, 448, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xAF43E) // Vortex Lightning Trap { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - if (_api.MemLib.ReadByte(curObj + 0x15) != 0) + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + if (Mem.ReadByte(curObj + 0x15) != 0) { - if (_api.MemLib.ReadS16(0xFFAA12) != 0) + if (Mem.ReadS16(0xFFAA12) != 0) { Ymid -= 8; } DrawBoxMWH(Xmid, Ymid, 92, 16, Color.Red); - PutText(_api.MemLib.ReadByte(curObj + 0x15).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); + PutText(Mem.ReadByte(curObj + 0x15).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); } else { DrawBoxMWH(Xmid, Ymid, 92, 16, Color.Gray); - PutText(_api.MemLib.ReadByte(curObj + 0x7F).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); + PutText(Mem.ReadByte(curObj + 0x7F).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); } } else if (type == 0xA6E24) // Barrier Glyph Forcefield { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = _api.MemLib.ReadS32(0xFFAA1A) - Xmid; - Yvec = _api.MemLib.ReadS32(0xFFAA1E) - Ymid; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = Mem.ReadS32(0xFFAA1A) - Xmid; + Yvec = Mem.ReadS32(0xFFAA1E) - Ymid; var div = Math.Abs(Xvec) + Math.Abs(Yvec); Xvec /= div; Yvec /= div; Xvec += Xmid; Yvec += Ymid; @@ -1891,31 +1908,31 @@ namespace BizHawk.Client.EmuHawk Xmid -= _camX; Ymid -= _camY; Xvec -= _camX; Yvec -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xC4A44) || (type == 0xAA32C)) // Pulsar power-up and Vortex bullet-spawner { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue, 16); } else if (type == 0xC2F00) // Sky bubbles { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - var mode = _api.MemLib.ReadByte(curObj + 0x15); + var mode = Mem.ReadByte(curObj + 0x15); switch (mode) { case 0: @@ -1933,75 +1950,75 @@ namespace BizHawk.Client.EmuHawk break; } DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0x9FA7E) //Air refiller/drainer { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Lime)); } else if (type == 0xBFC14) //Pushable fish { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x54) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Orange); } else if ((type == 0xBE97C) //Slowing Kelp //Default Bounds nose-responsive || (type == 0xACDAE)) //Metasphere { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xACB42) // Turtle { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - var mode = _api.MemLib.ReadByte(curObj + 0x15); + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + var mode = Mem.ReadByte(curObj + 0x15); switch (mode) { case 0: case 1: case 2: case 3: - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x4C)) >> 16) - _camX; + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x4C)) >> 16) - _camX; break; case 4: case 5: case 6: case 7: - Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x4C)) >> 16) - _camX; + Xvec = ((Xmid - Mem.ReadS32(curObj + 0x4C)) >> 16) - _camX; break; default: Xvec = (Xmid >> 16) - _camX; @@ -2011,300 +2028,300 @@ namespace BizHawk.Client.EmuHawk Xmid >>= 16; Xmid -= _camX; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - int width = _api.MemLib.ReadS16(curObj + 0x44) << 1; + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + int width = Mem.ReadS16(curObj + 0x44) << 1; DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); - TickerText($"{_api.MemLib.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Lime); + TickerText($"{Mem.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xACA7E) // Retracting Turtle { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + (_api.MemLib.ReadS32(curObj + 0x4C) >> 1)) >> 16) - _camX; - Yvec = ((Ymid + (_api.MemLib.ReadS32(curObj + 0x50) >> 1)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + (Mem.ReadS32(curObj + 0x4C) >> 1)) >> 16) - _camX; + Yvec = ((Ymid + (Mem.ReadS32(curObj + 0x50) >> 1)) >> 16) - _camY; Xmid >>= 16; Xmid -= _camX; Ymid >>= 16; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - int width = _api.MemLib.ReadS16(curObj + 0x44) << 1; + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + int width = Mem.ReadS16(curObj + 0x44) << 1; DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); - TickerText($"{(_api.MemLib.ReadS32(curObj + 0x4C) >> 1) / 65536.0:0.######}:{(_api.MemLib.ReadS32(curObj + 0x50) >> 1) / 65536.0:0.######}", Color.Lime); + TickerText($"{(Mem.ReadS32(curObj + 0x4C) >> 1) / 65536.0:0.######}:{(Mem.ReadS32(curObj + 0x50) >> 1) / 65536.0:0.######}", Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xB5134) || (type == 0xA7E0C) //Default Bounds sonar-responsive || (type == 0xAF868) || (type == 0xAF960) || (type == 0xD8E5C) || (type == 0xAA5C6)) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if ((type == 0xACCB4) || (type == 0xACD7E) //Default Baunds non-responsive || (type == 0xD8D96) || (type == 0xA955E) || (type == 0xA92E4) || (type == 0xC05DC) || (type == 0xC2684)) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Gray); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0x9DE86) // Star Wreath { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - Xpos = _api.MemLib.ReadS32(curObj + 0x1C); - Ypos = _api.MemLib.ReadS32(curObj + 0x20); - Xpos2 = ((Xpos + _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Ypos2 = ((Ypos + _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xpos = Mem.ReadS32(curObj + 0x1C); + Ypos = Mem.ReadS32(curObj + 0x20); + Xpos2 = ((Xpos + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Ypos2 = ((Ypos + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - DrawBoxMWH(Xpos, Ypos, 1, 1, (_api.MemLib.ReadByte(curObj + 0x7F) == 0) ? Color.Blue : Color.Black, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); - if (_api.MemLib.ReadByte(curObj + 0x12) % 7 == 0) + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + DrawBoxMWH(Xpos, Ypos, 1, 1, (Mem.ReadByte(curObj + 0x7F) == 0) ? Color.Blue : Color.Black, 0); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + if (Mem.ReadByte(curObj + 0x12) % 7 == 0) { - TickerText($"{_api.MemLib.ReadS32(curObj + 0x5C) / 65536.0:0.######}:{_api.MemLib.ReadS32(curObj + 0x60) / 65536.0:0.######}:{_api.MemLib.ReadByte(curObj + 0x7F)}", Color.Lime); + TickerText($"{Mem.ReadS32(curObj + 0x5C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x60) / 65536.0:0.######}:{Mem.ReadByte(curObj + 0x7F)}", Color.Lime); } } else if ((type == 0x9D774) || (type == 0x9DA26)) // Fish { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 0x14, 0x14, Color.Lime); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xAD87C) // Enemy dolphins in metamorph levels { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(_api.MemLib.ReadS16(curObj + 0x1C) - _camX, _api.MemLib.ReadS16(curObj + 0x20) - _camY, 1024, 1024, Color.Orange, 0); + DrawBoxMWH(Mem.ReadS16(curObj + 0x1C) - _camX, Mem.ReadS16(curObj + 0x20) - _camY, 1024, 1024, Color.Orange, 0); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xC6128) // Drone attacking dolphin { - Xmid = _api.MemLib.ReadS16(curObj + 0x4C) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x50) - _camY; + Xmid = Mem.ReadS16(curObj + 0x4C) - _camX; + Ymid = Mem.ReadS16(curObj + 0x50) - _camY; DrawEccoOct(Xmid, Ymid, 360, Color.Red, 0); } else if (type == 0xC605A) // Drone attacking dolphin sonar { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camY; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camY; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawBox(Xmid, Ymid - 1, Xmid + 32, Ymid + 1, Color.Orange); } else if (type == 0xB1BE0) // Globe { - int mode = _api.MemLib.ReadS8(curObj + 0x15); + int mode = Mem.ReadS8(curObj + 0x15); if (mode == 1) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); - _api.GUILib.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xB1A10) // Approaching globes { - Xmid = _api.MemLib.ReadS16(0xFFAA1A) - _camX; - Ymid = _api.MemLib.ReadS16(0xFFAA1E) - _camY; + Xmid = Mem.ReadS16(0xFFAA1A) - _camX; + Ymid = Mem.ReadS16(0xFFAA1E) - _camY; DrawEccoOct(Xmid - 56, Ymid, 8, Color.Orange); DrawEccoOct(Xmid + 56, Ymid, 8, Color.Orange); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xpos = _api.MemLib.ReadS32(curObj + 0x4C); - Ypos = _api.MemLib.ReadS32(curObj + 0x50); - Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xpos2 = ((Xpos + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Ypos2 = ((Ypos + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xpos = Mem.ReadS32(curObj + 0x4C); + Ypos = Mem.ReadS32(curObj + 0x50); + Xvec = ((Xmid - Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid - Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos2 = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Ypos2 = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; Xpos >>= 16; Ypos >>= 16; Xpos -= _camX; Ypos -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); } else if (type == 0xB1920) // Orbiting globes { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xpos = _api.MemLib.ReadS16(curObj + 0x4C) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x50) - _camY; - Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x60)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x4C) - _camX; + Ypos = Mem.ReadS16(curObj + 0x50) - _camY; + Xvec = ((Xmid - Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; + Yvec = ((Ymid - Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); } else if (type == 0xC28A0) // Control point in Four Islands/Dolphin that gives Rock-breaking song { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, _api.MemLib.ReadByte(curObj + 0x15) == 0 ? Color.Orange : Color.Blue); + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Mem.ReadByte(curObj + 0x15) == 0 ? Color.Orange : Color.Blue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } // Crystal Springs merging glyphs else if (type == 0xC651E) // Bound glyph { - Xpos = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; + Ypos = Mem.ReadS16(curObj + 0x20) - _camY; DrawEccoRhomb(Xpos, Ypos, 4 << 4, Color.Orange); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xC67E4) // Freed glyph { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xC6970) // Pulled glyph { - uint subObj = _api.MemLib.ReadU24(curObj + 5); - Xvec = _api.MemLib.ReadS32(subObj + 0x54); - Yvec = _api.MemLib.ReadS32(subObj + 0x58); - for (i = 1; i < _api.MemLib.ReadByte(curObj + 0x7F); i++) + uint subObj = Mem.ReadU24(curObj + 5); + Xvec = Mem.ReadS32(subObj + 0x54); + Yvec = Mem.ReadS32(subObj + 0x58); + for (i = 1; i < Mem.ReadByte(curObj + 0x7F); i++) { Xvec ^= Yvec; Yvec ^= Xvec; Xvec ^= Yvec; Xvec = 0 - Xvec; } - Xpos = (Xvec + _api.MemLib.ReadS32(subObj + 0x1C) >> 16) - _camX; - Ypos = (Yvec + _api.MemLib.ReadS32(subObj + 0x20) >> 16) - _camY; + Xpos = (Xvec + Mem.ReadS32(subObj + 0x1C) >> 16) - _camX; + Ypos = (Yvec + Mem.ReadS32(subObj + 0x20) >> 16) - _camY; DrawEccoRhomb(Xpos, Ypos, 3, Color.Orange); - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); } else if (type == 0xC6BA8) // Delivery Point { - Xvec = _api.MemLib.ReadS32(curObj + 0x54); - Yvec = _api.MemLib.ReadS32(curObj + 0x58); - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xvec = Mem.ReadS32(curObj + 0x54); + Yvec = Mem.ReadS32(curObj + 0x58); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); for (i = 0; i < 4; i++) { - Xpos = (Xvec + _api.MemLib.ReadS32(curObj + 0x1C) >> 16) - _camX; - Ypos = (Yvec + _api.MemLib.ReadS32(curObj + 0x20) >> 16) - _camY; - _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + Xpos = (Xvec + Mem.ReadS32(curObj + 0x1C) >> 16) - _camX; + Ypos = (Yvec + Mem.ReadS32(curObj + 0x20) >> 16) - _camY; + Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); Xvec ^= Yvec; Yvec ^= Xvec; Xvec ^= Yvec; @@ -2313,46 +2330,46 @@ namespace BizHawk.Client.EmuHawk } else if (type == 0xC6A6C) // Delivered glyph { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid - Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid - Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xC6F82) // Full delivery point { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawEccoOct(Xmid, Ymid, 3, Color.Orange); } else if (type == 0xC6A9E) // Merging glyph { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid - _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid - _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid - Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid - Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xC7052) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS16(curObj + 0x24); - Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS16(curObj + 0x24); + Ymid = Mem.ReadS16(curObj + 0x28); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; - uint dropSpeed = _api.MemLib.ReadU8(curObj + 0x16); + uint dropSpeed = Mem.ReadU8(curObj + 0x16); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xmid, Ymid + (int)(dropSpeed), Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xmid, Ymid + (int)(dropSpeed), Color.Orange); } else if ((type == 0xD8B7C) || (type == 0xD89EA) || (type == 0x9E3AA) || (type == 0x9E5A8) // GFX particles don't need displayed. || (type == 0x9B5D8) || (type == 0x9E2A6) || (type == 0xACD1E) || (type == 0xD9678) @@ -2380,14 +2397,14 @@ namespace BizHawk.Client.EmuHawk || (type == 0xC32C8) || (type == 0xAB5E6) || (type == 0xAC796) || (type == 0xAC9F2) || (type == 0xA538A)) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; @@ -2397,7 +2414,7 @@ namespace BizHawk.Client.EmuHawk if (type != 0xA975E) { DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } if (HP > 2) { @@ -2406,33 +2423,33 @@ namespace BizHawk.Client.EmuHawk } else // Default bounds { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); PutText(type.ToString("X5"), Xmid, Ymid + 8, 1, 9, -1, -1, Color.Blue, Color.Red); } break; } case Modes.Ecco1: - type = _api.MemLib.ReadU32(curObj + 0x6); - Xpos = _api.MemLib.ReadS16(curObj + 0x17); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x1F); - Ypos = _api.MemLib.ReadS16(curObj + 0x1B); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x23); - Xmid = _api.MemLib.ReadS16(curObj + 0x0F); - Ymid = _api.MemLib.ReadS16(curObj + 0x13); + type = Mem.ReadU32(curObj + 0x6); + Xpos = Mem.ReadS16(curObj + 0x17); + Xpos2 = Mem.ReadS16(curObj + 0x1F); + Ypos = Mem.ReadS16(curObj + 0x1B); + Ypos2 = Mem.ReadS16(curObj + 0x23); + Xmid = Mem.ReadS16(curObj + 0x0F); + Ymid = Mem.ReadS16(curObj + 0x13); Xpos >>= 2; Xpos2 >>= 2; Ypos >>= 2; @@ -2446,13 +2463,13 @@ namespace BizHawk.Client.EmuHawk PutText(type.ToString("X8"), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); break; } - curObj = _api.MemLib.ReadU24(curObj+1); + curObj = Mem.ReadU24(curObj+1); } //events - curObj = _api.MemLib.ReadU24(0xFFCFB5); + curObj = Mem.ReadU24(0xFFCFB5); while (curObj != 0) { - type = _api.MemLib.ReadU32(curObj + 0xC); + type = Mem.ReadU32(curObj + 0xC); if ((type == 0) // Null object || (type == 0x9C1FA) || (type == 0x9C6D0) // Skytubes BG Image manager || (type == 0x9ED72) || (type == 0xA57F2) // And Miscellaneous GFX particles @@ -2460,22 +2477,22 @@ namespace BizHawk.Client.EmuHawk || (type == 0xB308A) || (type == 0xA1676) || (type == 0xB6822) || (type == 0xD12E2)) { } else if ((type == 0xA44EE) || (type == 0xD120C)) { - Xmid = _api.MemLib.ReadS16(curObj + 0x1C) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x20) - _camY; + Xmid = Mem.ReadS16(curObj + 0x1C) - _camX; + Ymid = Mem.ReadS16(curObj + 0x20) - _camY; DrawEccoOct(Xmid, Ymid, 0x20, Color.Red); } else if (type == 0x9F0D0) // Water Current { - int Xvec = _api.MemLib.ReadS32(curObj + 0x54); - int Yvec = _api.MemLib.ReadS32(curObj + 0x58); + int Xvec = Mem.ReadS32(curObj + 0x54); + int Yvec = Mem.ReadS32(curObj + 0x58); if ((Xvec != 0) || (Yvec != 0)) { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); Xvec += Xmid; Yvec += Ymid; Xmid >>= 16; Ymid >>= 16; Xvec >>= 16; Yvec >>= 16; @@ -2485,73 +2502,73 @@ namespace BizHawk.Client.EmuHawk Xvec -= _camX; Yvec -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Red)); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } } else if (type == 0xDEF94) { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawEccoOct(Xmid, Ymid, 0x18, Color.Cyan); } else if (type == 0xA6584) // Eagle { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawEccoOct(Xmid, Ymid, 0x10, Color.Red); } else if ((type == 0x9BA8A) // Autoscroller controller || (type == 0xE27D4) || (type == 0xE270E) || (type == 0xE26C2)) { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - var Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - var Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + var Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + var Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0x9B948) // Autoscroller waypoint { - Xmid = _api.MemLib.ReadS32(curObj + 0x24); - Ymid = _api.MemLib.ReadS32(curObj + 0x28); - var Xvec = ((Xmid + _api.MemLib.ReadS32(curObj + 0x54)) >> 16) - _camX; - var Yvec = ((Ymid + _api.MemLib.ReadS32(curObj + 0x58)) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj + 0x24); + Ymid = Mem.ReadS32(curObj + 0x28); + var Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; + var Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 8, 8, Color.Orange); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } else if (type == 0xA5448) // Bomb spawner { - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - PutText($"{_api.MemLib.ReadU16(curObj + 0x6E)}", Xmid, Ymid, 1, 1, -1, -1, Color.White, Color.Blue); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + PutText($"{Mem.ReadU16(curObj + 0x6E)}", Xmid, Ymid, 1, 1, -1, -1, Color.White, Color.Blue); } else if ((type == 0xA529C) || (type == 0xA5236) || (type == 0xA51E6)) // Explosion { - uint subObj = _api.MemLib.ReadU24(curObj + 5); + uint subObj = Mem.ReadU24(curObj + 5); if (subObj != 0) { - Xpos = _api.MemLib.ReadS16(subObj + 0x1C) - _camX; - Ypos = _api.MemLib.ReadS16(subObj + 0x28) - _camY; - int Width = _api.MemLib.ReadS16(subObj + 0x24) - Xpos - _camX; + Xpos = Mem.ReadS16(subObj + 0x1C) - _camX; + Ypos = Mem.ReadS16(subObj + 0x28) - _camY; + int Width = Mem.ReadS16(subObj + 0x24) - Xpos - _camX; DrawBoxMWH(Xpos, Ypos, Width, 16, Color.Red); } - subObj = _api.MemLib.ReadU24(curObj + 9); + subObj = Mem.ReadU24(curObj + 9); if (subObj != 0) { - Xpos = _api.MemLib.ReadS16(subObj + 0x1C) - _camX; - Ypos = _api.MemLib.ReadS16(subObj + 0x28) - _camY; - int Width = _api.MemLib.ReadS16(subObj + 0x24) - Xpos - _camX; + Xpos = Mem.ReadS16(subObj + 0x1C) - _camX; + Ypos = Mem.ReadS16(subObj + 0x28) - _camY; + int Width = Mem.ReadS16(subObj + 0x24) - Xpos - _camX; DrawBoxMWH(Xpos, Ypos, Width, 16, Color.Red); } } else if (type == 0x9B5D8) { - var subtype = _api.MemLib.ReadByte(curObj + 0x13); + var subtype = Mem.ReadByte(curObj + 0x13); int width = 0; int height = 0; switch (subtype) @@ -2568,10 +2585,10 @@ namespace BizHawk.Client.EmuHawk case 59: case 87: case 181: - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - width = _api.MemLib.ReadS16(curObj + 0x44); - height = _api.MemLib.ReadS16(curObj + 0x48); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + width = Mem.ReadS16(curObj + 0x44); + height = Mem.ReadS16(curObj + 0x48); DrawEccoOct(Xmid, Ymid, (width + height) >> 1, Color.Lime); break; case 71: @@ -2579,10 +2596,10 @@ namespace BizHawk.Client.EmuHawk case 158: case 159: case 165: - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); break; case 82: @@ -2590,71 +2607,71 @@ namespace BizHawk.Client.EmuHawk case 84: case 85: case 86: - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - width = _api.MemLib.ReadS16(curObj + 0x44); - height = _api.MemLib.ReadS16(curObj + 0x48); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + width = Mem.ReadS16(curObj + 0x44); + height = Mem.ReadS16(curObj + 0x48); DrawBoxMWH(Xmid, Ymid, width, height, Color.Red); break; case 210: - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; - width = _api.MemLib.ReadS16(curObj + 0x44); - height = _api.MemLib.ReadS16(curObj + 0x48); + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; + width = Mem.ReadS16(curObj + 0x44); + height = Mem.ReadS16(curObj + 0x48); DrawBoxMWH(Xmid, Ymid, width, height, Color.Blue); break; case 107: - Xmid = (_api.MemLib.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; - Ymid = (_api.MemLib.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; - Xpos = (_api.MemLib.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; - Ypos = (_api.MemLib.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; + Xmid = (Mem.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; + Ymid = (Mem.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; + Xpos = (Mem.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; + Ypos = (Mem.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; DrawBoxMWH(Xmid, Ymid, 64, 64, Color.Orange, 0); DrawBoxMWH(Xpos, Ypos, 64, 64, Color.Orange, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); break; case 110: //Gravity conrol points case 179: - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63,_api.MemLib.ReadByte(curObj + 0x15) == 0 ? Color.Gray : Color.Red)); + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; + DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63,Mem.ReadByte(curObj + 0x15) == 0 ? Color.Gray : Color.Red)); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); - int dir = _api.MemLib.ReadS8(curObj + 0x71) & 7; + int dir = Mem.ReadS8(curObj + 0x71) & 7; int[] xtable = { 7, 4, -3, -10, -14, -11, -3, 4}; int[] ytable = { 11, 4, 7, 4, -3, -11, -14, -11}; - Xmid = _api.MemLib.ReadS16(curObj + 0x24) - _camX; - Ymid = _api.MemLib.ReadS16(curObj + 0x28) - _camY; + Xmid = Mem.ReadS16(curObj + 0x24) - _camX; + Ymid = Mem.ReadS16(curObj + 0x28) - _camY; DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawImage(".\\dll\\gravitometer_bg.png", Xmid - 15, Ymid - 15); - _api.GUILib.DrawImage(".\\dll\\gravitometer_fg.png", Xmid + xtable[dir], Ymid + ytable[dir]); + Gui.DrawImage(".\\dll\\gravitometer_bg.png", Xmid - 15, Ymid - 15); + Gui.DrawImage(".\\dll\\gravitometer_fg.png", Xmid + xtable[dir], Ymid + ytable[dir]); break; case 176: - Xmid = (_api.MemLib.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; - Ymid = (_api.MemLib.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; - Xpos = (_api.MemLib.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; - Ypos = (_api.MemLib.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; + Xmid = (Mem.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; + Ymid = (Mem.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; + Xpos = (Mem.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; + Ypos = (Mem.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; DrawEccoOct(Xmid, Ymid, 32, Color.Orange, 0); DrawEccoOct(Xpos, Ypos, 32, Color.Orange, 0); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); break; case 194: // Kill plane - Xpos = _api.MemLib.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34) - _camX; - Ypos = _api.MemLib.ReadS16(curObj + 0x30) - _camY; - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38) - _camY; + Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; + Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; + Ypos = Mem.ReadS16(curObj + 0x30) - _camY; + Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Black, 127); DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); break; default: - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2 = _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2 = _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS16(curObj + 0x24); - Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2 = Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2 = Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS16(curObj + 0x24); + Ymid = Mem.ReadS16(curObj + 0x28); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; @@ -2666,58 +2683,58 @@ namespace BizHawk.Client.EmuHawk } else { - Xpos = _api.MemLib.ReadS16(curObj + 0x2C); - Xpos2= _api.MemLib.ReadS16(curObj + 0x34); - Ypos = _api.MemLib.ReadS16(curObj + 0x30); - Ypos2= _api.MemLib.ReadS16(curObj + 0x38); - Xmid = _api.MemLib.ReadS16(curObj + 0x24); - Ymid = _api.MemLib.ReadS16(curObj + 0x28); + Xpos = Mem.ReadS16(curObj + 0x2C); + Xpos2= Mem.ReadS16(curObj + 0x34); + Ypos = Mem.ReadS16(curObj + 0x30); + Ypos2= Mem.ReadS16(curObj + 0x38); + Xmid = Mem.ReadS16(curObj + 0x24); + Ymid = Mem.ReadS16(curObj + 0x28); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); - PutText($"{type:X5}:{_api.MemLib.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); + PutText($"{type:X5}:{Mem.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); } - curObj = _api.MemLib.ReadU24(curObj+1); + curObj = Mem.ReadU24(curObj+1); } //Ecco head - Xpos = _api.MemLib.ReadS16(0xFFA8F8); - Xpos2 = _api.MemLib.ReadS16(0xFFA900); - Ypos = _api.MemLib.ReadS16(0xFFA8FC); - Ypos2 = _api.MemLib.ReadS16(0xFFA904); - Xmid = _api.MemLib.ReadS16(0xFFA8F0); - Ymid = _api.MemLib.ReadS16(0xFFA8F4); + Xpos = Mem.ReadS16(0xFFA8F8); + Xpos2 = Mem.ReadS16(0xFFA900); + Ypos = Mem.ReadS16(0xFFA8FC); + Ypos2 = Mem.ReadS16(0xFFA904); + Xmid = Mem.ReadS16(0xFFA8F0); + Ymid = Mem.ReadS16(0xFFA8F4); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.PowderBlue, 0); //Ecco tail - Xpos = _api.MemLib.ReadS16(0xFFA978); - Xpos2 = _api.MemLib.ReadS16(0xFFA980); - Ypos = _api.MemLib.ReadS16(0xFFA97C); - Ypos2 = _api.MemLib.ReadS16(0xFFA984); - Xmid = _api.MemLib.ReadS16(0xFFA970); - Ymid = _api.MemLib.ReadS16(0xFFA974); + Xpos = Mem.ReadS16(0xFFA978); + Xpos2 = Mem.ReadS16(0xFFA980); + Ypos = Mem.ReadS16(0xFFA97C); + Ypos2 = Mem.ReadS16(0xFFA984); + Xmid = Mem.ReadS16(0xFFA970); + Ymid = Mem.ReadS16(0xFFA974); Xpos -= _camX; Xpos2 -= _camX; Ypos -= _camY; Ypos2 -= _camY; Xmid -= _camX; Ymid -= _camY; DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.PowderBlue, 0); //Ecco body - Xpos = _api.MemLib.ReadS32(0xFFAA22); - Ypos = _api.MemLib.ReadS32(0xFFAA26); - Xpos2 = _api.MemLib.ReadS32(0xFFAA2A); - Ypos2 = _api.MemLib.ReadS32(0xFFAA2E); - Xmid = _api.MemLib.ReadS16(0xFFAA1A); - Ymid = _api.MemLib.ReadS16(0xFFAA1E); - int Xvel = _api.MemLib.ReadS32(0xFFAA36); - if (_api.MemLib.ReadU32(0xFFA9D6) > 7) Xvel += _api.MemLib.ReadS32(0xFFA9D6); - if (_api.MemLib.ReadU32(0xFFAA3E) > 7) Xvel += _api.MemLib.ReadS32(0xFFAA3E); - int Yvel = _api.MemLib.ReadS32(0xFFAA3A); - if (_api.MemLib.ReadU32(0xFFA9DA) > 7) Yvel += _api.MemLib.ReadS32(0xFFA9DA); - if (_api.MemLib.ReadU32(0xFFAA42) > 7) Yvel += _api.MemLib.ReadS32(0xFFAA42); + Xpos = Mem.ReadS32(0xFFAA22); + Ypos = Mem.ReadS32(0xFFAA26); + Xpos2 = Mem.ReadS32(0xFFAA2A); + Ypos2 = Mem.ReadS32(0xFFAA2E); + Xmid = Mem.ReadS16(0xFFAA1A); + Ymid = Mem.ReadS16(0xFFAA1E); + int Xvel = Mem.ReadS32(0xFFAA36); + if (Mem.ReadU32(0xFFA9D6) > 7) Xvel += Mem.ReadS32(0xFFA9D6); + if (Mem.ReadU32(0xFFAA3E) > 7) Xvel += Mem.ReadS32(0xFFAA3E); + int Yvel = Mem.ReadS32(0xFFAA3A); + if (Mem.ReadU32(0xFFA9DA) > 7) Yvel += Mem.ReadS32(0xFFA9DA); + if (Mem.ReadU32(0xFFAA42) > 7) Yvel += Mem.ReadS32(0xFFAA42); int XV = ((Xpos + Xvel) >> 16) - _camX; int YV = ((Ypos + Yvel) >> 16) - _camY; int XV2 = ((Xpos2 + Xvel) >> 16) - _camX; @@ -2733,58 +2750,58 @@ namespace BizHawk.Client.EmuHawk int X4 = (Xmid + X2) >> 1; int Y3 = (Ymid + Y) >> 1; int Y4 = (Ymid + Y2) >> 1; - _api.GUILib.DrawLine(X, Y, Xmid, Ymid, Color.Green); - _api.GUILib.DrawLine(Xmid, Ymid, X2, Y2, Color.Green); + Gui.DrawLine(X, Y, Xmid, Ymid, Color.Green); + Gui.DrawLine(Xmid, Ymid, X2, Y2, Color.Green); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Red); DrawBoxMWH(X, Y, 1, 1, Color.Lime); DrawBoxMWH(X2, Y2, 1, 1, Color.Blue); DrawBoxMWH(X3, Y3, 1, 1, Color.Yellow); DrawBoxMWH(X4, Y4, 1, 1, Color.Yellow); - _api.GUILib.DrawLine(X, Y, XV, YV, Color.Orange); - _api.GUILib.DrawLine(X2, Y2, XV2, YV2, Color.Orange); + Gui.DrawLine(X, Y, XV, YV, Color.Orange); + Gui.DrawLine(X2, Y2, XV2, YV2, Color.Orange); // sonar - if (_api.MemLib.ReadU8(0xFFAB77) != 0) + if (Mem.ReadU8(0xFFAB77) != 0) { - Xmid = _api.MemLib.ReadS32(0xFFA9EC); - Ymid = _api.MemLib.ReadS32(0xFFA9F0); - int Xvec = ((_api.MemLib.ReadS32(0xFFAA04) + Xmid) >> 16) - _camX; - int Yvec = ((_api.MemLib.ReadS32(0xFFAA08) + Ymid) >> 16) - _camY; + Xmid = Mem.ReadS32(0xFFA9EC); + Ymid = Mem.ReadS32(0xFFA9F0); + int Xvec = ((Mem.ReadS32(0xFFAA04) + Xmid) >> 16) - _camX; + int Yvec = ((Mem.ReadS32(0xFFAA08) + Ymid) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; - Width2 = _api.MemLib.ReadS16(0xFFA9FC); - Height2 = _api.MemLib.ReadS16(0xFFAA00); - color = ((_api.MemLib.ReadU8(0xFFAA0C) != 0) ? Color.FromArgb(255, 0, 127) : Color.FromArgb(0, 0, 255)); + Width2 = Mem.ReadS16(0xFFA9FC); + Height2 = Mem.ReadS16(0xFFAA00); + color = ((Mem.ReadU8(0xFFAA0C) != 0) ? Color.FromArgb(255, 0, 127) : Color.FromArgb(0, 0, 255)); DrawBoxMWH(Xmid, Ymid, Width2, Height2, color); DrawBoxMWH(Xmid, Ymid, 1, 1, color, 0); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } //Pulsar - curObj = _api.MemLib.ReadU24(0xFFCFD1); - if ((curObj != 0) && ((_api.MemLib.ReadU32(curObj + 0xC) == 0xC9222) || (_api.MemLib.ReadU32(curObj + 0xC) == 0xC9456))) + curObj = Mem.ReadU24(0xFFCFD1); + if ((curObj != 0) && ((Mem.ReadU32(curObj + 0xC) == 0xC9222) || (Mem.ReadU32(curObj + 0xC) == 0xC9456))) { curObj += 0x26; for (int l = 0; l < 4; l++) { - if (_api.MemLib.ReadU16(curObj + 0x12) != 0) + if (Mem.ReadU16(curObj + 0x12) != 0) { - Xmid = _api.MemLib.ReadS32(curObj); - Ymid = _api.MemLib.ReadS32(curObj + 4); - int Xvec = (Xmid + _api.MemLib.ReadS32(curObj + 8) >> 16) - _camX; - int Yvec = (Ymid + _api.MemLib.ReadS32(curObj + 0xC) >> 16) - _camY; + Xmid = Mem.ReadS32(curObj); + Ymid = Mem.ReadS32(curObj + 4); + int Xvec = (Xmid + Mem.ReadS32(curObj + 8) >> 16) - _camX; + int Yvec = (Ymid + Mem.ReadS32(curObj + 0xC) >> 16) - _camY; Xmid >>= 16; Ymid >>= 16; Xmid -= _camX; Ymid -= _camY; DrawBoxMWH(Xmid, Ymid, 0x30, 0x30, Color.Red); DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue); - _api.GUILib.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); + Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); } curObj += 0x14; } } //Water Level - int waterLevel = _api.MemLib.ReadS16(0xFFA7B2); - _api.GUILib.DrawLine(0, waterLevel - _camY, _left + 320 + _right, waterLevel - _camY, Color.Aqua); + int waterLevel = Mem.ReadS16(0xFFA7B2); + Gui.DrawLine(0, waterLevel - _camY, _left + 320 + _right, waterLevel - _camY, Color.Aqua); } @@ -2792,43 +2809,43 @@ namespace BizHawk.Client.EmuHawk { //Modif N - ECCO HACK - make caps lock (weirdly) autofire player 1's C key uint charge; - uint mode = _api.MemLib.ReadU8(0xFFA555); - int frameCount = _api.EmuLib.FrameCount(); - int lagCount = _api.EmuLib.LagCount(); - _api.JoypadLib.Set("Start", on, 1); + uint mode = Mem.ReadU8(0xFFA555); + int frameCount = Emu.FrameCount(); + int lagCount = Emu.LagCount(); + Joy.Set("Start", on, 1); switch (mode) { case 0x00: if (on) { - if (_api.MemLib.ReadU16(0xFFF342) == 0xFFFD) - _api.JoypadLib.Set("C", true, 1); + if (Mem.ReadU16(0xFFF342) == 0xFFFD) + Joy.Set("C", true, 1); else - _api.JoypadLib.Set("C", false, 1); + Joy.Set("C", false, 1); } break; case 0xE6: - if (_api.MemLib.ReadU16(0xFFD5E8) == 0x00000002) { + if (Mem.ReadU16(0xFFD5E8) == 0x00000002) { Dictionary buttons = new Dictionary(); buttons["B"] = buttons["C"] = true; - _api.JoypadLib.Set(buttons, 1); + Joy.Set(buttons, 1); } else { Dictionary buttons = new Dictionary(); buttons["B"] = buttons["C"] = false; - _api.JoypadLib.Set(buttons, 1); + Joy.Set(buttons, 1); } break; case 0xF6: - charge = _api.MemLib.ReadU8(0xFFB19B); + charge = Mem.ReadU8(0xFFB19B); if (on) { - if ((charge <= 1) && ((_api.MemLib.ReadU8(0xFFB1A6) == 0) || (_api.MemLib.ReadU8(0xFFB1A9) != 0))) - _api.JoypadLib.Set("B", true, 1); + if ((charge <= 1) && ((Mem.ReadU8(0xFFB1A6) == 0) || (Mem.ReadU8(0xFFB1A9) != 0))) + Joy.Set("B", true, 1); else if (charge > 1) - _api.JoypadLib.Set("B", false, 1); - _api.JoypadLib.Set("C", (_api.MemLib.ReadU16(0xFFA7C8) % 2) == 0, 1); + Joy.Set("B", false, 1); + Joy.Set("C", (Mem.ReadU16(0xFFA7C8) % 2) == 0, 1); } break; case 0x20: @@ -2836,19 +2853,19 @@ namespace BizHawk.Client.EmuHawk case 0xAC: if (on) { - if ((_api.MemLib.ReadU8(0xFFAB72) & 3) == 0) - _api.JoypadLib.Set("C", (_api.MemLib.ReadS8(0xFFAA6E) < 11), 1); + if ((Mem.ReadU8(0xFFAB72) & 3) == 0) + Joy.Set("C", (Mem.ReadS8(0xFFAA6E) < 11), 1); } break; default: break; } } - public override void Init(IPluginAPI api) + public override void Init(IApiContainer api) { base.Init(api); - _api.MemLib.SetBigEndian(); - string gameName = _api.GameInfoLib.GetRomName(); + Mem.SetBigEndian(); + string gameName = GI.GetRomName(); if ((gameName == "ECCO - The Tides of Time (J) [!]") || (gameName == "ECCO - The Tides of Time (U) [!]") || (gameName == "ECCO - The Tides of Time (E) [!]")) @@ -2858,7 +2875,7 @@ namespace BizHawk.Client.EmuHawk _camYAddr = 0xFFAD9E; _top = _bottom = 112; _left = _right = 160; - EmuHawkPluginLibrary.SetGameExtraPadding(_left, _top, _right, _bottom); + ClientApi.SetGameExtraPadding(_left, _top, _right, _bottom); } else if ((gameName == "ECCO The Dolphin (J) [!]") || (gameName == "ECCO The Dolphin (UE) [!]")) @@ -2869,7 +2886,7 @@ namespace BizHawk.Client.EmuHawk _camYAddr = 0xFFB834; _top = _bottom = 112; _left = _right = 160; - EmuHawkPluginLibrary.SetGameExtraPadding(_left, _top, _right, _bottom); + ClientApi.SetGameExtraPadding(_left, _top, _right, _bottom); } else { @@ -2879,48 +2896,47 @@ namespace BizHawk.Client.EmuHawk } private Color BackdropColor() { - uint color = _api.MemLib.ReadU16(0, "CRAM"); + uint color = Mem.ReadU16(0, "CRAM"); int r = (int)(( color & 0x7) * 0x22); int g = (int)(((color >> 3) & 0x7) * 0x22); int b = (int)(((color >> 6) & 0x7) * 0x22); return Color.FromArgb(r, g, b); - } public override void PreFrameCallback() { - _api.GUILib.ClearText(); + Gui.ClearText(); if (_mode != Modes.disabled) { - _camX = _api.MemLib.ReadS16(_camXAddr) - _left; - _camY = _api.MemLib.ReadS16(_camYAddr) - _top; - EccoAutofire(_api.JoypadLib.Get(1)["Start"]); + _camX = Mem.ReadS16(_camXAddr) - _left; + _camY = Mem.ReadS16(_camYAddr) - _top; + EccoAutofire(Joy.Get(1)["Start"]); if (_dumpMap == 0) { Color bg = BackdropColor(); - _api.GUILib.DrawRectangle(0, 0, _left + 320 + _right, _top, bg, bg); - _api.GUILib.DrawRectangle(0, 0, _left, _top + 224 + _bottom, bg, bg); - _api.GUILib.DrawRectangle(_left + 320, 0, _left + 320 + _right, _top + 224 + _bottom, bg, bg); - _api.GUILib.DrawRectangle(0, _top + 224, _left + 320 + _right, _top + 224 + _bottom, bg, bg); + Gui.DrawRectangle(0, 0, _left + 320 + _right, _top, bg, bg); + Gui.DrawRectangle(0, 0, _left, _top + 224 + _bottom, bg, bg); + Gui.DrawRectangle(_left + 320, 0, _left + 320 + _right, _top + 224 + _bottom, bg, bg); + Gui.DrawRectangle(0, _top + 224, _left + 320 + _right, _top + 224 + _bottom, bg, bg); } - uint mode = _api.MemLib.ReadByte(0xFFA555); + uint mode = Mem.ReadByte(0xFFA555); switch (mode) { case 0x20: case 0x28: case 0xAC: - //EmuHawkPluginLibrary.SetGameExtraPadding(160, 112, 160, 112); + //ClientApi.SetGameExtraPadding(160, 112, 160, 112); if (_dumpMap <= 1) EccoDrawBoxes(); // Uncomment the following block to enable mapdumping - if ((_api.MemLib.ReadU16(0xFFA7C8) > 1) && (_api.MemLib.ReadU16(0xFFA7C8) < 4)) + if ((Mem.ReadU16(0xFFA7C8) > 1) && (Mem.ReadU16(0xFFA7C8) < 4)) { _dumpMap = 1; _rowStateGuid = string.Empty; _top = _bottom = _left = _right = 0; - EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); + ClientApi.SetGameExtraPadding(0, 0, 0, 0); } if (_dumpMap == 3) { - var levelID = _api.MemLib.ReadS8(0xFFA7D0); + var levelID = Mem.ReadS8(0xFFA7D0); int[] nameGroupLengths = { 7,1,11,6, @@ -2946,15 +2962,15 @@ namespace BizHawk.Client.EmuHawk if (i < 0) { i += nameGroupLengths[nameGroup]; - uint strOffset = _api.MemLib.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); + uint strOffset = Mem.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); Console.WriteLine($"{i}"); - strOffset = _api.MemLib.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); + strOffset = Mem.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); strOffset += 0x20; List strTmp = new List(); byte c; do { - c = (byte)_api.MemLib.ReadByte(strOffset++); + c = (byte)Mem.ReadByte(strOffset++); if (c != 0) strTmp.Add(c); } while (c != 0); @@ -2962,14 +2978,14 @@ namespace BizHawk.Client.EmuHawk TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; name = textInfo.ToTitleCase(name).Replace(" ", string.Empty); } - EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_top.png"); + ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_top.png"); _destX = _destY = 0; - EmuHawkPluginLibrary.SetGameExtraPadding(0, 0, 0, 0); + ClientApi.SetGameExtraPadding(0, 0, 0, 0); _dumpMap++; } if (_dumpMap == 6) { - var levelID = _api.MemLib.ReadS8(0xFFA7D0); + var levelID = Mem.ReadS8(0xFFA7D0); int[] nameGroupLengths = { 7,1,11,6, @@ -2995,15 +3011,15 @@ namespace BizHawk.Client.EmuHawk if (i < 0) { i += nameGroupLengths[nameGroup]; - uint strOffset = _api.MemLib.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); + uint strOffset = Mem.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); Console.WriteLine($"{i}"); - strOffset = _api.MemLib.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); + strOffset = Mem.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); strOffset += 0x20; List strTmp = new List(); byte c; do { - c = (byte)_api.MemLib.ReadByte(strOffset++); + c = (byte)Mem.ReadByte(strOffset++); if (c != 0) strTmp.Add(c); } while (c != 0); @@ -3011,11 +3027,11 @@ namespace BizHawk.Client.EmuHawk TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; name = textInfo.ToTitleCase(name).Replace(" ", string.Empty); } - EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_bottom.png"); + ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_bottom.png"); _destX = _destY = 0; _left = _right = 160; _top = _bottom = 112; - EmuHawkPluginLibrary.SetGameExtraPadding(_left, _top, _right, _bottom); + ClientApi.SetGameExtraPadding(_left, _top, _right, _bottom); _dumpMap = 0; } break; @@ -3025,52 +3041,52 @@ namespace BizHawk.Client.EmuHawk default: break; } - _prevF = _api.MemLib.ReadU32(0xFFA524); + _prevF = Mem.ReadU32(0xFFA524); } } public override void PostFrameCallback() { - uint frame = _api.MemLib.ReadU32(0xFFA524); - if ((frame <= _prevF) && !_api.EmuLib.IsLagged()) + uint frame = Mem.ReadU32(0xFFA524); + if ((frame <= _prevF) && !Emu.IsLagged()) { - _api.EmuLib.SetIsLagged(true); - _api.EmuLib.SetLagCount(_api.EmuLib.LagCount() + 1); + Emu.SetIsLagged(true); + Emu.SetLagCount(Emu.LagCount() + 1); } - uint mode = _api.MemLib.ReadByte(0xFFA555); + uint mode = Mem.ReadByte(0xFFA555); _tickerY = 81; - string valueTicker = $"{_api.MemLib.ReadU32(0xFFA520)}:{_api.MemLib.ReadU32(0xFFA524)}:{_api.MemLib.ReadU16(0xFFA7C8)}:{mode:X2}"; + string valueTicker = $"{Mem.ReadU32(0xFFA520)}:{Mem.ReadU32(0xFFA524)}:{Mem.ReadU16(0xFFA7C8)}:{mode:X2}"; TickerText(valueTicker); switch (mode) { case 0x20: case 0x28: case 0xAC: - valueTicker = $"{_api.MemLib.ReadS16(0xFFAD9C)}:{_api.MemLib.ReadS16(0xFFAD9E)}"; + valueTicker = $"{Mem.ReadS16(0xFFAD9C)}:{Mem.ReadS16(0xFFAD9E)}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFAA1A) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFAA1E) / 65536.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFAA1A) / 65536.0:0.######}:{Mem.ReadS32(0xFFAA1E) / 65536.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFAA32) / 65536.0:0.######}:{_api.MemLib.ReadU8(0xFFAA6D)}:{_api.MemLib.ReadU8(0xFFAA6E)}"; + valueTicker = $"{Mem.ReadS32(0xFFAA32) / 65536.0:0.######}:{Mem.ReadU8(0xFFAA6D)}:{Mem.ReadU8(0xFFAA6E)}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFAA36) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFAA3A) / 65536.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFAA36) / 65536.0:0.######}:{Mem.ReadS32(0xFFAA3A) / 65536.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFA9D6) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFA9DA) / 65536.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFA9D6) / 65536.0:0.######}:{Mem.ReadS32(0xFFA9DA) / 65536.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFAA3E) / 65536.0:0.######}:{_api.MemLib.ReadS32(0xFFAA42) / 65536.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFAA3E) / 65536.0:0.######}:{Mem.ReadS32(0xFFAA42) / 65536.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{(_api.MemLib.ReadS32(0xFFAA36) + _api.MemLib.ReadS32(0xFFA9D6) + _api.MemLib.ReadS32(0xFFAA3E)) / 65536.0:0.######}:" + - $"{(_api.MemLib.ReadS32(0xFFAA3A) + _api.MemLib.ReadS32(0xFFA9DA) + _api.MemLib.ReadS32(0xFFAA42)) / 65536.0:0.######}"; + valueTicker = $"{(Mem.ReadS32(0xFFAA36) + Mem.ReadS32(0xFFA9D6) + Mem.ReadS32(0xFFAA3E)) / 65536.0:0.######}:" + + $"{(Mem.ReadS32(0xFFAA3A) + Mem.ReadS32(0xFFA9DA) + Mem.ReadS32(0xFFAA42)) / 65536.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadU8(0xFFAB72)}:{_api.MemLib.ReadU8(0xFFAB70)}:{(short)_api.MemLib.ReadS16(0xFFAA52):X4}:{(short)_api.MemLib.ReadS16(0xFFAA5A):X4}"; + valueTicker = $"{Mem.ReadU8(0xFFAB72)}:{Mem.ReadU8(0xFFAB70)}:{(short)Mem.ReadS16(0xFFAA52):X4}:{(short)Mem.ReadS16(0xFFAA5A):X4}"; TickerText(valueTicker); - switch (_api.MemLib.ReadU8(0xFFA7D0)) + switch (Mem.ReadU8(0xFFA7D0)) { case 1: case 2: case 3: case 30: case 46: - var globeFlags = _api.MemLib.ReadU32(0xFFD434) >> 1; - var globeFlags2 = _api.MemLib.ReadU32(0xFFD438) >> 1; + var globeFlags = Mem.ReadU32(0xFFD434) >> 1; + var globeFlags2 = Mem.ReadU32(0xFFD438) >> 1; int i, j = i = 0; while (globeFlags > 0) { @@ -3089,33 +3105,33 @@ namespace BizHawk.Client.EmuHawk } if (_dumpMap != 0) { - _api.MemLib.WriteS16(0xFFAA16, 7); - _api.MemLib.WriteS16(0xFFAA18, 56); - int PlayerX = _api.MemLib.ReadS16(0xFFAA1A) - _camX; - int PlayerY = _api.MemLib.ReadS16(0xFFAA1E) - _camY; + Mem.WriteS16(0xFFAA16, 7); + Mem.WriteS16(0xFFAA18, 56); + int PlayerX = Mem.ReadS16(0xFFAA1A) - _camX; + int PlayerY = Mem.ReadS16(0xFFAA1E) - _camY; if ((PlayerX < -64) || (PlayerX > 384) || (PlayerY < -64) || (PlayerY > 288)) { - _api.MemLib.WriteByte(0xFFAA70, 0xC); - _api.MemLib.WriteS16(0xFFA7CA, 1); + Mem.WriteByte(0xFFAA70, 0xC); + Mem.WriteS16(0xFFA7CA, 1); } else { - _api.MemLib.WriteByte(0xFFAA70, 0x0); - _api.MemLib.WriteS16(0xFFA7CA, 0); + Mem.WriteByte(0xFFAA70, 0x0); + Mem.WriteS16(0xFFA7CA, 0); } } if (_dumpMap == 1) { - int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); - int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); - var levelID = _api.MemLib.ReadByte(0xFFA7D0); - var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + int levelWidth = Mem.ReadS16(0xFFA7A8); + int levelHeight = Mem.ReadS16(0xFFA7AC); + var levelID = Mem.ReadByte(0xFFA7D0); + var s = Emu.GetSettings() as GPGX.GPGXSettings; s.DrawBGA = false; s.DrawBGB = false; s.DrawBGW = false; s.DrawObj = false; s.Backdrop = true; - _api.EmuLib.PutSettings(s); + Emu.PutSettings(s); if ((_camX == _destX) && (_camY == _destY)) { if ((_prevX != _camX) || (_prevY != _camY)) @@ -3124,9 +3140,9 @@ namespace BizHawk.Client.EmuHawk { if (_rowStateGuid != string.Empty) { - _api.MemStateLib.DeleteState(_rowStateGuid); + MemSS.DeleteState(_rowStateGuid); } - _rowStateGuid = _api.MemStateLib.SaveCoreStateToMemory(); + _rowStateGuid = MemSS.SaveCoreStateToMemory(); } _snapPast = 1; } @@ -3136,14 +3152,14 @@ namespace BizHawk.Client.EmuHawk } if (_snapPast == 0) { - EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_top.png"); + ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_top.png"); if (_destX >= levelWidth - 320) { if (_destY < levelHeight - 224) { if (_rowStateGuid != string.Empty) { - _api.MemStateLib.LoadCoreStateFromMemory(_rowStateGuid); + MemSS.LoadCoreStateFromMemory(_rowStateGuid); } _destX = 0; _destY = Math.Min(_destY + 111, levelHeight - 224); @@ -3153,70 +3169,70 @@ namespace BizHawk.Client.EmuHawk _destX = Math.Min(_destX + 159, levelWidth - 320); if ((_prevX == _destX) && (_prevY == _destY)) { - EmuHawkPluginLibrary.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); + ClientApi.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); _dumpMap++; } } } - _api.MemLib.WriteS16(0xFFAD8C, _destX); - _api.MemLib.WriteS16(0xFFAD90, _destY); + Mem.WriteS16(0xFFAD8C, _destX); + Mem.WriteS16(0xFFAD90, _destY); } else if (_dumpMap == 2) { if (_rowStateGuid != String.Empty) - _api.MemStateLib.DeleteState(_rowStateGuid); + MemSS.DeleteState(_rowStateGuid); _rowStateGuid = String.Empty; - int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); - int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); - EmuHawkPluginLibrary.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); - var levelID = _api.MemLib.ReadS8(0xFFA7D0); - var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + int levelWidth = Mem.ReadS16(0xFFA7A8); + int levelHeight = Mem.ReadS16(0xFFA7AC); + ClientApi.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); + var levelID = Mem.ReadS8(0xFFA7D0); + var s = Emu.GetSettings() as GPGX.GPGXSettings; s.DrawBGA = false; s.DrawBGB = false; s.DrawBGW = false; s.DrawObj = false; s.Backdrop = true; - _api.EmuLib.PutSettings(s); + Emu.PutSettings(s); - var a = _api.GUILib.GetAttributes(); + var a = Gui.GetAttributes(); a.SetColorKey(Color.FromArgb(0, 0x11, 0x22, 0x33), Color.FromArgb(0, 0x11, 0x22, 0x33)); - _api.GUILib.SetAttributes(a); - _api.GUILib.ToggleCompositingMode(); + Gui.SetAttributes(a); + Gui.ToggleCompositingMode(); - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_top.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_top.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) { var dx = (x == 0) ? 0 : 2; - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_top.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_top.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); } for (int y = ((levelHeight - 224) / 111) * 111; y >= 0; y -= 111) { var dy = (y == 0) ? 0 : 2; - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_top.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_top.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) { var dx = (x == 0) ? 0 : 2; - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_top.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_top.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); } } - _api.GUILib.ToggleCompositingMode(); - _api.GUILib.SetAttributes(new System.Drawing.Imaging.ImageAttributes()); - _api.GUILib.DrawFinish(); + Gui.ToggleCompositingMode(); + Gui.SetAttributes(new System.Drawing.Imaging.ImageAttributes()); + Gui.DrawFinish(); _dumpMap++; } else if (_dumpMap == 4) { - int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); - int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); - var levelID = _api.MemLib.ReadByte(0xFFA7D0); - var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + int levelWidth = Mem.ReadS16(0xFFA7A8); + int levelHeight = Mem.ReadS16(0xFFA7AC); + var levelID = Mem.ReadByte(0xFFA7D0); + var s = Emu.GetSettings() as GPGX.GPGXSettings; s.DrawBGA = (levelID != 29); s.DrawBGB = (levelID == 7); s.DrawBGW = true; s.DrawObj = true; s.Backdrop = false; - _api.EmuLib.PutSettings(s); + Emu.PutSettings(s); if ((_camX == _destX) && (_camY == _destY)) { if ((_prevX != _camX) || (_prevY != _camY)) @@ -3225,9 +3241,9 @@ namespace BizHawk.Client.EmuHawk { if (_rowStateGuid != string.Empty) { - _api.MemStateLib.DeleteState(_rowStateGuid); + MemSS.DeleteState(_rowStateGuid); } - _rowStateGuid = _api.MemStateLib.SaveCoreStateToMemory(); + _rowStateGuid = MemSS.SaveCoreStateToMemory(); } _snapPast = 1; } @@ -3237,14 +3253,14 @@ namespace BizHawk.Client.EmuHawk } if (_snapPast == 0) { - EmuHawkPluginLibrary.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_bottom.png"); + ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_bottom.png"); if (_destX >= levelWidth - 320) { if (_destY < levelHeight - 224) { if (_rowStateGuid != string.Empty) { - _api.MemStateLib.LoadCoreStateFromMemory(_rowStateGuid); + MemSS.LoadCoreStateFromMemory(_rowStateGuid); } _destX = 0; _destY = Math.Min(_destY + 111, levelHeight - 224); @@ -3254,80 +3270,80 @@ namespace BizHawk.Client.EmuHawk _destX = Math.Min(_destX + 159, levelWidth - 320); if ((_prevX == _destX) && (_prevY == _destY)) { - EmuHawkPluginLibrary.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); + ClientApi.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); _dumpMap++; } } } - _api.MemLib.WriteS16(0xFFAD8C, _destX); - _api.MemLib.WriteS16(0xFFAD90, _destY); + Mem.WriteS16(0xFFAD8C, _destX); + Mem.WriteS16(0xFFAD90, _destY); } else if (_dumpMap == 5) { if (_rowStateGuid != String.Empty) - _api.MemStateLib.DeleteState(_rowStateGuid); + MemSS.DeleteState(_rowStateGuid); _rowStateGuid = String.Empty; - int levelWidth = _api.MemLib.ReadS16(0xFFA7A8); - int levelHeight = _api.MemLib.ReadS16(0xFFA7AC); - var levelID = _api.MemLib.ReadS8(0xFFA7D0); - var s = _api.EmuLib.GetSettings() as GPGX.GPGXSettings; + int levelWidth = Mem.ReadS16(0xFFA7A8); + int levelHeight = Mem.ReadS16(0xFFA7AC); + var levelID = Mem.ReadS8(0xFFA7D0); + var s = Emu.GetSettings() as GPGX.GPGXSettings; s.DrawBGA = (levelID != 29); s.DrawBGB = (levelID == 7); s.DrawBGW = true; s.DrawObj = true; s.Backdrop = false; - _api.EmuLib.PutSettings(s); - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_bottom.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); + Emu.PutSettings(s); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_bottom.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) { var dx = (x == 0) ? 0 : 2; - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_bottom.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_bottom.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); } for (int y = ((levelHeight - 224) / 111) * 111; y >= 0; y -= 111) { var dy = (y == 0) ? 0 : 2; - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_bottom.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_bottom.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) { var dx = (x == 0) ? 0 : 2; - _api.GUILib.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_bottom.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); + Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_bottom.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); } } - _api.GUILib.DrawFinish(); + Gui.DrawFinish(); _dumpMap++; } _prevX = _camX; _prevY = _camY; break; case 0xF6: - valueTicker = $"{_api.MemLib.ReadS32(0xFFD5E0) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFD5E8) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFD5E4) / 2048.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFD5E0) / 4096.0:0.######}:{Mem.ReadS32(0xFFD5E8) / 4096.0:0.######}:{Mem.ReadS32(0xFFD5E4) / 2048.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFB13A) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB142) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB13E) / 2048.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFB13A) / 4096.0:0.######}:{Mem.ReadS32(0xFFB142) / 4096.0:0.######}:{Mem.ReadS32(0xFFB13E) / 2048.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadS32(0xFFB162) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB16A) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFB166) / 2048.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFB162) / 4096.0:0.######}:{Mem.ReadS32(0xFFB16A) / 4096.0:0.######}:{Mem.ReadS32(0xFFB166) / 2048.0:0.######}"; TickerText(valueTicker); - valueTicker = $"{_api.MemLib.ReadU8(0xFFB19B)}:{_api.MemLib.ReadU8(0xFFB1A6)}:{_api.MemLib.ReadU8(0xFFB1A9)}"; + valueTicker = $"{Mem.ReadU8(0xFFB19B)}:{Mem.ReadU8(0xFFB1A6)}:{Mem.ReadU8(0xFFB1A9)}"; TickerText(valueTicker); - int SpawnZ = _api.MemLib.ReadS32(0xFFD5F0) + 0x180000; + int SpawnZ = Mem.ReadS32(0xFFD5F0) + 0x180000; int nextRingZ = SpawnZ; while (((nextRingZ >> 17) & 0xF) != 0) { nextRingZ += 0x20000; } - valueTicker = $"{_api.MemLib.ReadS32(0xFFD856) / 4096.0:0.######}:{_api.MemLib.ReadS32(0xFFD85A) / 4096.0:0.######}:{(nextRingZ - 0x160000) / 2048.0:0.######}:{nextRingZ / 2048.0:0.######}"; + valueTicker = $"{Mem.ReadS32(0xFFD856) / 4096.0:0.######}:{Mem.ReadS32(0xFFD85A) / 4096.0:0.######}:{(nextRingZ - 0x160000) / 2048.0:0.######}:{nextRingZ / 2048.0:0.######}"; TickerText(valueTicker); - var levelId = -1 - _api.MemLib.ReadS16(0xFFA79E); + var levelId = -1 - Mem.ReadS16(0xFFA79E); bool spawn = false; bool firstRand = true; int SpawnX, SpawnY, z; - int CamX = (_api.MemLib.ReadS32(0xFFD5E0) >> 0xC) - _left; - int CamY = (_api.MemLib.ReadS32(0xFFD5E8) >> 0xC) + _top; - int CamZ = (_api.MemLib.ReadS32(0xFFD5E4) >> 0xC) + _top; + int CamX = (Mem.ReadS32(0xFFD5E0) >> 0xC) - _left; + int CamY = (Mem.ReadS32(0xFFD5E8) >> 0xC) + _top; + int CamZ = (Mem.ReadS32(0xFFD5E4) >> 0xC) + _top; while (!spawn) { var temp = (SpawnZ >> 17) & 0xFF; - var controlList = _api.MemLib.ReadS32(0x7B54 + (levelId << 2)); - temp = _api.MemLib.ReadS16(controlList + (temp << 1)); + var controlList = Mem.ReadS32(0x7B54 + (levelId << 2)); + temp = Mem.ReadS16(controlList + (temp << 1)); var v = temp & 0xFF; var num = (temp >> 8) + v; temp = v; @@ -3343,7 +3359,7 @@ namespace BizHawk.Client.EmuHawk break; case 2: // Jellyfish - SpawnX = _api.MemLib.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); + SpawnX = Mem.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); firstRand = false; SpawnY = -0xC0000 + (EccoRand() << 3); z = SpawnZ + 0x20000;// ? @@ -3357,7 +3373,7 @@ namespace BizHawk.Client.EmuHawk break; case 3: // Eagle - SpawnX = _api.MemLib.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); + SpawnX = Mem.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); firstRand = false; SpawnY = 0x50000; z = SpawnZ - 0x40000 + 0x20000;// ? @@ -3374,8 +3390,8 @@ namespace BizHawk.Client.EmuHawk bool left = (EccoRand(firstRand) > 0x8000); firstRand = false; var xdiff = 0xC0000 + (EccoRand() << 3); - SpawnX = _api.MemLib.ReadS32(0xFFB13A) + (left ? -xdiff : xdiff); - SpawnY = Math.Min(_api.MemLib.ReadS32(0xFFB142), -0x10000) - (EccoRand() + 0x10000); + SpawnX = Mem.ReadS32(0xFFB13A) + (left ? -xdiff : xdiff); + SpawnY = Math.Min(Mem.ReadS32(0xFFB142), -0x10000) - (EccoRand() + 0x10000); z = SpawnZ + 0x20000; valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; TickerText(valueTicker); @@ -3406,7 +3422,7 @@ namespace BizHawk.Client.EmuHawk break; case 14: // Shell - SpawnX = _api.MemLib.ReadS32(0xFFB13A) - 0x20000 + (EccoRand(firstRand) << 2); + SpawnX = Mem.ReadS32(0xFFB13A) - 0x20000 + (EccoRand(firstRand) << 2); firstRand = false; SpawnY = -0x80000; z = SpawnZ + 0x20000; @@ -3425,16 +3441,16 @@ namespace BizHawk.Client.EmuHawk } break; } - _api.JoypadLib.Set("C", null, 1); - _api.JoypadLib.Set("Start", null, 1); - var color = _turnSignalColors[_api.MemLib.ReadS8(0xFFA7C9) & 7]; - _api.GUILib.DrawRectangle(_left - 48, _top - 112, 15, 15, color, color); + Joy.Set("C", null, 1); + Joy.Set("Start", null, 1); + var color = _turnSignalColors[Mem.ReadS8(0xFFA7C9) & 7]; + Gui.DrawRectangle(_left - 48, _top - 112, 15, 15, color, color); } public override void LoadStateCallback(string name) { - _api.GUILib.DrawNew("emu"); + Gui.DrawNew("emu"); PreFrameCallback(); - _api.GUILib.DrawFinish(); + Gui.DrawFinish(); } } } diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs b/BizHawk.Client.EmuHawk/Api/Libraries/CommApi.cs similarity index 95% rename from BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs rename to BizHawk.Client.EmuHawk/Api/Libraries/CommApi.cs index 43012c1817..152658c639 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Communications.cs +++ b/BizHawk.Client.EmuHawk/Api/Libraries/CommApi.cs @@ -2,7 +2,7 @@ using System.ComponentModel; using BizHawk.Emulation.Common; -using BizHawk.Client.Common; +using BizHawk.Client.ApiHawk; using System.Text; using System.Collections.Generic; using System.Net.Http; @@ -11,7 +11,7 @@ using System.Windows.Forms; namespace BizHawk.Client.EmuHawk { - public sealed class CommunicationPluginLibrary : PluginLibraryBase + public sealed class CommApi : IComm { [RequiredService] private IEmulator Emulator { get; set; } @@ -19,7 +19,7 @@ namespace BizHawk.Client.EmuHawk [RequiredService] private IVideoProvider VideoProvider { get; set; } - public CommunicationPluginLibrary() : base() + public CommApi() : base() { } public string SocketServerScreenShot() diff --git a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs b/BizHawk.Client.EmuHawk/Api/Libraries/GUIApi.cs similarity index 65% rename from BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs rename to BizHawk.Client.EmuHawk/Api/Libraries/GUIApi.cs index 2647c19a89..5270a6eece 100644 --- a/BizHawk.Client.Common/plugins/PluginLibrary.GUIDraw.cs +++ b/BizHawk.Client.EmuHawk/Api/Libraries/GUIApi.cs @@ -5,44 +5,47 @@ using System.Drawing.Imaging; using System.Windows.Forms; using System.IO; +using BizHawk.Client.ApiHawk; using BizHawk.Emulation.Common; -namespace BizHawk.Client.Common +namespace BizHawk.Client.EmuHawk { - public abstract class GUIDrawPluginBase : PluginLibraryBase + public sealed class GuiApi : IGui { [RequiredService] - protected IEmulator Emulator { get; set; } - - public GUIDrawPluginBase() : base() - { } - - public bool HasGUISurface = false; - - protected Color _defaultForeground = Color.White; - protected Color? _defaultBackground; - protected Color? _defaultTextBackground = Color.FromArgb(128, 0, 0, 0); - protected int _defaultPixelFont = 1; // gens - protected Padding _padding = new Padding(0); - protected ImageAttributes _attributes = new ImageAttributes(); + private IEmulator Emulator { get; set; } + private Color _defaultForeground = Color.White; + private Color? _defaultBackground; + private Color? _defaultTextBackground = Color.FromArgb(128, 0, 0, 0); + private int _defaultPixelFont = 1; // gens + private Padding _padding = new Padding(0); + private ImageAttributes _attributes = new ImageAttributes(); private System.Drawing.Drawing2D.CompositingMode _compositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver; - public virtual void ToggleCompositingMode() + + public GuiApi() + { } + + private DisplaySurface _GUISurface = null; + + public bool HasGUISurface => _GUISurface != null; + + #region Gui API + public void ToggleCompositingMode() { _compositingMode = 1 - _compositingMode; } - public virtual ImageAttributes GetAttributes() + public ImageAttributes GetAttributes() { return _attributes; } - public virtual void SetAttributes(ImageAttributes a) + public void SetAttributes(ImageAttributes a) { _attributes = a; } - #region Gui API - public virtual void Dispose() + public void Dispose() { foreach (var brush in _solidBrushes.Values) { @@ -55,16 +58,35 @@ namespace BizHawk.Client.Common } } - public abstract void DrawNew(string name, bool? clear = true); - public abstract void DrawFinish(); + public void DrawNew(string name, bool? clear = true) + { + try + { + DrawFinish(); + _GUISurface = GlobalWin.DisplayManager.LockLuaSurface(name, clear ?? true); + } + catch (InvalidOperationException ex) + { + Console.WriteLine(ex.ToString()); + } + } + + public void DrawFinish() + { + if (_GUISurface != null) + { + GlobalWin.DisplayManager.UnlockLuaSurface(_GUISurface); + } + + _GUISurface = null; + } #endregion #region Helpers - protected readonly Dictionary _imageCache = new Dictionary(); - - protected readonly Dictionary _solidBrushes = new Dictionary(); - protected readonly Dictionary _pens = new Dictionary(); - protected SolidBrush GetBrush(Color color) + private readonly Dictionary _imageCache = new Dictionary(); + private readonly Dictionary _solidBrushes = new Dictionary(); + private readonly Dictionary _pens = new Dictionary(); + private SolidBrush GetBrush(Color color) { SolidBrush b; if (!_solidBrushes.TryGetValue(color, out b)) @@ -76,7 +98,7 @@ namespace BizHawk.Client.Common return b; } - protected Pen GetPen(Color color) + private Pen GetPen(Color color) { Pen p; if (!_pens.TryGetValue(color, out p)) @@ -88,7 +110,22 @@ namespace BizHawk.Client.Common return p; } - protected abstract Graphics GetGraphics(); + private Graphics GetGraphics() + { + var g = _GUISurface == null ? Graphics.FromImage(new Bitmap(1,1)) : _GUISurface.GetGraphics(); + + // we don't like CoreComm, right? Someone should find a different way to do this then. + var tx = Emulator.CoreComm.ScreenLogicalOffsetX; + var ty = Emulator.CoreComm.ScreenLogicalOffsetY; + if (tx != 0 || ty != 0) + { + var transform = g.Transform; + transform.Translate(-tx, -ty); + g.Transform = transform; + } + + return g; + } public void SetPadding(int all) { _padding = new Padding(all); @@ -97,7 +134,7 @@ namespace BizHawk.Client.Common { _padding = new Padding(x / 2, y / 2, x / 2 + x & 1, y / 2 + y & 1); } - public void SetPadding(int l,int t,int r, int b) + public void SetPadding(int l, int t, int r, int b) { _padding = new Padding(l, t, r, b); } @@ -107,11 +144,21 @@ namespace BizHawk.Client.Common } #endregion - public abstract void AddMessage(string message); + public void AddMessage(string message) + { + GlobalWin.OSD.AddMessage(message); + } - public abstract void ClearGraphics(); + public void ClearGraphics() + { + _GUISurface.Clear(); + DrawFinish(); + } - public abstract void ClearText(); + public void ClearText() + { + GlobalWin.OSD.ClearGUIText(); + } public void SetDefaultForegroundColor(Color color) { @@ -352,7 +399,7 @@ namespace BizHawk.Client.Common { using (var g = GetGraphics()) { - g.CompositingMode = _compositingMode; + g.CompositingMode = _compositingMode; g.DrawLine(GetPen(color ?? _defaultForeground), x1, y1, x2, y2); } } @@ -424,12 +471,13 @@ namespace BizHawk.Client.Common var bg = background ?? _defaultBackground; if (bg.HasValue) { - g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, Math.Max(w - 1, 0), Math.Max(h - 1, 0)); } + g.FillRectangle(GetBrush(bg.Value), x + 1, y + 1, Math.Max(w - 1, 0), Math.Max(h - 1, 0)); + } } } - public void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null, - string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null) + public void DrawString(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, int? fontsize = null, + string fontfamily = null, string fontstyle = null, string horizalign = null, string vertalign = null) { using (var g = GetGraphics()) { @@ -508,7 +556,7 @@ namespace BizHawk.Client.Common { for (var yd = -1; yd <= 1; yd++) { - g.DrawString(message, font, GetBrush(bg.Value), x+xd, y+yd); + g.DrawString(message, font, GetBrush(bg.Value), x + xd, y + yd); } } } @@ -522,7 +570,86 @@ namespace BizHawk.Client.Common } } - public abstract void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null); - public abstract void Text(int x, int y, string message, Color? forecolor = null, string anchor = null); + public void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null) + { + using (var g = GetGraphics()) + { + try + { + var index = 0; + if (string.IsNullOrEmpty(fontfamily)) + { + index = _defaultPixelFont; + } + else + { + switch (fontfamily) + { + case "fceux": + case "0": + index = 0; + break; + case "gens": + case "1": + index = 1; + break; + default: + Console.WriteLine($"Unable to find font family: {fontfamily}"); + return; + } + } + + var f = new StringFormat(StringFormat.GenericTypographic) + { + FormatFlags = StringFormatFlags.MeasureTrailingSpaces + }; + var font = new Font(GlobalWin.DisplayManager.CustomFonts.Families[index], 8, FontStyle.Regular, GraphicsUnit.Pixel); + Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize(); + var rect = new Rectangle(new Point(x, y), sizeOfText + new Size(1, 0)); + if (backcolor.HasValue) g.FillRectangle(GetBrush(backcolor.Value), rect); + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; + g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y); + } + catch (Exception) + { + return; + } + } + } + + public void Text(int x, int y, string message, Color? forecolor = null, string anchor = null) + { + var a = 0; + + if (!string.IsNullOrEmpty(anchor)) + { + switch (anchor) + { + case "0": + case "topleft": + a = 0; + break; + case "1": + case "topright": + a = 1; + break; + case "2": + case "bottomleft": + a = 2; + break; + case "3": + case "bottomright": + a = 3; + break; + } + } + else + { + x -= Emulator.CoreComm.ScreenLogicalOffsetX; + y -= Emulator.CoreComm.ScreenLogicalOffsetY; + } + + GlobalWin.OSD.AddGUIText(message, x, y, Color.Black, forecolor ?? Color.White, a); + } } } \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs b/BizHawk.Client.EmuHawk/Api/Libraries/InputApi.cs similarity index 92% rename from BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs rename to BizHawk.Client.EmuHawk/Api/Libraries/InputApi.cs index e2e289bae0..56e2cd767f 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Input.cs +++ b/BizHawk.Client.EmuHawk/Api/Libraries/InputApi.cs @@ -3,13 +3,14 @@ using System.Linq; using System.Collections.Generic; using System.Windows.Forms; +using BizHawk.Client.ApiHawk; using BizHawk.Client.Common; namespace BizHawk.Client.EmuHawk { - public sealed class InputPluginLibrary : PluginLibraryBase + public sealed class InputApi : IInput { - public InputPluginLibrary() : base() + public InputApi() : base() { } public Dictionary Get() diff --git a/BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs b/BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs new file mode 100644 index 0000000000..ca44e44a3d --- /dev/null +++ b/BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using BizHawk.Common.ReflectionExtensions; +using BizHawk.Emulation.Common; +using BizHawk.Client.ApiHawk; + +namespace BizHawk.Client.EmuHawk + +{ + public static class ApiManager + { + private static ApiContainer container; + private static void Register(IEmulatorServiceProvider serviceProvider) + { + // Register external apis + var libs = Assembly + .Load("BizHawk.Client.ApiHawk") + .GetTypes() + .Where(t => typeof(IExternalApi).IsAssignableFrom(t)) + .Where(t => t.IsSealed) + .Where(t => ServiceInjector.IsAvailable(serviceProvider, t)) + .ToList(); + + libs.AddRange( + Assembly + .GetAssembly(typeof(ApiContainer)) + .GetTypes() + .Where(t => typeof(IExternalApi).IsAssignableFrom(t)) + .Where(t => t.IsSealed) + .Where(t => ServiceInjector.IsAvailable(serviceProvider, t))); + + foreach (var lib in libs) + { + var instance = (IExternalApi)Activator.CreateInstance(lib); + ServiceInjector.UpdateServices(serviceProvider, instance); + Libraries.Add(lib, instance); + } + container = new ApiContainer(Libraries); + GlobalWin.ApiProvider = new BasicApiProvider(container); + } + private static readonly Dictionary Libraries = new Dictionary(); + public static void Restart(IEmulatorServiceProvider newServiceProvider) + { + Libraries.Clear(); + Register(newServiceProvider); + } + } +} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs b/BizHawk.Client.EmuHawk/Api/Libraries/SaveStateAPI.cs similarity index 84% rename from BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs rename to BizHawk.Client.EmuHawk/Api/Libraries/SaveStateAPI.cs index 90f4e5e7f6..df75742920 100644 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Savestate.cs +++ b/BizHawk.Client.EmuHawk/Api/Libraries/SaveStateAPI.cs @@ -2,13 +2,13 @@ using System.Collections.Generic; using System.IO; -using BizHawk.Client.Common; +using BizHawk.Client.ApiHawk; namespace BizHawk.Client.EmuHawk { - public sealed class SavestatePluginibrary : PluginLibraryBase + public sealed class SaveStateApi : ISaveState { - public SavestatePluginibrary() : base() + public SaveStateApi() : base() { } public void Load(string path) diff --git a/BizHawk.Client.EmuHawk/Api/Libraries/ToolApi.cs b/BizHawk.Client.EmuHawk/Api/Libraries/ToolApi.cs new file mode 100644 index 0000000000..d356761cdf --- /dev/null +++ b/BizHawk.Client.EmuHawk/Api/Libraries/ToolApi.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using BizHawk.Common; +using BizHawk.Emulation.Common; +using BizHawk.Client.ApiHawk; +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public sealed class ToolApi : ITool + { + private class ToolStatic + { + public Type GetTool(string name) + { + var toolType = ReflectionUtil.GetTypeByName(name) + .FirstOrDefault(x => typeof(IToolForm).IsAssignableFrom(x) && !x.IsInterface); + + if (toolType != null) + { + GlobalWin.Tools.Load(toolType); + } + + var selectedTool = GlobalWin.Tools.AvailableTools + .FirstOrDefault(tool => tool.GetType().Name.ToLower() == name.ToLower()); + + if (selectedTool != null) + { + return selectedTool; + } + + return null; + } + + public object CreateInstance(string name) + { + var possibleTypes = ReflectionUtil.GetTypeByName(name); + + if (possibleTypes.Any()) + { + return Activator.CreateInstance(possibleTypes.First()); + } + + return null; + } + + public static void OpenCheats() + { + GlobalWin.Tools.Load(); + } + + public static void OpenHexEditor() + { + GlobalWin.Tools.Load(); + } + + public static void OpenRamWatch() + { + GlobalWin.Tools.LoadRamWatch(loadDialog: true); + } + + public static void OpenRamSearch() + { + GlobalWin.Tools.Load(); + } + + public static void OpenTasStudio() + { + GlobalWin.Tools.Load(); + } + + public static void OpenToolBox() + { + GlobalWin.Tools.Load(); + } + + public static void OpenTraceLogger() + { + GlobalWin.Tools.Load(); + } + + } + [RequiredService] + private static IEmulator Emulator { get; set; } + + [RequiredService] + private static IVideoProvider VideoProvider { get; set; } + + public ToolApi() + { } + + public Type GetTool(string name) + { + var toolType = ReflectionUtil.GetTypeByName(name) + .FirstOrDefault(x => typeof(IToolForm).IsAssignableFrom(x) && !x.IsInterface); + + if (toolType != null) + { + GlobalWin.Tools.Load(toolType); + } + + var selectedTool = GlobalWin.Tools.AvailableTools + .FirstOrDefault(tool => tool.GetType().Name.ToLower() == name.ToLower()); + + if (selectedTool != null) + { + return selectedTool; + } + + return null; + } + + public object CreateInstance(string name) + { + var possibleTypes = ReflectionUtil.GetTypeByName(name); + + if (possibleTypes.Any()) + { + return Activator.CreateInstance(possibleTypes.First()); + } + + return null; + } + + public void OpenCheats() + { + ToolStatic.OpenCheats(); + } + + public void OpenHexEditor() + { + ToolStatic.OpenHexEditor(); + } + + public void OpenRamWatch() + { + ToolStatic.OpenRamWatch(); + } + + public void OpenRamSearch() + { + ToolStatic.OpenRamSearch(); + } + + public void OpenTasStudio() + { + ToolStatic.OpenTasStudio(); + } + + public void OpenToolBox() + { + ToolStatic.OpenToolBox(); + } + + public void OpenTraceLogger() + { + ToolStatic.OpenTraceLogger(); + } + } +} diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 46f0aa381a..efbb0d391d 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -658,9 +658,14 @@ - - - + + + + + + + + @@ -734,7 +739,6 @@ NameStateForm.cs - Form @@ -747,10 +751,6 @@ PlatformChooser.cs - - - - @@ -1888,7 +1888,6 @@ - diff --git a/BizHawk.Client.EmuHawk/GlobalWin.cs b/BizHawk.Client.EmuHawk/GlobalWin.cs index 5ede6c61fc..06a2bbaab5 100644 --- a/BizHawk.Client.EmuHawk/GlobalWin.cs +++ b/BizHawk.Client.EmuHawk/GlobalWin.cs @@ -1,4 +1,5 @@ using BizHawk.Bizware.BizwareGL; +using BizHawk.Client.ApiHawk; // ReSharper disable StyleCop.SA1401 namespace BizHawk.Client.EmuHawk @@ -7,7 +8,7 @@ namespace BizHawk.Client.EmuHawk { public static MainForm MainForm; public static ToolManager Tools; - public static PluginLibrary Plugins; + public static BasicApiProvider ApiProvider; /// /// the IGL to be used for rendering diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 9fb06ed416..2cc7539c80 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -252,8 +252,6 @@ namespace BizHawk.Client.EmuHawk GlobalWin.Sound.StartSound(); InputManager.RewireInputChain(); GlobalWin.Tools = new ToolManager(this); - GlobalWin.Plugins = new PluginLibrary(Emulator.ServiceProvider); - GlobalWin.Plugins.Load(new Ecco2AssistantPlugin()); RewireSound(); // Workaround for windows, location is -32000 when minimized, if they close it during this time, that's what gets saved @@ -2937,7 +2935,6 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallFrameBeforeEvent(); } - GlobalWin.Plugins.CallFrameBeforeEvent(); if (IsTurboing) { @@ -3024,7 +3021,6 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallFrameAfterEvent(); } - GlobalWin.Plugins.CallFrameAfterEvent(); if (IsTurboing) { @@ -3798,7 +3794,7 @@ namespace BizHawk.Client.EmuHawk } GlobalWin.Tools.Restart(); - GlobalWin.Plugins.Restart(Emulator.ServiceProvider); + ApiManager.Restart(Emulator.ServiceProvider); if (Global.Config.LoadCheatFileByGame) { @@ -3846,7 +3842,7 @@ namespace BizHawk.Client.EmuHawk } } - ClientApi.OnRomLoaded(); + ClientApi.OnRomLoaded(Emulator); return true; } else @@ -3857,10 +3853,11 @@ namespace BizHawk.Client.EmuHawk // The ROM has been loaded by a recursive invocation of the LoadROM method. if (!(Emulator is NullEmulator)) { - ClientApi.OnRomLoaded(); + ClientApi.OnRomLoaded(Emulator); return true; } + ClientApi.UpdateEmulatorAndVP(Emulator); HandlePlatformMenus(); _stateSlots.Clear(); UpdateStatusSlots(); @@ -3950,6 +3947,7 @@ namespace BizHawk.Client.EmuHawk var coreComm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(coreComm); Emulator = new NullEmulator(coreComm, Global.Config.GetCoreSettings()); + ClientApi.UpdateEmulatorAndVP(Emulator); Global.ActiveController = new Controller(NullController.Instance.Definition); Global.AutoFireController = _autofireNullControls; RewireSound(); @@ -3972,7 +3970,7 @@ namespace BizHawk.Client.EmuHawk Global.Game = GameInfo.NullInstance; GlobalWin.Tools.Restart(); - GlobalWin.Plugins.Restart(Emulator.ServiceProvider); + ApiManager.Restart(Emulator.ServiceProvider); RewireSound(); Text = "BizHawk" + (VersionInfo.DeveloperBuild ? " (interim) " : ""); HandlePlatformMenus(); @@ -4068,7 +4066,6 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallLoadStateEvent(userFriendlyStateName); } - GlobalWin.Plugins.CallLoadStateEvent(userFriendlyStateName); SetMainformMovieInfo(); GlobalWin.Tools.UpdateToolsBefore(fromLua); @@ -4198,7 +4195,6 @@ namespace BizHawk.Client.EmuHawk { GlobalWin.Tools.LuaConsole.LuaImp.CallSaveStateEvent(quickSlotName); } - GlobalWin.Plugins.CallSaveStateEvent(quickSlotName); } private void SaveStateAs() diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs deleted file mode 100644 index b37d5f37dc..0000000000 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.Client.cs +++ /dev/null @@ -1,351 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -using BizHawk.Common; -using BizHawk.Emulation.Common; -using BizHawk.Client.Common; - -namespace BizHawk.Client.EmuHawk -{ - public sealed class EmuHawkPluginLibrary : PluginLibraryBase - { - [RequiredService] - private IEmulator Emulator { get; set; } - - [RequiredService] - private IVideoProvider VideoProvider { get; set; } - - private readonly Dictionary _filterMappings = new Dictionary - { - { 0, "None" }, - { 1, "x2SAI" }, - { 2, "SuperX2SAI" }, - { 3, "SuperEagle" }, - { 4, "Scanlines" }, - }; - - public EmuHawkPluginLibrary() : base() - { } - - public void CloseEmulator() - { - GlobalWin.MainForm.CloseEmulator(); - } - - public void CloseEmulatorWithCode(int exitCode) - { - GlobalWin.MainForm.CloseEmulator(exitCode); - } - - public static int BorderHeight() - { - var point = new System.Drawing.Point(0, 0); - return GlobalWin.DisplayManager.TransformPoint(point).Y; - } - - public static int BorderWidth() - { - var point = new System.Drawing.Point(0, 0); - return GlobalWin.DisplayManager.TransformPoint(point).X; - } - - public int BufferHeight() - { - return VideoProvider.BufferHeight; - } - - public int BufferWidth() - { - return VideoProvider.BufferWidth; - } - - public void ClearAutohold() - { - GlobalWin.MainForm.ClearHolds(); - } - - public static void CloseRom() - { - GlobalWin.MainForm.CloseRom(); - } - - public void EnableRewind(bool enabled) - { - GlobalWin.MainForm.EnableRewind(enabled); - } - - public void FrameSkip(int numFrames) - { - if (numFrames > 0) - { - Global.Config.FrameSkip = numFrames; - GlobalWin.MainForm.FrameSkipMessage(); - } - else - { - Console.WriteLine("Invalid frame skip value"); - } - } - - public static int GetTargetScanlineIntensity() - { - return Global.Config.TargetScanlineFilterIntensity; - } - - public int GetWindowSize() - { - return Global.Config.TargetZoomFactors[Emulator.SystemId]; - } - - public static void SetGameExtraPadding(int left, int top, int right, int bottom) - { - GlobalWin.DisplayManager.GameExtraPadding = new System.Windows.Forms.Padding(left, top, right, bottom); - GlobalWin.MainForm.FrameBufferResized(); - } - - public static void SetSoundOn(bool enable) - { - Global.Config.SoundEnabled = enable; - } - - public static bool GetSoundOn() - { - return Global.Config.SoundEnabled; - } - - public static void SetClientExtraPadding(int left, int top, int right, int bottom) - { - GlobalWin.DisplayManager.ClientExtraPadding = new System.Windows.Forms.Padding(left, top, right, bottom); - GlobalWin.MainForm.FrameBufferResized(); - } - - public static bool IsPaused() - { - return GlobalWin.MainForm.EmulatorPaused; - } - - public static bool IsTurbo() - { - return GlobalWin.MainForm.IsTurboing; - } - - public static bool IsSeeking() - { - return GlobalWin.MainForm.IsSeeking; - } - - public static void OpenCheats() - { - GlobalWin.Tools.Load(); - } - - public static void OpenHexEditor() - { - GlobalWin.Tools.Load(); - } - - public static void OpenRamWatch() - { - GlobalWin.Tools.LoadRamWatch(loadDialog: true); - } - - public static void OpenRamSearch() - { - GlobalWin.Tools.Load(); - } - - public static void OpenRom(string path) - { - var ioa = OpenAdvancedSerializer.ParseWithLegacy(path); - GlobalWin.MainForm.LoadRom(path, new MainForm.LoadRomArgs { OpenAdvanced = ioa }); - } - - public static void OpenTasStudio() - { - GlobalWin.Tools.Load(); - } - - public static void OpenToolBox() - { - GlobalWin.Tools.Load(); - } - - public static void OpenTraceLogger() - { - GlobalWin.Tools.Load(); - } - - public static void Pause() - { - GlobalWin.MainForm.PauseEmulator(); - } - - public static void PauseAv() - { - GlobalWin.MainForm.PauseAvi = true; - } - - public static void RebootCore() - { - ((LuaConsole)GlobalWin.Tools.Get()).LuaImp.IsRebootingCore = true; - GlobalWin.MainForm.RebootCore(); - ((LuaConsole)GlobalWin.Tools.Get()).LuaImp.IsRebootingCore = false; - } - - public static int ScreenHeight() - { - return GlobalWin.MainForm.PresentationPanel.NativeSize.Height; - } - - public static void Screenshot(string path = null) - { - if (path == null) - { - GlobalWin.MainForm.TakeScreenshot(); - } - else - { - GlobalWin.MainForm.TakeScreenshot(path); - } - } - - public static void ScreenshotToClipboard() - { - GlobalWin.MainForm.TakeScreenshotToClipboard(); - } - - public static void SetTargetScanlineIntensity(int val) - { - Global.Config.TargetScanlineFilterIntensity = val; - } - - public static void SetScreenshotOSD(bool value) - { - Global.Config.Screenshot_CaptureOSD = value; - } - - public static int ScreenWidth() - { - return GlobalWin.MainForm.PresentationPanel.NativeSize.Width; - } - - public void SetWindowSize(int size) - { - if (size == 1 || size == 2 || size == 3 || size == 4 || size == 5 || size == 10) - { - Global.Config.TargetZoomFactors[Emulator.SystemId] = size; - GlobalWin.MainForm.FrameBufferResized(); - GlobalWin.OSD.AddMessage("Window size set to " + size + "x"); - } - else - { - Console.WriteLine("Invalid window size"); - } - } - - public void SpeedMode(int percent) - { - if (percent > 0 && percent < 6400) - { - GlobalWin.MainForm.ClickSpeedItem(percent); - } - else - { - Console.WriteLine("Invalid speed value"); - } - } - - public static void TogglePause() - { - GlobalWin.MainForm.TogglePause(); - } - - public static int TransformPointX(int x) - { - var point = new System.Drawing.Point(x, 0); - return GlobalWin.DisplayManager.TransformPoint(point).X; - } - - public static int TransformPointY(int y) - { - var point = new System.Drawing.Point(0, y); - return GlobalWin.DisplayManager.TransformPoint(point).Y; - } - - public static void Unpause() - { - GlobalWin.MainForm.UnpauseEmulator(); - } - - public static void UnpauseAv() - { - GlobalWin.MainForm.PauseAvi = false; - } - - public static int Xpos() - { - return GlobalWin.MainForm.DesktopLocation.X; - } - - public static int Ypos() - { - return GlobalWin.MainForm.DesktopLocation.Y; - } - - public List GetAvailableTools() - { - var tools = GlobalWin.Tools.AvailableTools.ToList(); - var t = new List(tools.Count); - for (int i = 0; i < tools.Count; i++) - { - t[i] = tools[i].Name.ToLower(); - } - - return t; - } - - public Type GetTool(string name) - { - var toolType = ReflectionUtil.GetTypeByName(name) - .FirstOrDefault(x => typeof(IToolForm).IsAssignableFrom(x) && !x.IsInterface); - - if (toolType != null) - { - GlobalWin.Tools.Load(toolType); - } - - var selectedTool = GlobalWin.Tools.AvailableTools - .FirstOrDefault(tool => tool.GetType().Name.ToLower() == name.ToLower()); - - if (selectedTool != null) - { - return selectedTool; - } - - return null; - } - - public object CreateInstance(string name) - { - var possibleTypes = ReflectionUtil.GetTypeByName(name); - - if (possibleTypes.Any()) - { - return Activator.CreateInstance(possibleTypes.First()); - } - - return null; - } - - public void DisplayMessages(bool value) - { - Global.Config.DisplayMessages = value; - } - - public void SaveRam() - { - GlobalWin.MainForm.FlushSaveRAM(); - } - } -} diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs deleted file mode 100644 index e22bd3e0fd..0000000000 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.GUI.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.Drawing; - -using BizHawk.Client.Common; - -namespace BizHawk.Client.EmuHawk -{ - public sealed class GUIPluginLibrary : GUIDrawPluginBase - { - public GUIPluginLibrary() : base() - { } - - private DisplaySurface _GUISurface = null; - - #region Gui API - - public override void DrawNew(string name, bool? clear = true) - { - try - { - DrawFinish(); - _GUISurface = GlobalWin.DisplayManager.LockLuaSurface(name, clear ?? true); - HasGUISurface = (_GUISurface != null); - - } - catch (InvalidOperationException ex) - { - Console.WriteLine(ex.ToString()); - } - } - - public override void DrawFinish() - { - if (_GUISurface != null) - { - GlobalWin.DisplayManager.UnlockLuaSurface(_GUISurface); - } - - _GUISurface = null; - HasGUISurface = false; - - } - #endregion - - #region Helpers - protected override Graphics GetGraphics() - { - var g = _GUISurface == null ? Graphics.FromImage(new Bitmap(1,1)) : _GUISurface.GetGraphics(); - - // we don't like CoreComm, right? Someone should find a different way to do this then. - var tx = Emulator.CoreComm.ScreenLogicalOffsetX; - var ty = Emulator.CoreComm.ScreenLogicalOffsetY; - if (tx != 0 || ty != 0) - { - var transform = g.Transform; - transform.Translate(-tx, -ty); - g.Transform = transform; - } - - return g; - } - #endregion - - public override void AddMessage(string message) - { - GlobalWin.OSD.AddMessage(message); - } - - public override void ClearGraphics() - { - _GUISurface.Clear(); - DrawFinish(); - } - - public override void ClearText() - { - GlobalWin.OSD.ClearGUIText(); - } - - public override void DrawText(int x, int y, string message, Color? forecolor = null, Color? backcolor = null, string fontfamily = null) - { - using (var g = GetGraphics()) - { - try - { - var index = 0; - if (string.IsNullOrEmpty(fontfamily)) - { - index = _defaultPixelFont; - } - else - { - switch (fontfamily) - { - case "fceux": - case "0": - index = 0; - break; - case "gens": - case "1": - index = 1; - break; - default: - Console.WriteLine($"Unable to find font family: {fontfamily}"); - return; - } - } - - var f = new StringFormat(StringFormat.GenericTypographic) - { - FormatFlags = StringFormatFlags.MeasureTrailingSpaces - }; - var font = new Font(GlobalWin.DisplayManager.CustomFonts.Families[index], 8, FontStyle.Regular, GraphicsUnit.Pixel); - Size sizeOfText = g.MeasureString(message, font, 0, f).ToSize(); - var rect = new Rectangle(new Point(x, y), sizeOfText + new Size(1, 0)); - if (backcolor.HasValue) g.FillRectangle(GetBrush(backcolor.Value), rect); - g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; - g.DrawString(message, font, GetBrush(forecolor ?? _defaultForeground), x, y); - } - catch (Exception) - { - return; - } - } - } - - public override void Text(int x, int y, string message, Color? forecolor = null, string anchor = null) - { - var a = 0; - - if (!string.IsNullOrEmpty(anchor)) - { - switch (anchor) - { - case "0": - case "topleft": - a = 0; - break; - case "1": - case "topright": - a = 1; - break; - case "2": - case "bottomleft": - a = 2; - break; - case "3": - case "bottomright": - a = 3; - break; - } - } - else - { - x -= Emulator.CoreComm.ScreenLogicalOffsetX; - y -= Emulator.CoreComm.ScreenLogicalOffsetY; - } - - GlobalWin.OSD.AddGUIText(message, x, y, Color.Black, forecolor ?? Color.White, a); - } - } -} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs b/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs deleted file mode 100644 index 132ba4a2df..0000000000 --- a/BizHawk.Client.EmuHawk/Plugins/Libraries/PluginLibrary.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using BizHawk.Common.ReflectionExtensions; -using BizHawk.Emulation.Common; -using BizHawk.Client.Common; - -namespace BizHawk.Client.EmuHawk - -{ - public class PluginLibrary - { -// public LuaDocumentation Docs { get; } - private void Register(IEmulatorServiceProvider serviceProvider) - { - // Docs.Clear(); - - // Register lua libraries - var libs = Assembly - .Load("BizHawk.Client.Common") - .GetTypes() - .Where(t => typeof(PluginLibraryBase).IsAssignableFrom(t)) - .Where(t => t.IsSealed) - .Where(t => ServiceInjector.IsAvailable(serviceProvider, t)) - .ToList(); - - libs.AddRange( - Assembly - .GetAssembly(typeof(PluginLibrary)) - .GetTypes() - .Where(t => typeof(PluginLibraryBase).IsAssignableFrom(t)) - .Where(t => t.IsSealed) - .Where(t => ServiceInjector.IsAvailable(serviceProvider, t))); - - foreach (var lib in libs) - { - var instance = (PluginLibraryBase)Activator.CreateInstance(lib); - ServiceInjector.UpdateServices(serviceProvider, instance); - Libraries.Add(lib, instance); - } - } - public PluginLibrary(IEmulatorServiceProvider serviceProvider) - { - Register(serviceProvider); - } - private readonly Dictionary Libraries = new Dictionary(); - public List PluginList { get; } = new List(); - - public IEnumerable RunningPlugins - { - get { return PluginList.Where(plug => plug.Enabled); } - } - -// private FormsPluginLibrary FormsLibrary => (FormsLuaLibrary)Libraries[typeof(FormsLuaLibrary)]; -// private EmulatorPluginLibrary EmuPluginLibrary => (EmulatorPluginLibrary)Libraries[typeof(EmulatorPluginLibrary)]; - private GUIPluginLibrary GuiLibrary => (GUIPluginLibrary)Libraries[typeof(GUIPluginLibrary)]; - - public void Restart(IEmulatorServiceProvider newServiceProvider) - { - Libraries.Clear(); - Register(newServiceProvider); - foreach (var plugin in PluginList) - { - plugin.Init(new PluginAPI(Libraries)); - } - } - - public void StartPluginDrawing() - { - if (PluginList.Any() && !GuiLibrary.HasGUISurface) - { - GuiLibrary.DrawNew("emu"); - } - } - - public void EndPluginDrawing() - { - if (PluginList.Any()) - { - GuiLibrary.DrawFinish(); - } - } - - public void CallSaveStateEvent(string name) - { - foreach (var plugin in RunningPlugins) plugin.SaveStateCallback(name); - } - - public void CallLoadStateEvent(string name) - { - foreach (var plugin in RunningPlugins) plugin.LoadStateCallback(name); - } - - public void CallFrameBeforeEvent() - { - StartPluginDrawing(); - foreach (var plugin in RunningPlugins) plugin.PreFrameCallback(); - } - - public void CallFrameAfterEvent() - { - foreach (var plugin in RunningPlugins) plugin.PostFrameCallback(); - EndPluginDrawing(); - } - - public void CallExitEvent() - { - foreach (var plugin in RunningPlugins) plugin.ExitCallback(); - } - - public void Close() - { - GuiLibrary.Dispose(); - } - - public void Load(PluginBase plugin) - { - plugin.Init(new PluginAPI(Libraries)); - PluginList.Add(plugin); - } - } -} diff --git a/BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs b/BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs deleted file mode 100644 index c2e1ea3960..0000000000 --- a/BizHawk.Client.EmuHawk/Plugins/PluginAPI.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Linq; - -using BizHawk.Client.Common; - -namespace BizHawk.Client.EmuHawk -{ - public sealed class PluginAPI : IPluginAPI - { - public EmulatorPluginLibrary EmuLib => (EmulatorPluginLibrary)Libraries[typeof(EmulatorPluginLibrary)]; - public GameInfoPluginLibrary GameInfoLib => (GameInfoPluginLibrary)Libraries[typeof(GameInfoPluginLibrary)]; - public GUIDrawPluginBase GUILib => (GUIDrawPluginBase)Libraries[typeof(GUIPluginLibrary)]; - public JoypadPluginLibrary JoypadLib => (JoypadPluginLibrary)Libraries[typeof(JoypadPluginLibrary)]; - public MemoryPluginLibrary MemLib => (MemoryPluginLibrary)Libraries[typeof(MemoryPluginLibrary)]; - public MemoryEventsPluginLibrary MemEventsLib => (MemoryEventsPluginLibrary)Libraries[typeof(MemoryEventsPluginLibrary)]; - public MemorySavestatePluginLibrary MemStateLib => (MemorySavestatePluginLibrary)Libraries[typeof(MemorySavestatePluginLibrary)]; - public MoviePluginLibrary MovieLib => (MoviePluginLibrary)Libraries[typeof(MoviePluginLibrary)]; - public SQLPluginLibrary SQLLib => (SQLPluginLibrary)Libraries[typeof(SQLPluginLibrary)]; - public UserDataPluginLibrary UserDataLib => (UserDataPluginLibrary)Libraries[typeof(UserDataPluginLibrary)]; - public Dictionary Libraries { get; set; } - public PluginAPI(Dictionary libs) - { - Libraries = libs; - } - } -} diff --git a/BizHawk.Client.EmuHawk/tools/ToolBox.cs b/BizHawk.Client.EmuHawk/tools/ToolBox.cs index 503714c6b1..67aefdfd0f 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolBox.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolBox.cs @@ -6,7 +6,7 @@ using System.Reflection; using System.Windows.Forms; using BizHawk.Emulation.Common; -using BizHawk.Client.Common; +using BizHawk.Client.ApiHawk; namespace BizHawk.Client.EmuHawk { @@ -66,6 +66,8 @@ namespace BizHawk.Client.EmuHawk continue; if (!ServiceInjector.IsAvailable(Emulator.ServiceProvider, t)) continue; +// if (!ApiInjector.IsAvailable(, t)) +// continue; var instance = Activator.CreateInstance(t); diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs index 05d530176d..321b301c36 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.ComponentModel; using System.Windows.Forms; +using BizHawk.Client.ApiHawk; using BizHawk.Client.Common; using BizHawk.Emulation.Common; using BizHawk.Common.ReflectionExtensions; @@ -121,6 +122,11 @@ namespace BizHawk.Client.EmuHawk (newTool as Form).Owner = GlobalWin.MainForm; } + if (isExternal) + { + ApiInjector.UpdateApis(GlobalWin.ApiProvider, newTool); + } + ServiceInjector.UpdateServices(Global.Emulator.ServiceProvider, newTool); string toolType = typeof(T).ToString(); @@ -491,6 +497,8 @@ namespace BizHawk.Client.EmuHawk if ((tool.IsHandleCreated && !tool.IsDisposed) || tool is RamWatch) // Hack for RAM Watch - in display watches mode it wants to keep running even closed, it will handle disposed logic { + if (tool is IExternalToolForm) + ApiInjector.UpdateApis(GlobalWin.ApiProvider, tool); tool.Restart(); } } diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj index 8b9b8cac99..193d86f3fc 100644 --- a/BizHawk.Common/BizHawk.Common.csproj +++ b/BizHawk.Common/BizHawk.Common.csproj @@ -109,4 +109,4 @@ --> - + \ No newline at end of file From 79aaef02574530972b47dc989dac81abfc373953 Mon Sep 17 00:00:00 2001 From: upthorn Date: Sat, 22 Dec 2018 11:16:54 -0800 Subject: [PATCH 15/22] Removed project references to old, unrefactored files that no longer exist. --- .../BizHawk.Client.Common.csproj | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj index 84c1eed24d..cee56ac8a8 100644 --- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj +++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj @@ -132,21 +132,6 @@ - - - - - - - - - - - - - - - From 3b1fd8fec6d837f2d48215e71edb912bbf011b2e Mon Sep 17 00:00:00 2001 From: upthorn Date: Sat, 22 Dec 2018 11:58:14 -0800 Subject: [PATCH 16/22] Unrename SetExtraPadding methods. --- BizHawk.Client.ApiHawk/Classes/ClientApi.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs index 8756885f54..19d01f9f08 100644 --- a/BizHawk.Client.ApiHawk/Classes/ClientApi.cs +++ b/BizHawk.Client.ApiHawk/Classes/ClientApi.cs @@ -307,7 +307,7 @@ namespace BizHawk.Client.ApiHawk /// Top padding /// Right padding /// Bottom padding - public static void SetClientExtraPadding(int left, int top, int right, int bottom) + public static void SetExtraPadding(int left, int top, int right, int bottom) { FieldInfo f = clientAssembly.GetType("BizHawk.Client.EmuHawk.GlobalWin").GetField("DisplayManager"); object displayManager = f.GetValue(null); @@ -321,9 +321,9 @@ namespace BizHawk.Client.ApiHawk /// Sets the extra padding added to the 'native' surface so that you can draw HUD elements in predictable placements /// /// Left padding - public static void SetClientExtraPadding(int left) + public static void SetExtraPadding(int left) { - SetClientExtraPadding(left, 0, 0, 0); + SetExtraPadding(left, 0, 0, 0); } /// @@ -331,9 +331,9 @@ namespace BizHawk.Client.ApiHawk /// /// Left padding /// Top padding - public static void SetClientExtraPadding(int left, int top) + public static void SetExtraPadding(int left, int top) { - SetClientExtraPadding(left, top, 0, 0); + SetExtraPadding(left, top, 0, 0); } /// @@ -342,12 +342,11 @@ namespace BizHawk.Client.ApiHawk /// Left padding /// Top padding /// Right padding - public static void SetClientExtraPadding(int left, int top, int right) + public static void SetExtraPadding(int left, int top, int right) { - SetClientExtraPadding(left, top, right, 0); + SetExtraPadding(left, top, right, 0); } - /// /// Set inputs in specified to specified player /// From b9d35399b7b75b7dd7ce451488c0265080875097 Mon Sep 17 00:00:00 2001 From: upthorn Date: Sun, 23 Dec 2018 00:46:20 -0800 Subject: [PATCH 17/22] Created some working small integers to bypass C#'s hatred of 8bit and 16bit arithmetic. --- .../BizHawk.Emulation.Common.csproj | 4 + .../WorkingTypes/wbyte.cs | 112 ++++++++++++++++++ .../WorkingTypes/wsbyte.cs | 111 +++++++++++++++++ .../WorkingTypes/wshort.cs | 111 +++++++++++++++++ .../WorkingTypes/wushort.cs | 112 ++++++++++++++++++ 5 files changed, 450 insertions(+) create mode 100644 BizHawk.Emulation.Common/WorkingTypes/wbyte.cs create mode 100644 BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs create mode 100644 BizHawk.Emulation.Common/WorkingTypes/wshort.cs create mode 100644 BizHawk.Emulation.Common/WorkingTypes/wushort.cs diff --git a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj index 0a8aa6ec09..7287faab8b 100644 --- a/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj +++ b/BizHawk.Emulation.Common/BizHawk.Emulation.Common.csproj @@ -121,6 +121,10 @@ + + + + diff --git a/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs b/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs new file mode 100644 index 0000000000..f09a152bd6 --- /dev/null +++ b/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs @@ -0,0 +1,112 @@ +using System; +using System.Globalization; +using System.Security; + + +namespace BizHawk.Emulation.Common.WorkingTypes +{ + // + // Summary: + // Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# Byte by calling its methods where relevant. + public unsafe class wbyte : IComparable, IFormattable, IComparable, IEquatable + { + private Byte val; + public const Byte MaxValue = Byte.MaxValue; + public const Byte MinValue = Byte.MinValue; + public static implicit operator wbyte(uint value) + { + return value; + } + public static implicit operator byte(wbyte value) + { + return value.val; + } + public wbyte() + { + + } + public wbyte(uint value) + { + val = (Byte)(value & 0xFF); + } + public wbyte(int value) + { + val = (Byte)(value & 0xFF); + } + public wbyte(double value) + { + val = (Byte)(((int)value) & 0xFF); + } + public static wbyte Parse(string s, NumberStyles style, IFormatProvider provider) + { + return (uint)Byte.Parse(s, style, provider); + } + public static wbyte Parse(string s, IFormatProvider provider) + { + return (uint)Byte.Parse(s, provider); + } + public static wbyte Parse(string s) + { + return (uint)Byte.Parse(s); + } + public static wbyte Parse(string s, NumberStyles style) + { + return (uint)Byte.Parse(s, style); + } + public static bool TryParse(string s, out wbyte result) + { + result = new wbyte(); + return byte.TryParse(s, out result.val); + } + public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wbyte result) + { + result = new wbyte(); + return byte.TryParse(s, style, provider, out result.val); + } + public int CompareTo(wbyte value) + { + return val.CompareTo(value.val); + } + public int CompareTo(object value) + { + return val.CompareTo(value); + } + public override bool Equals(object obj) + { + return val.Equals(obj); + } + public bool Equals(wbyte obj) + { + return val.Equals(obj); + } + public override int GetHashCode() + { + return val.GetHashCode(); + } + public TypeCode GetTypeCode() + { + return val.GetTypeCode(); + } + [SecuritySafeCritical] + public string ToString(string format, IFormatProvider provider) + { + return val.ToString(format, provider); + } + [SecuritySafeCritical] + public override string ToString() + { + return val.ToString(); + } + [SecuritySafeCritical] + public string ToString(string format) + { + return val.ToString(format); + } + [SecuritySafeCritical] + public string ToString(IFormatProvider provider) + { + return val.ToString(provider); + } + } +} \ No newline at end of file diff --git a/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs b/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs new file mode 100644 index 0000000000..859b0a563c --- /dev/null +++ b/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs @@ -0,0 +1,111 @@ +using System; +using System.Globalization; +using System.Security; + +namespace BizHawk.Emulation.Common.WorkingTypes +{ + // + // Summary: + // Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# SByte by calling its methods where relevant. + public unsafe class wsbyte : IComparable, IFormattable, IComparable, IEquatable + { + private SByte val; + public const SByte MaxValue = SByte.MaxValue; + public const SByte MinValue = SByte.MinValue; + public static implicit operator wsbyte(int value) + { + return value; + } + public static implicit operator SByte(wsbyte value) + { + return value.val; + } + public wsbyte() + { + + } + public wsbyte(int value) + { + val = (SByte)(value & 0xFF); + } + public wsbyte(uint value) + { + val = (SByte)(value & 0xFF); + } + public wsbyte(double value) + { + val = (SByte)(((uint)value) & 0xFF); + } + public static wsbyte Parse(string s, NumberStyles style, IFormatProvider provider) + { + return (int)SByte.Parse(s, style, provider); + } + public static wsbyte Parse(string s, IFormatProvider provider) + { + return (int)SByte.Parse(s, provider); + } + public static wsbyte Parse(string s) + { + return (int)SByte.Parse(s); + } + public static wsbyte Parse(string s, NumberStyles style) + { + return (int)SByte.Parse(s, style); + } + public static bool TryParse(string s, out wsbyte result) + { + result = new wsbyte(); + return SByte.TryParse(s, out result.val); + } + public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wsbyte result) + { + result = new wsbyte(); + return SByte.TryParse(s, style, provider, out result.val); + } + public int CompareTo(wsbyte value) + { + return val.CompareTo(value.val); + } + public int CompareTo(object value) + { + return val.CompareTo(value); + } + public override bool Equals(object obj) + { + return val.Equals(obj); + } + public bool Equals(wsbyte obj) + { + return val.Equals(obj); + } + public override int GetHashCode() + { + return val.GetHashCode(); + } + public TypeCode GetTypeCode() + { + return val.GetTypeCode(); + } + [SecuritySafeCritical] + public string ToString(string format, IFormatProvider provider) + { + return val.ToString(format, provider); + } + [SecuritySafeCritical] + public override string ToString() + { + return val.ToString(); + } + [SecuritySafeCritical] + public string ToString(string format) + { + return val.ToString(format); + } + [SecuritySafeCritical] + public string ToString(IFormatProvider provider) + { + return val.ToString(provider); + } + } +} \ No newline at end of file diff --git a/BizHawk.Emulation.Common/WorkingTypes/wshort.cs b/BizHawk.Emulation.Common/WorkingTypes/wshort.cs new file mode 100644 index 0000000000..04040691b9 --- /dev/null +++ b/BizHawk.Emulation.Common/WorkingTypes/wshort.cs @@ -0,0 +1,111 @@ +using System; +using System.Globalization; +using System.Security; + +namespace BizHawk.Emulation.Common.WorkingTypes +{ + // + // Summary: + // Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# Int16 by calling its methods where relevant. + public unsafe class wshort : IComparable, IFormattable, IComparable, IEquatable + { + private Int16 val; + public const Int16 MaxValue = Int16.MaxValue; + public const Int16 MinValue = Int16.MinValue; + public static implicit operator wshort(int value) + { + return value; + } + public static implicit operator Int16(wshort value) + { + return value.val; + } + public wshort() + { + + } + public wshort(int value) + { + val = (Int16)(value & 0xFFFF); + } + public wshort(uint value) + { + val = (Int16)(value & 0xFFFF); + } + public wshort(double value) + { + val = (Int16)(((uint)value) & 0xFFFF); + } + public static wshort Parse(string s, NumberStyles style, IFormatProvider provider) + { + return (int)Int16.Parse(s, style, provider); + } + public static wshort Parse(string s, IFormatProvider provider) + { + return (int)Int16.Parse(s, provider); + } + public static wshort Parse(string s) + { + return (int)Int16.Parse(s); + } + public static wshort Parse(string s, NumberStyles style) + { + return (int)Int16.Parse(s, style); + } + public static bool TryParse(string s, out wshort result) + { + result = new wshort(); + return Int16.TryParse(s, out result.val); + } + public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wshort result) + { + result = new wshort(); + return Int16.TryParse(s, style, provider, out result.val); + } + public int CompareTo(wshort value) + { + return val.CompareTo(value.val); + } + public int CompareTo(object value) + { + return val.CompareTo(value); + } + public override bool Equals(object obj) + { + return val.Equals(obj); + } + public bool Equals(wshort obj) + { + return val.Equals(obj); + } + public override int GetHashCode() + { + return val.GetHashCode(); + } + public TypeCode GetTypeCode() + { + return val.GetTypeCode(); + } + [SecuritySafeCritical] + public string ToString(string format, IFormatProvider provider) + { + return val.ToString(format, provider); + } + [SecuritySafeCritical] + public override string ToString() + { + return val.ToString(); + } + [SecuritySafeCritical] + public string ToString(string format) + { + return val.ToString(format); + } + [SecuritySafeCritical] + public string ToString(IFormatProvider provider) + { + return val.ToString(provider); + } + } +} \ No newline at end of file diff --git a/BizHawk.Emulation.Common/WorkingTypes/wushort.cs b/BizHawk.Emulation.Common/WorkingTypes/wushort.cs new file mode 100644 index 0000000000..3e5a84abe3 --- /dev/null +++ b/BizHawk.Emulation.Common/WorkingTypes/wushort.cs @@ -0,0 +1,112 @@ +using System; +using System.Globalization; +using System.Security; + + +namespace BizHawk.Emulation.Common.WorkingTypes +{ + // + // Summary: + // Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# UInt16 by calling its methods where relevant. + public unsafe class wushort : IComparable, IFormattable, IComparable, IEquatable + { + private UInt16 val; + public const UInt16 MaxValue = UInt16.MaxValue; + public const UInt16 MinValue = UInt16.MinValue; + public static implicit operator wushort(uint value) + { + return value; + } + public static implicit operator ushort(wushort value) + { + return value.val; + } + public wushort() + { + + } + public wushort(uint value) + { + val = (UInt16)(value & 0xFFFF); + } + public wushort(int value) + { + val = (UInt16)(value & 0xFFFF); + } + public wushort(double value) + { + val = (UInt16)(((int)value) & 0xFFFF); + } + public static wushort Parse(string s, NumberStyles style, IFormatProvider provider) + { + return (uint)UInt16.Parse(s, style, provider); + } + public static wushort Parse(string s, IFormatProvider provider) + { + return (uint)UInt16.Parse(s, provider); + } + public static wushort Parse(string s) + { + return (uint)UInt16.Parse(s); + } + public static wushort Parse(string s, NumberStyles style) + { + return (uint)UInt16.Parse(s, style); + } + public static bool TryParse(string s, out wushort result) + { + result = new wushort(); + return ushort.TryParse(s, out result.val); + } + public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out wushort result) + { + result = new wushort(); + return ushort.TryParse(s, style, provider, out result.val); + } + public int CompareTo(wushort value) + { + return val.CompareTo(value.val); + } + public int CompareTo(object value) + { + return val.CompareTo(value); + } + public override bool Equals(object obj) + { + return val.Equals(obj); + } + public bool Equals(wushort obj) + { + return val.Equals(obj); + } + public override int GetHashCode() + { + return val.GetHashCode(); + } + public TypeCode GetTypeCode() + { + return val.GetTypeCode(); + } + [SecuritySafeCritical] + public string ToString(string format, IFormatProvider provider) + { + return val.ToString(format, provider); + } + [SecuritySafeCritical] + public override string ToString() + { + return val.ToString(); + } + [SecuritySafeCritical] + public string ToString(string format) + { + return val.ToString(format); + } + [SecuritySafeCritical] + public string ToString(IFormatProvider provider) + { + return val.ToString(provider); + } + } +} \ No newline at end of file From 34c207ff38e689dce820f8fb0c4b9fea7f4b9a84 Mon Sep 17 00:00:00 2001 From: upthorn Date: Sun, 23 Dec 2018 04:25:08 -0800 Subject: [PATCH 18/22] Fixed an infinite recursion in the implicit conversions of the working types --- BizHawk.Emulation.Common/WorkingTypes/wbyte.cs | 2 +- BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs | 2 +- BizHawk.Emulation.Common/WorkingTypes/wshort.cs | 2 +- BizHawk.Emulation.Common/WorkingTypes/wushort.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs b/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs index f09a152bd6..aeabe1ffd6 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs @@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Common.WorkingTypes public const Byte MinValue = Byte.MinValue; public static implicit operator wbyte(uint value) { - return value; + return new wbyte(value); } public static implicit operator byte(wbyte value) { diff --git a/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs b/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs index 859b0a563c..183f4af48e 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs @@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Common.WorkingTypes public const SByte MinValue = SByte.MinValue; public static implicit operator wsbyte(int value) { - return value; + return new wsbyte(value); } public static implicit operator SByte(wsbyte value) { diff --git a/BizHawk.Emulation.Common/WorkingTypes/wshort.cs b/BizHawk.Emulation.Common/WorkingTypes/wshort.cs index 04040691b9..7e0808471f 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wshort.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wshort.cs @@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Common.WorkingTypes public const Int16 MinValue = Int16.MinValue; public static implicit operator wshort(int value) { - return value; + return new wshort(value); } public static implicit operator Int16(wshort value) { diff --git a/BizHawk.Emulation.Common/WorkingTypes/wushort.cs b/BizHawk.Emulation.Common/WorkingTypes/wushort.cs index 3e5a84abe3..57851100b6 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wushort.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wushort.cs @@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Common.WorkingTypes public const UInt16 MinValue = UInt16.MinValue; public static implicit operator wushort(uint value) { - return value; + return new wushort(value); } public static implicit operator ushort(wushort value) { From c76d850687f320cafa6b174b6af98fedd3a63d3f Mon Sep 17 00:00:00 2001 From: upthorn Date: Thu, 3 Jan 2019 05:52:31 -0800 Subject: [PATCH 19/22] Working types now allow implicit conversions from longs. --- .../Api/Libraries/PluginLibrary.cs | 52 ------------------- .../WorkingTypes/wbyte.cs | 24 +++++---- .../WorkingTypes/wsbyte.cs | 20 +++---- .../WorkingTypes/wshort.cs | 20 +++---- .../WorkingTypes/wushort.cs | 18 ++++--- 5 files changed, 45 insertions(+), 89 deletions(-) delete mode 100644 BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs diff --git a/BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs b/BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs deleted file mode 100644 index ca44e44a3d..0000000000 --- a/BizHawk.Client.EmuHawk/Api/Libraries/PluginLibrary.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using BizHawk.Common.ReflectionExtensions; -using BizHawk.Emulation.Common; -using BizHawk.Client.ApiHawk; - -namespace BizHawk.Client.EmuHawk - -{ - public static class ApiManager - { - private static ApiContainer container; - private static void Register(IEmulatorServiceProvider serviceProvider) - { - // Register external apis - var libs = Assembly - .Load("BizHawk.Client.ApiHawk") - .GetTypes() - .Where(t => typeof(IExternalApi).IsAssignableFrom(t)) - .Where(t => t.IsSealed) - .Where(t => ServiceInjector.IsAvailable(serviceProvider, t)) - .ToList(); - - libs.AddRange( - Assembly - .GetAssembly(typeof(ApiContainer)) - .GetTypes() - .Where(t => typeof(IExternalApi).IsAssignableFrom(t)) - .Where(t => t.IsSealed) - .Where(t => ServiceInjector.IsAvailable(serviceProvider, t))); - - foreach (var lib in libs) - { - var instance = (IExternalApi)Activator.CreateInstance(lib); - ServiceInjector.UpdateServices(serviceProvider, instance); - Libraries.Add(lib, instance); - } - container = new ApiContainer(Libraries); - GlobalWin.ApiProvider = new BasicApiProvider(container); - } - private static readonly Dictionary Libraries = new Dictionary(); - public static void Restart(IEmulatorServiceProvider newServiceProvider) - { - Libraries.Clear(); - Register(newServiceProvider); - } - } -} diff --git a/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs b/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs index aeabe1ffd6..621ea82131 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wbyte.cs @@ -7,14 +7,18 @@ namespace BizHawk.Emulation.Common.WorkingTypes { // // Summary: - // Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep. - // Also provides all the base functionality of the standard C# Byte by calling its methods where relevant. + // Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# Byte by calling its methods where relevant. public unsafe class wbyte : IComparable, IFormattable, IComparable, IEquatable { private Byte val; public const Byte MaxValue = Byte.MaxValue; public const Byte MinValue = Byte.MinValue; - public static implicit operator wbyte(uint value) + public static implicit operator wbyte(ulong value) + { + return new wbyte(value); + } + public static implicit operator wbyte(wushort value) { return new wbyte(value); } @@ -26,33 +30,33 @@ namespace BizHawk.Emulation.Common.WorkingTypes { } - public wbyte(uint value) + public wbyte(ulong value) { val = (Byte)(value & 0xFF); } - public wbyte(int value) + public wbyte(long value) { val = (Byte)(value & 0xFF); } public wbyte(double value) { - val = (Byte)(((int)value) & 0xFF); + val = (Byte)(((long)value) & 0xFF); } public static wbyte Parse(string s, NumberStyles style, IFormatProvider provider) { - return (uint)Byte.Parse(s, style, provider); + return (ulong)Byte.Parse(s, style, provider); } public static wbyte Parse(string s, IFormatProvider provider) { - return (uint)Byte.Parse(s, provider); + return (ulong)Byte.Parse(s, provider); } public static wbyte Parse(string s) { - return (uint)Byte.Parse(s); + return (ulong)Byte.Parse(s); } public static wbyte Parse(string s, NumberStyles style) { - return (uint)Byte.Parse(s, style); + return (ulong)Byte.Parse(s, style); } public static bool TryParse(string s, out wbyte result) { diff --git a/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs b/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs index 183f4af48e..187cf46c39 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wsbyte.cs @@ -6,14 +6,14 @@ namespace BizHawk.Emulation.Common.WorkingTypes { // // Summary: - // Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep. - // Also provides all the base functionality of the standard C# SByte by calling its methods where relevant. + // Represents an 8-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# SByte by calling its methods where relevant. public unsafe class wsbyte : IComparable, IFormattable, IComparable, IEquatable { private SByte val; public const SByte MaxValue = SByte.MaxValue; public const SByte MinValue = SByte.MinValue; - public static implicit operator wsbyte(int value) + public static implicit operator wsbyte(long value) { return new wsbyte(value); } @@ -25,33 +25,33 @@ namespace BizHawk.Emulation.Common.WorkingTypes { } - public wsbyte(int value) + public wsbyte(long value) { val = (SByte)(value & 0xFF); } - public wsbyte(uint value) + public wsbyte(ulong value) { val = (SByte)(value & 0xFF); } public wsbyte(double value) { - val = (SByte)(((uint)value) & 0xFF); + val = (SByte)(((ulong)value) & 0xFF); } public static wsbyte Parse(string s, NumberStyles style, IFormatProvider provider) { - return (int)SByte.Parse(s, style, provider); + return (long)SByte.Parse(s, style, provider); } public static wsbyte Parse(string s, IFormatProvider provider) { - return (int)SByte.Parse(s, provider); + return (long)SByte.Parse(s, provider); } public static wsbyte Parse(string s) { - return (int)SByte.Parse(s); + return (long)SByte.Parse(s); } public static wsbyte Parse(string s, NumberStyles style) { - return (int)SByte.Parse(s, style); + return (long)SByte.Parse(s, style); } public static bool TryParse(string s, out wsbyte result) { diff --git a/BizHawk.Emulation.Common/WorkingTypes/wshort.cs b/BizHawk.Emulation.Common/WorkingTypes/wshort.cs index 7e0808471f..aa66438db3 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wshort.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wshort.cs @@ -6,14 +6,14 @@ namespace BizHawk.Emulation.Common.WorkingTypes { // // Summary: - // Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep. - // Also provides all the base functionality of the standard C# Int16 by calling its methods where relevant. + // Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# Int16 by calling its methods where relevant. public unsafe class wshort : IComparable, IFormattable, IComparable, IEquatable { private Int16 val; public const Int16 MaxValue = Int16.MaxValue; public const Int16 MinValue = Int16.MinValue; - public static implicit operator wshort(int value) + public static implicit operator wshort(long value) { return new wshort(value); } @@ -25,33 +25,33 @@ namespace BizHawk.Emulation.Common.WorkingTypes { } - public wshort(int value) + public wshort(long value) { val = (Int16)(value & 0xFFFF); } - public wshort(uint value) + public wshort(ulong value) { val = (Int16)(value & 0xFFFF); } public wshort(double value) { - val = (Int16)(((uint)value) & 0xFFFF); + val = (Int16)(((ulong)value) & 0xFFFF); } public static wshort Parse(string s, NumberStyles style, IFormatProvider provider) { - return (int)Int16.Parse(s, style, provider); + return (long)Int16.Parse(s, style, provider); } public static wshort Parse(string s, IFormatProvider provider) { - return (int)Int16.Parse(s, provider); + return (long)Int16.Parse(s, provider); } public static wshort Parse(string s) { - return (int)Int16.Parse(s); + return (long)Int16.Parse(s); } public static wshort Parse(string s, NumberStyles style) { - return (int)Int16.Parse(s, style); + return (long)Int16.Parse(s, style); } public static bool TryParse(string s, out wshort result) { diff --git a/BizHawk.Emulation.Common/WorkingTypes/wushort.cs b/BizHawk.Emulation.Common/WorkingTypes/wushort.cs index 57851100b6..427a414c6f 100644 --- a/BizHawk.Emulation.Common/WorkingTypes/wushort.cs +++ b/BizHawk.Emulation.Common/WorkingTypes/wushort.cs @@ -7,18 +7,22 @@ namespace BizHawk.Emulation.Common.WorkingTypes { // // Summary: - // Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep. - // Also provides all the base functionality of the standard C# UInt16 by calling its methods where relevant. + // Represents an 16-bit unsigned integer, that is capable of arithmetic without making you weep. + // Also provides all the base functionality of the standard C# UInt16 by calling its methods where relevant. public unsafe class wushort : IComparable, IFormattable, IComparable, IEquatable { private UInt16 val; public const UInt16 MaxValue = UInt16.MaxValue; public const UInt16 MinValue = UInt16.MinValue; - public static implicit operator wushort(uint value) + public static implicit operator wushort(ulong value) { return new wushort(value); } - public static implicit operator ushort(wushort value) + public static implicit operator wushort(wbyte value) + { + return new wushort(value); + } + public static implicit operator UInt16(wushort value) { return value.val; } @@ -26,17 +30,17 @@ namespace BizHawk.Emulation.Common.WorkingTypes { } - public wushort(uint value) + public wushort(ulong value) { val = (UInt16)(value & 0xFFFF); } - public wushort(int value) + public wushort(long value) { val = (UInt16)(value & 0xFFFF); } public wushort(double value) { - val = (UInt16)(((int)value) & 0xFFFF); + val = (UInt16)(((long)value) & 0xFFFF); } public static wushort Parse(string s, NumberStyles style, IFormatProvider provider) { From bc4330a9d1df1ed8cf84fa1ce4b5bbe1a86b1e44 Mon Sep 17 00:00:00 2001 From: upthorn Date: Thu, 3 Jan 2019 05:53:26 -0800 Subject: [PATCH 20/22] External tools no longer crash on loading new ROM --- BizHawk.Client.EmuHawk/Api/ApiManager.cs | 52 +++++++++++++++++++ .../BizHawk.Client.EmuHawk.csproj | 2 +- BizHawk.Client.EmuHawk/MainForm.cs | 2 +- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 BizHawk.Client.EmuHawk/Api/ApiManager.cs diff --git a/BizHawk.Client.EmuHawk/Api/ApiManager.cs b/BizHawk.Client.EmuHawk/Api/ApiManager.cs new file mode 100644 index 0000000000..9dd5b71087 --- /dev/null +++ b/BizHawk.Client.EmuHawk/Api/ApiManager.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using BizHawk.Common.ReflectionExtensions; +using BizHawk.Emulation.Common; +using BizHawk.Client.ApiHawk; + +namespace BizHawk.Client.EmuHawk + +{ + public static class ApiManager + { + private static ApiContainer container; + private static void Register(IEmulatorServiceProvider serviceProvider) + { + // Register external apis + var apis = Assembly + .Load("BizHawk.Client.ApiHawk") + .GetTypes() + .Where(t => typeof(IExternalApi).IsAssignableFrom(t)) + .Where(t => t.IsSealed) + .Where(t => ServiceInjector.IsAvailable(serviceProvider, t)) + .ToList(); + + apis.AddRange( + Assembly + .GetAssembly(typeof(ApiContainer)) + .GetTypes() + .Where(t => typeof(IExternalApi).IsAssignableFrom(t)) + .Where(t => t.IsSealed) + .Where(t => ServiceInjector.IsAvailable(serviceProvider, t))); + + foreach (var api in apis) + { + var instance = (IExternalApi)Activator.CreateInstance(api); + ServiceInjector.UpdateServices(serviceProvider, instance); + Libraries.Add(api, instance); + } + container = new ApiContainer(Libraries); + GlobalWin.ApiProvider = new BasicApiProvider(container); + } + private static readonly Dictionary Libraries = new Dictionary(); + public static void Restart(IEmulatorServiceProvider newServiceProvider) + { + Libraries.Clear(); + Register(newServiceProvider); + } + } +} diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index efbb0d391d..e149f0bf88 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -664,7 +664,7 @@ - + diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 626e98fe2b..5ac22ab9f3 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -3793,8 +3793,8 @@ namespace BizHawk.Client.EmuHawk } } - GlobalWin.Tools.Restart(); ApiManager.Restart(Emulator.ServiceProvider); + GlobalWin.Tools.Restart(); if (Global.Config.LoadCheatFileByGame) { From 9d853d200d7830239357210408bc76b0882c5fd7 Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 4 Jan 2019 13:57:34 -0800 Subject: [PATCH 21/22] Remove vestigial hard-coded Ecco 2 tool --- .../Api/Example/Ecco2AssistantPlugin.cs | 3456 ----------------- .../BizHawk.Client.EmuHawk.csproj | 1 - 2 files changed, 3457 deletions(-) delete mode 100644 BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs diff --git a/BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs b/BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs deleted file mode 100644 index 8764258e3d..0000000000 --- a/BizHawk.Client.EmuHawk/Api/Example/Ecco2AssistantPlugin.cs +++ /dev/null @@ -1,3456 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Drawing; - -using System.Linq; -using BizHawk.Client.ApiHawk; -using BizHawk.Emulation.Cores.Consoles.Sega.gpgx; - -namespace BizHawk.Client.EmuHawk -{ - public sealed class Ecco2AssistantPlugin : PluginBase - { - [RequiredApi] - private IMem Mem {get; set;} - - [RequiredApi] - private IGui Gui { get; set; } - - [RequiredApi] - private IJoypad Joy { get; set; } - - [RequiredApi] - private IEmu Emu { get; set; } - - [RequiredApi] - private IGameInfo GI { get; set; } - - [RequiredApi] - private IMemorySaveState MemSS { get; set; } - - public override string Name => "Ecco 2 Assistant"; - - public override string Description => "Displays a hud with hitboxes, etc. Assists with maintaining maximum speed."; - - private enum Modes { disabled, Ecco1, Ecco2 } - private Modes _mode; - - private int _camX = 0; - private int _camY = 0; - private int _camXAddr; - private int _camYAddr; - private uint _prevF = 0; - private int _top = 0; - private int _bottom = 0; - private int _left = 0; - private int _right = 0; - private const int _signalAlpha = 255; - private int _tickerY = 81; - private int _dumpMap = 0; - private int _prevX = 0; - private int _prevY = 0; - private int _destX = 0; - private int _destY = 0; - private int _snapPast = 0; - private string _rowStateGuid = string.Empty; - private Color[] _turnSignalColors = - { - Color.FromArgb(_signalAlpha, 127, 127, 0), - Color.FromArgb(_signalAlpha, 255, 0, 0), - Color.FromArgb(_signalAlpha, 192, 0, 63), - Color.FromArgb(_signalAlpha, 63, 0, 192), - Color.FromArgb(_signalAlpha, 0, 0, 255), - Color.FromArgb(_signalAlpha, 0, 63, 192), - Color.FromArgb(_signalAlpha, 0, 192, 63), - Color.FromArgb(_signalAlpha, 0, 255, 0) - }; - private int _rseed = 1; - private int EccoRand(bool refresh = false) - { - if (refresh) - { - _rseed = (int)(Mem.ReadU16(0xFFE2F8)); - } - bool odd = (_rseed & 1) != 0; - _rseed >>= 1; - if (odd) - { - _rseed ^= 0xB400; - } - return _rseed; - } - private void DrawEccoRhomb(int x, int y, int radius, Color color, int fillAlpha = 63) - { - Point[] rhombus = { - new Point(x, y - radius), - new Point(x + radius, y), - new Point(x, y + radius), - new Point(x - radius, y) - }; - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawPolygon(rhombus, color, fillColor); - } - private void DrawEccoRhomb_scaled(int x, int y, int width, int height, int rscale, int bscale, int lscale, int tscale, Color color, int fillAlpha = 63) - { - Point[] rhombus = { - new Point(x + (width << rscale), y), - new Point(x, y + (height << bscale)), - new Point(x - (width << lscale), y), - new Point(x, y - (height << tscale)) - }; - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawPolygon(rhombus, color, fillColor); - } - private void DrawEccoOct(int x, int y, int r, Color color, int fillAlpha = 63) - { - var octOff = (int)(Math.Sqrt(2) * r) >> 1; - Point[] octagon = { - new Point(x, y - r), - new Point(x + octOff, y - octOff), - new Point(x + r, y), - new Point(x + octOff, y + octOff), - new Point(x, y + r), - new Point(x - octOff, y + octOff), - new Point(x - r, y), - new Point(x - octOff, y - octOff) - }; - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawPolygon(octagon, color, fillColor); - } - private void DrawEccoOct_scaled(int x, int y, int xscale, int yscale, int r, Color color, int fillAlpha = 63) - { - var octOff = (int)(Math.Sin(Math.PI / 4) * r); - var xoctOff = octOff << xscale; - var yoctOff = octOff << yscale; - var xr = r << xscale; - var yr = r << yscale; - Point[] octagon = { - new Point(x, y - yr), - new Point(x + xoctOff, y - yoctOff), - new Point(x + xr, y), - new Point(x + xoctOff, y + yoctOff), - new Point(x, y + yr), - new Point(x - xoctOff, y + yoctOff), - new Point(x - xr, y), - new Point(x - xoctOff, y - yoctOff) - }; - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawPolygon(octagon, color, fillColor); - } - private Point? Intersection(Point start1, Point end1, Point start2, Point end2) - { - if ((Math.Max(start1.X, end1.X) < Math.Min(start2.X, end2.X)) - || (Math.Min(start1.X, end1.X) > Math.Max(start2.X, end2.X)) - || (Math.Max(start1.Y, end1.Y) < Math.Min(start2.Y, end2.Y)) - || (Math.Min(start1.Y, end1.Y) > Math.Max(start2.Y, end2.Y))) - return null; - - - double ay_cy, ax_cx, px, py; - double dx_cx = end2.X - start2.X, - dy_cy = end2.Y - start2.Y, - bx_ax = end1.X - start1.X, - by_ay = end1.Y - start1.Y; - - double de = (bx_ax) * (dy_cy) - (by_ay) * (dx_cx); - - if (Math.Abs(de) < 0.01) - return null; - - ax_cx = start1.X - start2.X; - ay_cy = start1.Y - start2.Y; - double r = ((ay_cy) * (dx_cx) - (ax_cx) * (dy_cy)) / de; - double s = ((ay_cy) * (bx_ax) - (ax_cx) * (by_ay)) / de; - px = start1.X + r * (bx_ax); - py = start1.Y + r * (by_ay); - if ((px < Math.Min(start1.X, end1.X)) || (px > Math.Max(start1.X, end1.X)) - || (px < Math.Min(start2.X, end2.X)) || (px > Math.Max(start2.X, end2.X)) - || (py < Math.Min(start1.Y, end1.Y)) || (py > Math.Max(start1.Y, end1.Y)) - || (py < Math.Min(start2.Y, end2.Y)) || (py > Math.Max(start2.Y, end2.Y))) - return null; - return new Point((int)px, (int)py); - } - private void DrawRectRhombusIntersection(Point rectMid, Point rhombMid, int rw, int rh, int r, Color color, int fillAlpha = 63) // Octagon provided by the intersection of a rectangle and a rhombus - { - Point[] rect = - { - new Point(rectMid.X - rw, rectMid.Y + rh), - new Point(rectMid.X - rw, rectMid.Y - rh), - new Point(rectMid.X + rw, rectMid.Y - rh), - new Point(rectMid.X + rw, rectMid.Y + rh) - }; - Point[] rhombus = - { - new Point(rhombMid.X - r, rhombMid.Y), - new Point(rhombMid.X, rhombMid.Y - r), - new Point(rhombMid.X + r, rhombMid.Y), - new Point(rhombMid.X, rhombMid.Y + r) - }; - List finalShape = new List(); - foreach (Point p in rect) - { - if (Math.Abs(p.X - rhombMid.X) + Math.Abs(p.Y - rhombMid.Y) <= r) - finalShape.Add(p); - } - foreach (Point p in rhombus) - { - if ((Math.Abs(p.X - rectMid.X) <= rw) && (Math.Abs(p.Y - rectMid.Y) <= rh)) - finalShape.Add(p); - } - for (int i = 0; i < 5; i++) - { - Point? p = Intersection(rhombus[i & 3], rhombus[(i + 1) & 3], rect[i & 3], rect[(i + 1) & 3]); - if (p.HasValue) finalShape.Add(p.Value); - p = Intersection(rhombus[i & 3], rhombus[(i + 1) & 3], rect[(i + 1) & 3], rect[(i + 2) & 3]); - if (p.HasValue) finalShape.Add(p.Value); - } - double mX = 0; - double my = 0; - foreach (Point p in finalShape) - { - mX += p.X; - my += p.Y; - } - mX /= finalShape.ToArray().Length; - my /= finalShape.ToArray().Length; - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawPolygon(finalShape.OrderBy(p => Math.Atan2(p.Y - my, p.X - mX)).ToArray(), color, fillColor); - } - private void DrawEccoTriangle(int x1, int y1, int x2, int y2, int x3, int y3, Color color, int fillAlpha = 63) - { - Color? fillColor = null; - Point[] triPoints = - { - new Point(x1, y1), - new Point(x2, y2), - new Point(x3, y3) - }; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawPolygon(triPoints, color, fillColor); - } - private void DrawBoxMWH(int x, int y, int w, int h, Color color, int fillAlpha = 63) - { - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawRectangle(x - w, y - h, w << 1, h << 1, color, fillColor); - } - private void DrawBox(int x, int y, int x2, int y2, Color color, int fillAlpha = 63) - { - Color? fillColor = null; - if (fillAlpha > 0) fillColor = Color.FromArgb(fillAlpha, color); - Gui.DrawBox(x, y, x2, y2, color, fillColor); - } - private void Print_Text(string message, int x, int y, Color color) - { - Gui.DrawText(x, y, message, color, null); - } - private void PutText(string message, int x, int y, int xl, int yl, int xh, int yh, Color bg, Color fg) - { - xl = Math.Max(xl, 0); - yl = Math.Max(yl, 0); - xh = Math.Min(xh + 639, 639); - yh = Math.Min(yh + 441, 441); - xh -= 4 * message.Length; - x = x - ((5 * (message.Length - 1)) / 2); - y -= 3; -// x = Math.Min(Math.Max(x, Math.Max(xl, 1)), Math.Min(xh, 638 - 4 * (int)message.Length)); -// y = Math.Min(Math.Max(y - 3, Math.Max(yl, 1)), yh); - int[] xOffset = { -1, -1, -1, 0, 1, 1, 1, 0 }; - int[] yOffset = { -1, 0, 1, 1, 1, 0, -1, -1 }; - for (int i = 0; i < 8; i++) - Print_Text(message, x + xOffset[i], y + yOffset[i], bg); - Print_Text(message, x, y, fg); - } - private void TickerText(string message, Color? fg = null) - { - if (_dumpMap == 0) - Gui.Text(1, _tickerY, message, fg); - _tickerY += 16; - } - private void EccoDraw3D() - { - int CamX = (Mem.ReadS32(0xFFD5E0) >> 0xC) - _left; - int CamY = (Mem.ReadS32(0xFFD5E8) >> 0xC) + _top; - int CamZ = (Mem.ReadS32(0xFFD5E4) >> 0xC) + _top; - uint curObj = Mem.ReadU24(0xFFD4C1); - while (curObj != 0) - { - int Xpos = (Mem.ReadS32(curObj + 0x6) >> 0xC); - int Ypos = (Mem.ReadS32(curObj + 0xE) >> 0xC); - int Zpos = (Mem.ReadS32(curObj + 0xA) >> 0xC); - int Xmid = 160 + (Xpos - CamX); - int Ymid = 112 - (Ypos - CamY); - int Zmid = _top + 112 - (Zpos - CamZ); - uint type = Mem.ReadU32(curObj + 0x5A); - int width, height, depth = height = width = 0; - if (type == 0xD4AB8) // 3D poison Bubble - { - depth = 0x10; - int radius = 8; - width = radius; - DrawEccoOct(Xmid, Ymid, radius, Color.Lime); - DrawBoxMWH(Xmid, Zmid, width, depth, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); - } - else if (type == 0xD817E)// 3D Ring - { - depth = 8; - if (Mem.ReadU32(0xFFB166) < 0x1800) depth = 4; - int radius = 32; - width = radius; - DrawEccoOct(Xmid, Ymid, radius, (Mem.ReadS16(curObj + 0x62) == 0) ? Color.Orange : Color.Gray); - DrawBoxMWH(Xmid, Zmid, width, depth, Color.Red); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Red, 0); - TickerText($"{Mem.ReadS32(curObj + 0x6) / 4096.0:0.######}:{Mem.ReadS32(curObj + 0xE) / 4096.0:0.######}:{Mem.ReadS32(curObj + 0xA) / 2048.0:0.######}:{Mem.ReadByte(curObj + 0x72)}",Color.Lime); - } - else if (type == 0xD49CC) // Vines collisions are based on draw position, which is a fucking pain in the ass to calculate - { - int Xvel = (Mem.ReadS32(curObj + 0x3A) - Mem.ReadS32(curObj + 0x6)); - int Zvel = (Mem.ReadS32(curObj + 0x3E) - Mem.ReadS32(curObj + 0xA)); - int dx = Mem.ReadS32(0xFFD5E0) - Mem.ReadS32(0xFFD5C8) >> 3; - int dy = Mem.ReadS32(0xFFD5E8) - Mem.ReadS32(0xFFD600) >> 3; - int dz = Mem.ReadS32(0xFFD5E4) - Mem.ReadS32(0xFFD5CC); - var chargeCount = Mem.ReadByte(0xFFB19B); - if (chargeCount == 0) - { - dz >>= 2; - } - else if ((chargeCount > 0x20) || (chargeCount <= 0x10)) - { - dz >>= 3; - } - else if (chargeCount > 0x10) - { - dz >>= 4; - } - if (Mem.ReadByte(curObj + 0x64) == 0) - { - Xvel >>= 0xA; - Zvel >>= 9; - } - else - { - Xvel >>= 9; - Zvel >>= 0xA; - } - Xvel += Mem.ReadS32(curObj + 0x2E); - Zvel += Mem.ReadS32(curObj + 0x32); - Zpos = (Mem.ReadS32(curObj + 0x26) + dz - Mem.ReadS32(0xFFD5E4)) >> 0xB; - if ((Zpos < 0x600) && (Zpos > 0)) - { - Zpos += 0x20; - int Xcur, Xmax, Ycur, Ymax; - int Zpos2 = (Mem.ReadS32(curObj + 0xA) + Zvel + dz - Mem.ReadS32(0xFFD5E4)) >> 0xB; - Zpos2 = Math.Max(Zpos2 + 0x20, 1); - if (Mem.ReadS16(curObj + 0x62) != 0) - { - Xmid = Mem.ReadS32(curObj + 0x6) + dx + Xvel - Mem.ReadS32(0xFFD5E0); - if (Math.Abs(Xmid) > 0x400000) - continue; - Xpos = Mem.ReadS32(curObj + 0x22) + dx - Mem.ReadS32(0xFFD5E0); - if (Math.Abs(Xpos) > 0x400000) - continue; - Xcur = (Xmid << 2) / Zpos2 + (Xmid >> 5) + 0xA000 + (Xmid >> 5); - Xmax = (Xpos << 2) / Zpos + (Xpos >> 5) + 0xA000 + (Xpos >> 5); - } - else - { - Xcur = 0; - Xmax = 256; - } - Ymid = Mem.ReadS32(0xFFD5E8) + dy - Mem.ReadS32(curObj + 0xE); - Ycur = ((Ymid << 3) / Zpos2) + 0x6000; - Ypos = Mem.ReadS32(0xFFD5E8) + dy - Mem.ReadS32(curObj + 0x2A); - Ymax = ((Ypos << 3) / Zpos) + 0x6000; - dx = Xmax - Xcur; - dy = Ymax - Ycur; - int asindx = Math.Abs(dx >> 6) & 0xFFFF; - int asindy = Math.Abs(dy >> 6) & 0xFFFF; - int ang; - if (asindx == asindy) - { - if (dx > 0) - { - if (dy > 0) - { - ang = 0x20; - } - else - { - ang = 0xE0; - } - } - else - { - if (dy > 0) - { - ang = 0x60; - } - else - { - ang = 0xA0; - } - } - } - else - { - if (asindx > asindy) - { - asindy <<= 5; - asindy += asindx - 1; - asindy &= 0xFFFF; - asindy /= asindx; - } - else - { - asindx <<= 5; - asindx += asindy - 1; - asindx &= 0xFFFF; - asindx /= asindy; - asindy = 0x40 - asindx; - } - if (dx > 0) - { - if (dy > 0) - { - ang = asindy; - } - else - { - ang = 0xff - asindy; - } - } - else - { - if (dy > 0) - { - ang = 0x7f - asindy; - } - else - { - ang = 0x81 + asindy; - } - } - } - Xcur += Mem.ReadS8(0x2CC8 + ang) << 6; - Ycur += Mem.ReadS8(0x2BC8 + ang) << 6; - var dSml = Math.Abs(dx); - var dBig = Math.Abs(dy); - if (dBig < dSml) - { - dSml ^= dBig; - dBig ^= dSml; - dSml ^= dBig; - } - int OctRad = (dBig + (dSml >> 1) - (dSml >> 3)); - int i = Math.Max(((OctRad >> 8) + 0x1F) >> 5, 1); - dx /= i; - dy /= i; - - Zmid = (Mem.ReadS32(curObj + 0xA) + Mem.ReadS32(curObj + 0x26)) >> 1; - Zmid >>= 0xC; - Zmid = 112 + _top - (Zmid - CamZ); - do - { - i--; - DrawEccoRhomb((Xcur >> 8) + _left, (Ycur >> 8) + _top, 8, Color.Lime); - DrawBoxMWH((Xcur >> 8) + _left, Zmid, 8, 0x10, Color.Blue); - Xcur += dx; - Ycur += dy; - } while (i >= 0); - DrawBoxMWH((Mem.ReadS32(0xFFB1AA) >> 8) + _left, (Mem.ReadS32(0xFFB1AE) >> 8) + _top, 1, 1, Color.Lime, 0); - } - } - else if ((type == 0xD3B40) || (type == 0xD3DB2)) // 3D Shark and Jellyfish - { - width = (Mem.ReadS32(curObj + 0x12) >> 0xC); - height = (Mem.ReadS32(curObj + 0x1A) >> 0xC); - depth = (Mem.ReadS32(curObj + 0x16) >> 0xC); - DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); - DrawBoxMWH(Xmid, Zmid, width, depth, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); - } - else if ((type == 0xD4028) || (type == 0xD4DBA)) // 3D Eagle and 3D Shell - { - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); - } - else if (type == 0xD4432) // 3D Sonar Blast - { - DrawEccoOct(Xmid, Ymid, 48, Color.Orange); - DrawEccoOct(Xmid, Ymid, 32, Color.Lime); - DrawBoxMWH(Xmid, Zmid, 32, 32, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); - } - else if (type == 0xD463A) // 3D Homing Bubble - { - DrawEccoOct(Xmid, Ymid, 48, Color.Orange); - DrawEccoOct(Xmid, Ymid, 32, Color.Lime); - DrawBoxMWH(Xmid, Zmid, 32, 32, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); - } - else if ((type == 0xD37CE) || (type == 0xD4214) || (type == 0xD3808)) // bubbles, splashes, gfx sprites - { - width = height = depth = 0; - } - else - { - if (curObj != 0xFFB134) - { - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Lime, 0); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Blue, 0); - PutText(type.ToString("X8"), Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); - PutText(curObj.ToString("X8"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); - } - else - { - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange); - DrawBoxMWH(Xmid, Zmid, 1, 1, Color.Red); - } - } - curObj = Mem.ReadU24(curObj+1); - } - } - private void EccoDrawBoxes() - { - // CamX-=8; - int Width2, Height2; - //Ecco HP and Air - int i = 0; - int HP = Mem.ReadS16(0xFFAA16) << 3; - int air = Mem.ReadS16(0xFFAA18); - Color color; - int off = 0; - for (int j = 0; j < air; j++) - { - if (j - off == 448) - { - i++; off += 448; - } - color = Color.FromArgb(j >> 2, j >> 2, j >> 2); - Gui.DrawLine(_left - 32, j - off, _left - 17, j - off, color); - } - for (int j = 0; j < HP; j += 8) - { - color = Color.FromArgb(Math.Max(0x38 - (j >> 3),0), 0, Math.Min(j >> 1,255)); - Gui.DrawRectangle(_left - 16, j, 15, 7, color, color); - } - - //Asterite - uint type = Mem.ReadU32(0xFFD440); - uint curObj = 0; - int Xpos, Xpos2, Ypos, Ypos2, Xmid, Ymid, X, X2, Y, Y2; - Xpos = Ypos = Xpos2 = Ypos2 = Xmid = Ymid = X = X2 = Y = Y2 = 0; - if (type == 0xB119A) - { - curObj = Mem.ReadU24(Mem.ReadU24(0xFFD429)+5); - while (curObj != 0) - { - Xpos = Mem.ReadS16(curObj + 0x3C); - Xpos2 = Mem.ReadS16(curObj + 0x24); - Ypos = Mem.ReadS16(curObj + 0x40); - Ypos2 = Mem.ReadS16(curObj + 0x28); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - if (Mem.ReadU8(curObj + 0x71) != 0) - { - DrawEccoOct(Xpos, Ypos, 48, Color.Blue, 16); - DrawEccoOct(Xpos2, Ypos2, 48, Color.Blue, 16); - } - curObj = Mem.ReadU24(curObj + 5); - } - if ((Mem.ReadU8(0xFFA7D0) == 30)) - { - curObj = Mem.ReadU24(0xFFD425); - if ((curObj != 0) && (Mem.ReadU32(curObj + 8) != 0)) - { - Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; - Ypos = Mem.ReadS16(curObj + 0x20) - _camY; - DrawEccoOct(Xpos, Ypos, 20, Color.Orange); - } - } - } - else if (type == 0xB2CB8) - { - curObj = Mem.ReadU24(Mem.ReadU24(0xFFD429) + 5); - while (curObj != 0) - { - Xpos = Mem.ReadS16(curObj + 0x3C); - Xpos2 = Mem.ReadS16(curObj + 0x24); - Ypos = Mem.ReadS16(curObj + 0x40); - Ypos2 = Mem.ReadS16(curObj + 0x28); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - if (Mem.ReadU8(curObj + 0x71) != 0) - { - if (Mem.ReadByte(0xFFA7D0) != 0x1F) - { - DrawEccoOct(Xpos, Ypos, 40, Color.Lime); - DrawEccoOct(Xpos2, Ypos2, 40, Color.Lime); - } - DrawEccoOct(Xpos, Ypos, 48, Color.Blue, 16); - DrawEccoOct(Xpos2, Ypos2, 48, Color.Blue, 16); - } - curObj = Mem.ReadU24(curObj + 5); - } - } - //aqua tubes - curObj = Mem.ReadU24(0xFFCFC5); - while (curObj != 0) - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2= Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2= Mem.ReadS16(curObj + 0x38); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - // displayed = false; - type = Mem.ReadU8(curObj + 0x7E); - switch (type) - { - case 0x15: - case 0x18: - case 0x19: - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.Purple); - break; - case 0x1A: - case 0x1D: - case 0x20: - case 0x21: - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.Purple); - break; - case 0x1F: - case 0x22: - case 0x23: - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.Purple); - break; - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.Purple); - break; - case 0x2B: - Point[] trapPoints = - { - new Point(Xpos, Ymid), - new Point(Xpos + (Ymid - Ypos >> 1), Ypos), - new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), - new Point(Xpos2, Ymid) - }; - Gui.DrawPolygon(trapPoints, Color.Purple, Color.FromArgb(63, Color.Purple)); - break; - default: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Purple); - if (type != 0x10) - PutText(type.ToString("X2"), Xmid, Ymid, 1, 1, -1, -1, Color.Red, Color.Blue); - break; - } - curObj = Mem.ReadU24(curObj+1); - } - //walls - curObj = Mem.ReadU24(0xFFCFC1); - while (curObj != 0) - { - Xmid = Mem.ReadS16(curObj + 0x24); - Xmid = Mem.ReadS16(curObj + 0x28); - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2= Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2= Mem.ReadS16(curObj + 0x38); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - int colltype = Mem.ReadS8(curObj + 0x7E); - switch (colltype) - { - case 0x10: - case 0x2D: - case 0x2E: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x11: - Xmid = (Xpos + Xpos2) >> 1; - Xpos2 = Xmid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x12: - Xmid = (Xpos + Xpos2) >> 1; - Xpos = Xmid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos, Ypos, Xpos, Ypos2, Color.PowderBlue); - break; - case 0x13: - Ymid = (Ypos + Ypos2) >> 1; - Ypos = Ymid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.PowderBlue); - break; - case 0x14: - Ymid = (Ypos + Ypos2) >> 1; - Ypos2 = Ymid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); - break; - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); - break; - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.FromArgb(63,Color.Yellow)); - Gui.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); - break; - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.FromArgb(63,Color.Yellow)); - Gui.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); - break; - case 0x29: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); - Gui.DrawLine(Xpos , Ypos, Xpos , Ypos2, Color.Black); - Gui.DrawLine(Xpos2, Ypos, Xpos2, Ypos2, Color.Black); - break; - case 0x2A: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); - break; - case 0x2B: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - Point[] trapPoints = - { - new Point(Xpos, Ymid), - new Point(Xpos + (Ymid - Ypos >> 1), Ypos), - new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), - new Point(Xpos2, Ymid) - }; - Gui.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); - //Gui.DrawLine(Xpos, Ymid, Xpos2, Ymid, Color.Yellow); - break; - default: - DrawEccoRhomb_scaled(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); - break; - } - curObj = Mem.ReadU24(curObj+1); - } - //inanimate objects - curObj = Mem.ReadU24(0xFFCFBD); - while (curObj != 0) - { - type = Mem.ReadU32(curObj + 0xC); - int colltype = Mem.ReadS8(curObj + 0x7E); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - int Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - int Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - if (type == 0x9CE3A) //Remnant Stars - { - uint subObj = Mem.ReadU24(curObj + 0x5); - uint anim = Mem.ReadU16(curObj + 0x6C); - if ((anim <= 7) && (subObj == 0xFFA9D4)) - { - DrawEccoRhomb(Xmid, Ymid, 96, Color.Red); - PutText($"{((7 - anim) * 4) - ((Mem.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Lime, Color.Blue); - } - } - else if ((type == 0x9CC06) || (type == 0x9CA10)) - { - Xvec = ((Mem.ReadS32(curObj + 0x24) + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Mem.ReadS32(curObj + 0x28) + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - } - else if (type == 0x9B5D8) - { - Xvec = Xmid; - Yvec = Ymid; - } - else if (type == 0xC0152) // Vortex Future Vertical Gate - { - Xvec = Mem.ReadS16(curObj + 0x1C) - _camX; - Yvec = (Mem.ReadS32(curObj + 0x20) + Mem.ReadS32(curObj + 0x60) >> 16) - _camY; - Gui.DrawLine(Xmid, 0, Xmid, 448, Color.PowderBlue); - DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - } - else if (type == 0xC3330) // City Of Forever Horizontal Gate Slave - { - Xvec = (Mem.ReadS32(curObj + 0x1C) + Mem.ReadS32(curObj + 0x5C) >> 16) - _camX; - Yvec = Mem.ReadS16(curObj + 0x20) - _camY; - DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - } - else if (type == 0xC35B0) // City Of Forever Horizontal Gate Master - { - var mode = Mem.ReadByte(curObj + 0x15); - var tmpx = Xpos; - Xpos = Mem.ReadS32(curObj + 0x1C); - Xvec = (Xpos + Mem.ReadS32(curObj + 0x5C) >> 16) - _camX; - Xpos >>= 16; Xpos -= _camX; - Yvec = Mem.ReadS16(curObj + 0x20) - _camY; - if ((mode == 1) || (mode == 3)) - { - DrawEccoOct(Xpos, Yvec, 128, Color.Orange); - } - Xpos = tmpx; - DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - } - else if (type == 0xC343A) // City Of Forever Vertical Gate - { - var mode = Mem.ReadByte(curObj + 0x15); - if ((mode == 1) || (mode == 3)) - { - DrawEccoOct(Xmid, Ymid, 128, Color.Orange); - } - Xvec = Mem.ReadS16(curObj + 0x1C) - _camX; - Yvec = (Mem.ReadS32(curObj + 0x20) + Mem.ReadS32(curObj + 0x60) >> 16) - _camY; - DrawBoxMWH(Xvec, Yvec, 1, 1, Color.Blue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - } - else if (type == 0xA579A) // Antigrav Ball - { - DrawEccoOct(Xmid, Ymid, Mem.ReadS16(curObj + 0x4C), (Mem.ReadU16(0xFFA7C8) & 7) == 7 ? Color.Blue : Color.Gray); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); - Xpos = Ypos = Xpos2 = Ypos2 = _camX - 128; - } - else if (type == 0xDF4E2) // Moray Abyss Conch Shell - { - Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; - Ypos = Mem.ReadS16(curObj + 0x20) - _camY; - DrawBox(Xpos - 96, 0 - _camY, Xpos + 96, Mem.ReadS16(0xFFA7AC) - _camY - 64, Color.Orange, 0); - var mode = Mem.ReadByte(curObj + 0x15); - var modeTimer = Mem.ReadS16(curObj + 0x6E); - var Xvel1 = Mem.ReadS32(curObj + 0x54) / 65536.0; - var Yvel1 = Mem.ReadS32(curObj + 0x58) / 65536.0; - var Xvel2 = Mem.ReadS32(curObj + 0x5C) / 65536.0; - var Yvel2 = Mem.ReadS32(curObj + 0x60) / 65536.0; - TickerText($"{mode}:{modeTimer}:{Mem.ReadS16(0xFFA7AC) - 64 - Ymid - _camY}", Color.Red); - TickerText($"{Xvel1:0.######}:{Yvel1:0.######}", Color.Red); - TickerText($"{Xvel2:0.######}:{Yvel2:0.######}", Color.Red); - TickerText($"{Xvel1 + Xvel2:0.######}:{Yvel1 + Yvel2:0.######}", Color.Red); - switch (mode) - { - case 0: - Xpos2 = Math.Abs(Xmid - Xpos); - if (Xpos2 > 0x48) - { - Xpos2 = (0x60 - Xpos2) << 1; - Ypos2 = Ymid + Xpos2; - } - else - { - Ypos2 = Ymid - (Xpos2 >> 1) + 0x60; - } - DrawBoxMWH(Xpos, Ypos2, 1, 1, Color.Gray, 0); - DrawBoxMWH(Xpos, 112 + _top, 72, 224, (modeTimer <= 1) ? Color.Orange : Color.Gray, 0); - break; - case 1: - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Orange, 0); - Xpos2 = Mem.ReadS32(0xFFAA1A) - Mem.ReadS32(curObj + 0x24); - Ypos2 = Mem.ReadS32(0xFFAA1E) - Mem.ReadS32(curObj + 0x28); - var dSml = Math.Abs(Xpos2); - var dBig = Math.Abs(Ypos2); - if (dBig < dSml) - { - dSml ^= dBig; - dBig ^= dSml; - dSml ^= dBig; - } - var rad = (dBig + (dSml >> 1) - (dSml >> 3)) / 65536.0; - Xpos2 = (int)(Xpos2 * (256.0 / (rad+1))) >> 20; - Ypos2 = (int)(Ypos2 * (256.0 / (rad+1))) >> 20; - Gui.DrawLine(Xmid, Ymid, Xmid + Xpos2, Ymid + Ypos2, Color.Gray); - TickerText($"{Xpos2 / 512.0:0.######}:{Ypos2 / 512.0:0.######}", Color.Red); - break; - case 2: - TickerText($"{Mem.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); - break; - } - } - else if ((type == 0xC57A6) || (type == 0xDEE3C) || (type == 0xDF8A0) || (type == 0xDFA98) - || (type == 0xA0BE4) || (type == 0x9FEB2) || (type == 0xA5670) || (type == 0xAEC1A) - || (type == 0xA6C4A) || (type == 0xAB65A) || (type == 0x9F2EC)) { } - else - { - PutText($"{type:X5}:{Mem.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.Lime, Color.Blue); - PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.Lime, Color.Blue); - } - colltype = Mem.ReadS8(curObj + 0x7E); - switch (colltype) - { - case 0x10: - case 0x2D: - case 0x2E: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x11: - Xmid = (Xpos + Xpos2) >> 1; - Xpos2 = Xmid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x12: - Xmid = (Xpos + Xpos2) >> 1; - Xpos = Xmid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x13: - Ymid = (Ypos + Ypos2) >> 1; - Ypos = Ymid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x14: - Ymid = (Ypos + Ypos2) >> 1; - Ypos2 = Ymid; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - break; - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xmid, Ypos2, Xpos2, Ymid, Color.PowderBlue); - break; - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - case 0x1E: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos2, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos, Ymid, Xmid, Ypos2, Color.PowderBlue); - break; - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos, Ymid, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xpos, Ymid, Xmid, Ypos, Color.PowderBlue); - break; - case 0x24: - case 0x25: - case 0x26: - case 0x27: - case 0x28: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - DrawEccoTriangle(Xmid, Ymid, Xmid, Ypos, Xpos2, Ymid, Color.FromArgb(63, Color.Yellow)); - Gui.DrawLine(Xmid, Ypos, Xpos2, Ymid, Color.PowderBlue); - break; - case 0x2A: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Black)); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos, Color.Black); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos2, Color.Black); - break; - case 0x2B: - Xmid = (Xpos + Xpos2) >> 1; - Ymid = (Ypos + Ypos2) >> 1; - Point[] trapPoints = - { - new Point(Xpos, Ymid), - new Point(Xpos + (Ymid - Ypos >> 1), Ypos), - new Point(Xpos2 - (Ymid - Ypos >> 1), Ypos), - new Point(Xpos2, Ymid) - }; - Gui.DrawPolygon(trapPoints, Color.PowderBlue, Color.FromArgb(63, Color.PowderBlue)); - break; - case 0x2C: - break; - default: - DrawEccoRhomb_scaled(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x44), (colltype & 1), (colltype & 2) >> 1, (colltype & 4) >> 2, (colltype & 8) >> 3, Color.PowderBlue); - break; - } - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - curObj = Mem.ReadU24(curObj+1); - } - //animate objects - if (_mode == Modes.Ecco2) - curObj = Mem.ReadU24(0xFFCFB9); - else - curObj = Mem.ReadU24(0xFFD829); - while (curObj != 0) - { - type = 0; - switch (_mode) { - case Modes.Ecco2: - { - uint flags = Mem.ReadU16(curObj + 0x10); - int Xvec = 0; - int Yvec = 0; - //if ((flags & 0x2000) || !(flags & 2)); - HP = Mem.ReadS8(curObj + 0x7B); - type = Mem.ReadU32(curObj + 0xC); - if ((type == 0xA1FE6) || (type == 0xA208E) // Chain link creatures such as vortex worm, magic arm, etc - || (type == 0xA2288) || (type == 0xA27A4) || (type == 0xA2BB0) || (type == 0xA2C50)) - { - uint subObj = curObj; - while (subObj != 0) - { - Xpos = Mem.ReadS32(subObj + 0x24); - Ypos = Mem.ReadS32(subObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(subObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(subObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - if (Mem.ReadS16(subObj + 0x44) == Mem.ReadS16(subObj + 0x48)) - { - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.Cyan, 0); - } - else - { - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.Lime, 0); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x48), Color.Blue, 0); - } - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - subObj = Mem.ReadU24(subObj + 5); - } - if (HP > 2) - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); - } - } - else if ((type == 0xB7486) || (type == 0xB864E) //Chain link creatures such as eels and worms - || (type == 0xB8A64) || (type == 0xB8C1A) - || (type == 0xB904A) || (type == 0xB9728) || (type == 0xB9B6A) || (type == 0xBA52E) - || (type == 0xBA66E) || (type == 0xE0988) || (type == 0xA18E2) || (type == 0xE069A)) - { - uint subObj = curObj; - while (subObj != 0) - { - Xpos = Mem.ReadS32(subObj + 0x24); - Ypos = Mem.ReadS32(subObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(subObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(subObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - if (Mem.ReadS16(subObj + 0x44) == Mem.ReadS16(subObj + 0x48)) - { - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.White, 0); - } - else - { - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x44), Color.Lime, 0); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x48), Color.FromArgb(255, 0, 127)); - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(subObj + 0x48), Color.Magenta, 0); - } - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - if (type == 0xBA66E) - { - DrawEccoOct(Xpos, Ypos, 32, Color.Blue, 16); - if (subObj == curObj) - { - var mode = Mem.ReadByte(subObj + 0x15); - TickerText($"{Mem.ReadByte(subObj + 0x14)}:{mode}:{Mem.ReadByte(subObj + 0x70)}", Color.Red); - TickerText($"{Mem.ReadS32(subObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); - TickerText($"{Mem.ReadS32(subObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(subObj + 0x50) / 65536.0:0.######}", Color.Red); - switch (mode) - { - case 0: - case 2: - case 4: - Xpos2 = Mem.ReadS32(0xFFAA22) - Mem.ReadS32(subObj + 0x24); - Ypos2 = Mem.ReadS32(0xFFAA26) - Mem.ReadS32(subObj + 0x28); - var dSml = Math.Abs(Xpos2); - var dBig = Math.Abs(Ypos2); - if (dBig < dSml) - { - dSml ^= dBig; - dBig ^= dSml; - dSml ^= dBig; - } - var rad = (dBig + (dSml >> 1) - (dSml >> 3)) / 65536.0; - Xpos2 = (int)(Xpos2 * (256.0 / (rad + 1))) >> 20; - Ypos2 = (int)(Ypos2 * (256.0 / (rad + 1))) >> 20; - Gui.DrawLine(Xpos, Ypos, Xpos + Xpos2, Ypos + Ypos2, Color.Red); - break; - default: - break; - - } - } - } - else if ((type == 0xBA52E) && (subObj == Mem.ReadU24(curObj + 0x1D))) - { - DrawEccoOct(Xpos, Ypos, 32, (Mem.ReadByte(subObj + 0x70) == 0) ? Color.Blue : Color.Gray, 16); - var mode = Mem.ReadByte(curObj + 0x15); - TickerText($"{Mem.ReadByte(curObj + 0x14)}:{mode}:{Mem.ReadS16(curObj + 0x6E)}:{Mem.ReadByte(subObj + 0x70)}", Color.Red); - TickerText($"{Mem.ReadS32(subObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(subObj + 0x58) / 65536.0:0.######}", Color.Red); - TickerText($"{Mem.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Red); - } - else if (type == 0xE0988) - { - DrawEccoOct(Xpos, Ypos, 48, Color.FromArgb(64, Color.Blue), 16); - } - if (HP > 2) - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); - } - subObj = Mem.ReadU24(subObj + 5); - } - } - else if (type == 0xB7DF4) - { - Xpos = Mem.ReadS32(curObj + 0x24); - Ypos = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, 26, Color.PowderBlue); - DrawEccoOct(Xpos, Ypos, 26, Color.White); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec); - } - else if (type == 0xE47EE) - { - uint subObj = Mem.ReadU24(curObj + 5); - while (subObj != 0) - { - Xpos = Mem.ReadS32(subObj + 0x1C); - Ypos = Mem.ReadS32(subObj + 0x20); - Xvec = ((Xpos + Mem.ReadS32(subObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(subObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, ((Mem.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.White); - DrawEccoOct(Xpos, Ypos, ((Mem.ReadS16(subObj + 0x2C) & 0xFFFF) >> 1) + 16, Color.Yellow, 0); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - subObj = Mem.ReadU24(subObj + 5); - } - } - else if (type == 0xDBE64) // Medusa Boss - { - uint subObj = curObj; - uint next; - do - { - next = Mem.ReadU24(subObj + 5); - if (next != 0) subObj = next; - } while (next != 0); - Xpos = Mem.ReadS16(subObj + 0x2C); - Xpos2 = Mem.ReadS16(subObj + 0x34); - Ypos = Mem.ReadS16(subObj + 0x30); - Ypos2 = Mem.ReadS16(subObj + 0x38); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - DrawEccoOct(Xpos, Ypos, 32, Color.Red); - DrawEccoOct(Xpos2, Ypos2, 32, Color.Red); - Xpos = Mem.ReadS32(curObj + 0x24); - Ypos = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - var octOff = (int)(Math.Sqrt(2) * 60) >> 1; - Point[] hemiOctPoints = - { - new Point(Xpos - 60, Ypos), - new Point(Xpos - octOff, Ypos - octOff), - new Point(Xpos, Ypos - 60), - new Point(Xpos + octOff, Ypos - octOff), - new Point(Xpos + 60, Ypos) - }; - Gui.DrawPolygon(hemiOctPoints, Color.Cyan, Color.FromArgb(0x3F, Color.Cyan)); - for (int l = 0; l < 4; l++) - { - Gui.DrawLine(hemiOctPoints[l].X, hemiOctPoints[l].Y, hemiOctPoints[l + 1].X, hemiOctPoints[l + 1].Y, Color.Cyan); - } - DrawBoxMWH(Xpos, Ypos + 12, 52, 12, Color.Cyan); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - } - else if (type == 0xDCEE0) // Globe Holder boss - { - uint subObj; - var mode = Mem.ReadByte(curObj + 0x15); - if (mode < 4) - { - subObj = Mem.ReadU24(curObj + 9); - while (subObj != 0) - { - Xmid = Mem.ReadS32(subObj + 0x24); - Ymid = Mem.ReadS32(subObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(subObj + 0x54) + Mem.ReadS32(subObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(subObj + 0x58) + Mem.ReadS32(subObj + 0x60)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawEccoOct(Xmid, Ymid, 12, Color.Orange); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - var next = Mem.ReadU24(subObj + 9); - if ((next == 0) && ((mode & 1) != 0)) - { - DrawEccoOct(Xmid, Ymid, Mem.ReadS16(subObj + 0x3C), Color.Orange); - } - subObj = Mem.ReadU24(subObj + 9); - } - subObj = Mem.ReadU24(curObj + 5); - while (subObj != 0) - { - Xmid = Mem.ReadS32(subObj + 0x24); - Ymid = Mem.ReadS32(subObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(subObj + 0x54) + Mem.ReadS32(subObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(subObj + 0x58) + Mem.ReadS32(subObj + 0x60)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawEccoOct(Xmid, Ymid, 12, Color.Orange); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - var next = Mem.ReadU24(subObj + 5); - if ((next == 0) && ((mode & 2) != 0)) - { - DrawEccoOct(Xmid, Ymid, Mem.ReadS16(subObj + 0x3C), Color.Orange); - } - subObj = Mem.ReadU24(subObj + 5); - } - } - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - int Xtmp = Mem.ReadS32(curObj + 0x2C); - int Ytmp = Mem.ReadS32(curObj + 0x30); - int Xtmp2 = Mem.ReadS32(curObj + 0x34); - int Ytmp2 = Mem.ReadS32(curObj + 0x38); - Xpos = (Xtmp >> 16) - _camX; Xpos2 = (Xtmp2 >> 16) - _camX; - Ypos = (Ytmp >> 16) - _camY; Ypos2 = (Ytmp2 >> 16) - _camY; - Xvec = ((Mem.ReadS32(curObj + 0x24) + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Mem.ReadS32(curObj + 0x28) + +Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - if (mode < 7) - { - double overlap = 0; - DrawEccoOct(Xmid, Ymid, 0x5C, Mem.ReadByte(curObj + 0x7C) == 0 ? Color.Blue : Color.Gray); - DrawEccoOct(Xmid, Ymid, 0x5C, Color.Cyan, 0); - Xvec = (Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)); - Yvec = (Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)); - subObj = Mem.ReadU24(curObj + 0x69); - if (subObj != 0) - { - Xpos = Mem.ReadS32(subObj + 0x2C); - Ypos = Mem.ReadS32(subObj + 0x30); - Xpos2 = Mem.ReadS32(subObj + 0x34); - Ypos2 = Mem.ReadS32(subObj + 0x38); - while ((Xtmp > Xpos) && (Xtmp2 < Xpos2) && (Ytmp > Ypos) && (Ytmp2 < Ypos2) && ((Xvec != 0) || (Yvec != 0))) - { - Xtmp += Xvec; Xtmp2 += Xvec; - Ytmp += Yvec; Ytmp2 += Yvec; - } - overlap = Math.Max(Math.Max(Xpos - Xtmp, Xtmp2 - Xpos2), Math.Max(Ypos - Ytmp, Ytmp2 - Ypos2)) / 65536.0; - Xpos >>= 16; Xpos2 >>= 16; - Ypos >>= 16; Ypos2 >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, (overlap >= 6) ? Color.Orange : Color.White, 0); - } - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, (overlap >= 6) ? Color.Orange : Color.White, (overlap >= 6) ? 63 : 0); - if (mode < 4) - { - Xmid = Mem.ReadS16(curObj + 0x4C) - _camX; - Ymid = Mem.ReadS16(curObj + 0x50) - _camY; - if ((mode & 1) == 0) DrawEccoOct(Xmid, Ymid - 0xAE, 32, Color.Orange); - if ((mode & 2) == 0) DrawEccoOct(Xmid, Ymid + 0xAE, 32, Color.Orange); - } - TickerText($"{mode}:{Mem.ReadByte(curObj + 0x7F)}:{Mem.ReadByte(curObj + 0x6D)}:{Mem.ReadByte(curObj + 0x7C)}", Color.Red); - } - else if (mode == 8) - { - DrawEccoOct(Xmid - 16, Ymid - 16, 12, Color.Red); - } - } - else if (type == 0xE1BA2) // Vortex Queen Boss - { - var vulnCount = Mem.ReadByte(curObj + 0x7F); - var state = Mem.ReadByte(curObj + 0x7C); - var stateCounter = Mem.ReadU16(curObj + 0x6E); - var mode = Mem.ReadU16(curObj + 0x64); - var modeCounter = Mem.ReadU16(curObj + 0x66); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x40); - Xvec = Xmid + Mem.ReadS32(curObj + 0x54); - Yvec = Ymid + Mem.ReadS32(curObj + 0x58); - Xvec >>= 16; Yvec >>= 16; - Xmid >>= 16; Ymid >>= 16; - Xvec -= _camX; Yvec -= _camY; - Xmid -= _camX; Ymid -= _camY; - if (mode < 5) - { - var octOff = (int)(80 * Math.Sqrt(2)) >> 1; - Point hexOff = Intersection(new Point(-80, 0), new Point(-octOff, -octOff), new Point(-80, -32), new Point(-octOff, -32)).Value; - Point[] roundedRect = { - new Point(Xmid - 80, Ymid), - new Point(Xmid + hexOff.X, Ymid - 32), - new Point(Xmid - hexOff.X, Ymid - 32), - new Point(Xmid + 80, Ymid), - new Point(Xmid - hexOff.X, Ymid + 32), - new Point(Xmid + hexOff.X, Ymid + 32) - }; - Gui.DrawPolygon(roundedRect, Color.Orange, Color.FromArgb(63, Color.Orange)); - } - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - TickerText($"{state:X2}:{stateCounter}:{mode}:{modeCounter}:{Mem.ReadByte(curObj + 0x70) & 0xF}", Color.Red); - var subObj = Mem.ReadU24(curObj + 0x5); - var tongueMode = mode; - mode = Mem.ReadByte(subObj + 0x15); - modeCounter = Mem.ReadU16(subObj + 0x6E); - Xmid = Mem.ReadS32(subObj + 0x24); - Ymid = Mem.ReadS32(subObj + 0x40); - Xvec = (Xmid + Mem.ReadS32(subObj + 0x5C) >> 16) - _camX; - Yvec = (Ymid + Mem.ReadS32(subObj + 0x60) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Ymid -= 32; Yvec -= 32; - var levelHeight = Mem.ReadS16(0xFFA7AC) - _camY; - switch (mode) - { - case 0: - DrawBox(Xmid - 32, Ymid - ((state == 5) ? 0x60 : 0x70), Xmid + 32, Ymid - 16, Color.Red); - break; - case 2: - Ypos = Mem.ReadS16(subObj + 0x50) - _camY; - Gui.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); - DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); - break; - case 3: - modeCounter = Mem.ReadByte(subObj + 0x7C); - break; - case 5: - Point[] throatShape = - { - new Point(Xmid - 48, levelHeight), - new Point(Xmid - 48, Ymid + 60), - new Point(Xmid - 16, Ymid + 20), - new Point(Xmid + 16, Ymid + 20), - new Point(Xmid + 48, Ymid + 60), - new Point(Xmid + 48, levelHeight) - }; - Gui.DrawPolygon(throatShape, Color.Red, Color.FromArgb(63, Color.Red)); - DrawEccoOct(Xmid, Ymid, 24, Color.Red); - DrawEccoOct(Xmid, Ymid, 24, Color.White, 0); - break; - case 6: - if ((state != 7) && (vulnCount == 0) && (tongueMode != 7)) - { - DrawEccoOct(Xmid, Ymid + 16, 64, Color.Blue); - } - if (tongueMode == 7) - { - uint subObj2 = Mem.ReadU24(0xFFCFCD); - while (subObj2 != 0) - { - if (Mem.ReadU16(subObj2 + 0x10) == 0xFF) - { - Xpos = Mem.ReadS16(subObj2 + 0x24) - _camX; - Ypos = Mem.ReadS16(subObj2 + 0x28) - _camY; - Xpos2 = ((Mem.ReadS32(subObj2 + 0x24) + Mem.ReadS32(subObj2 + 0x54)) >> 16) - _camX; - Ypos2 = ((Mem.ReadS32(subObj2 + 0x28) + Mem.ReadS32(subObj2 + 0x58)) >> 16) - _camY; - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); - } - subObj2 = Mem.ReadU24(subObj2 + 1); - } - } - Ypos = Mem.ReadS16(subObj + 0x50) - _camY; - Gui.DrawLine(Xmid - 48, Ypos - 94, Xmid + 48, Ypos - 94, Color.Orange); - Gui.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); - DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); - break; - default: - break; - } - if ((mode < 7) || ((mode == 7) && (Mem.ReadU24(0xFFCFC9) != 0))) - { - if (Mem.ReadByte(subObj + 0x70) == 0) - { - DrawEccoOct(Xmid, Ymid, 32, Color.Red); - DrawBox(Xmid - 48, Ymid + 32, Xmid + 48, levelHeight, Color.Red); - } - Ypos = Mem.ReadS16(subObj + 0x50) - _camY - 94; - Gui.DrawLine(Xmid - 48, Ypos, Xmid + 48, Ypos, Color.Orange); - DrawBoxMWH(Xmid, Ymid + 32, 1, 1, Color.Orange, 0); - } - if (Mem.ReadS32(subObj + 0xC) == 0xE17B4) - { - Point[] shapePoints = - { - new Point(Xmid - 48, levelHeight), - new Point(Xmid - 48, Ymid + 60), - new Point(Xmid - 16, Ymid + 20), - new Point(Xmid + 16, Ymid + 20), - new Point(Xmid + 48, Ymid + 60), - new Point(Xmid + 48, levelHeight) - }; - Gui.DrawPolygon(shapePoints, Color.Red, Color.FromArgb(63, Color.Red)); - DrawEccoOct(Xmid, Ymid, 24, Color.Red); - DrawEccoOct(Xmid, Ymid, 24, Color.White, 0); - } - Ypos = (Mem.ReadS16(subObj + 0x50) - _camY) - 264; - DrawBoxMWH(160 + _left, Ypos, 320, 12, (32 < stateCounter) && (stateCounter < 160) ? Color.Brown : Color.Gray); - if ((32 < stateCounter) && (stateCounter < 160)) - { - DrawBoxMWH(_left + 160, Ypos, 320, 12, Color.White, 0); - } - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - TickerText($"{mode:X2}:{modeCounter}:{HP}:{vulnCount}", Color.Red); - HP = 0; - } - else if (type == 0xA5BD2) // Telekinetic future dolphins - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); - DrawEccoOct(Xmid, Ymid, 4, Color.Red); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0x9F5B0) || (type == 0x9F4DC) || (type == 0x9F6A0)) // Falling rock, breaks barriers - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - if (type == 0x9F6A0) - { - int width = Mem.ReadS16(curObj + 0x44) << 1; - DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); - } - TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); - } - else if (type == 0xA3B18) - { - Xpos = Mem.ReadS32(curObj + 0x24); - Ypos = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(curObj + 0x44), Color.Yellow); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - } - else if (type == 0xA4018) - { - Xpos = Mem.ReadS32(curObj + 0x24); - Ypos = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; - Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, Mem.ReadS16(curObj + 0x44), Color.Gray); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - } - else if (type == 0xA091E) // Blue Whale - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Xpos = Xmid; Ypos = Ymid; - Ymid -= 64; Yvec -= 64; - DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x50, Color.Red, 31); - DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x40, Color.Red, 31); - DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x30, Color.Red, 31); - DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x20, Color.Red, 31); - DrawEccoOct_scaled(Xmid, Ymid, 2, 0, 0x10, Color.Red, 31); - if (Mem.ReadByte(curObj + 0x7F) == 0) - { - Xpos += (Mem.ReadS16(curObj + 0x6E) == 0) ? -278 : 162; - Ypos += 44 - Mem.ReadS16(curObj + 0x48); - DrawEccoOct(Xpos, Ypos, 32, Color.Blue); - } - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - - } - else if (type == 0xE66D8) //Vortex Larva - { - uint subObj = Mem.ReadU24(curObj + 5); - while (subObj != 0) - { - Xpos = Mem.ReadS16(subObj + 0x1C); - Ypos = Mem.ReadS16(subObj + 0x20); - Xpos2 = Mem.ReadS16(subObj + 0x24); - Ypos2 = Mem.ReadS16(subObj + 0x28); - Xpos -= _camX; Ypos -= _camY; - Xpos2 -= _camX; Ypos2 -= _camY; - DrawEccoOct(Xpos, Ypos, 30, Color.White, 32); - DrawEccoOct(Xpos, Ypos, 30, Color.Yellow, 0); - DrawEccoOct(Xpos2, Ypos2, 30, Color.White, 32); - DrawEccoOct(Xpos2, Ypos2, 30, Color.Yellow, 0); - subObj = Mem.ReadU24(subObj + 5); - } - Xpos = Mem.ReadS32(curObj + 0x24); - Ypos = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xpos + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ypos + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xpos2 = Mem.ReadS16(curObj + 0x72) - _camX; - Ypos2 = Mem.ReadS16(curObj + 0x76) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; Ypos -= _camY; - DrawEccoOct(Xpos, Ypos, 0xB0, Color.Yellow); - DrawEccoOct(Xpos, Ypos, 0xB0, Color.Red, 0); - DrawEccoOct(Xpos, Ypos, 0x70, Color.Red); - DrawEccoOct(Xpos, Ypos, 0x38, Color.White); - DrawEccoOct(Xpos, Ypos, 0x38, Color.Red, 0); - DrawEccoOct(Xpos, Ypos, 48, Color.Blue, ((Mem.ReadByte(curObj + 0x7B) > 2) && (Mem.ReadByte(curObj + 0x14) != 0)) ? 63 : 0); - DrawEccoOct(Xpos2, Ypos2, 32, Color.Orange); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); - TickerText($"{Mem.ReadByte(curObj + 0x14):X2}:{Mem.ReadByte(curObj + 0x7B):X2}:{Mem.ReadS16(curObj + 0x6E):D2}", Color.Red); - TickerText($"{ Mem.ReadByte(curObj + 0x7C):X2}:{Mem.ReadS16(curObj + 0x18):D3}", Color.Red); - TickerText($"{(Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C))/65536.0:0.######}:{(Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) / 65536.0:0.######}", Color.Red); - - } - else if (type == 0x9CE3A) //Remnant Stars - { - flags = Mem.ReadU16(curObj + 0x10); - uint subObj = Mem.ReadU24(curObj + 0x5); - uint anim = Mem.ReadU16(curObj + 0x6C); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - if ((anim <= 7) && (subObj == 0xFFA9D4)) - { - DrawEccoRhomb(Xmid, Ymid, 96, Color.Red); - PutText($"{((7 - anim) * 4) - ((Mem.ReadByte(0xFFA7C9) & 3) - 4)}", Xmid, Ymid + 4, 1, 1, -1, -1, Color.Blue, Color.Red); - - } - } - else if (type == 0xA997C) // Vortex Soldier - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = (Xmid + Mem.ReadS32(curObj + 0x54) >> 16) - _camX; - Yvec = (Ymid + Mem.ReadS32(curObj + 0x58) >> 16) - _camY; - Xvec += Mem.ReadS16(curObj + 0x64); - Yvec += Mem.ReadS16(curObj + 0x66); - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - if (Mem.ReadByte(curObj + 0x7A) == 0) - { - DrawRectRhombusIntersection(new Point(Xmid, Ymid + 6), new Point(Xmid, Ymid), 50, 44, 64, Color.Red); - } - DrawRectRhombusIntersection(new Point(Xmid, Ymid - 25), new Point(Xmid, Ymid), 38, 47, 64, Color.Red); - DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.Blue, 16); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xA6C4A) || (type == 0xC43D4)) // Barrier Glyphs - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - var subType = Mem.ReadByte(curObj + 0x13); - if ((Mem.ReadU8(curObj + 0x7A) == 0) && (Mem.ReadU8(0xFFA7B5) != 0) - && ((type != 0xA6C4A) || (subType == 0x14) || (subType == 0x97))) - { - DrawEccoOct(Xmid, Ymid, 70, Color.Red); - } - DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.Blue); - DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.PowderBlue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xB4F46) || (type == 0xB4E1C) || (type == 0xB4C18) || (type == 0xB4ACC) || (type == 0xB4B72)) // Guiding Orca/Dolphin - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - int Xdst = Mem.ReadS16(curObj + 0x64); - Xdst <<= 7; - Xdst = Xdst + 0x40 - _camX; - int Ydst = Mem.ReadS16(curObj + 0x66); - Ydst <<= 7; - Ydst = Ydst + 0x40 - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - Gui.DrawLine(Xmid, Ymid, Xdst, Ydst, Color.Orange); - DrawBoxMWH(Xdst, Ydst, 64, 64, Color.Orange); - TickerText($"{Mem.ReadS16(curObj + 0x24)}:{Mem.ReadS16(curObj + 0x28)}:{Mem.ReadByte(curObj + 0x7D)}:{Mem.ReadByte(curObj + 0x7A)}", Color.Lime); - TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); - TickerText($"{Mem.ReadS32(curObj + 0x72) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x76) / 65536.0:0.######}", Color.Lime); - } - else if (type == 0xB5938) // Lost Orca - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - //DrawBoxMWH(Xmid, Ymid, 64, 32, Color.Lime); - if (Mem.ReadU16(curObj + 0x6E) == 0) - { - if (Mem.ReadByte(curObj + 0x7D) == 0) - { - DrawBox(Xmid + 8, Ymid - 32, Xmid + 64, Ymid + 32, Color.Red); - } - else - { - DrawBox(Xmid - 64, Ymid - 32, Xmid - 8, Ymid + 32, Color.Red); - } - } - Gui.DrawLine(Xpos - 80, Ymid, Xpos + 80, Ymid, Color.Green); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xB552A) || (type == 0xB5C42) || (type == 0xB5AFE)) // Following Orca, Returning Orca, & Idling Orca - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xB624A) // Orca Mother - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - int height = Mem.ReadS16(curObj + 0x48) + 32; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 80, 32, Color.Red, 31); - DrawBoxMWH(Xmid, Ymid, Mem.ReadS16(curObj + 0x44), Mem.ReadS16(curObj + 0x48), Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - if (Mem.ReadS32(0xFFAB7E) != 0) - { - DrawEccoOct(Xmid, Ymid, 0x50, Color.Red, 31); - } - } - else if (type == 0xC047E) - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - var width = 2; - var height = 2; - if (Mem.ReadByte(curObj + 0x15) == 0) - { - width = Mem.ReadS16(curObj + 0x44); - height = Mem.ReadS16(curObj + 0x48); - } - DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); - } - else if (type == 0xC056E) - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - var width = Mem.ReadS16(curObj + 0x44); - var height = Mem.ReadS16(curObj + 0x48); - DrawBoxMWH(Xmid, Ymid, width, height, Color.Lime); - } - else if (type == 0xC4208) // Broken Glyph Base - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - var width = Mem.ReadS16(curObj + 0x44); - var height = Mem.ReadS16(curObj + 0x48); - DrawBoxMWH(Xmid, Ymid, width, height, Color.PowderBlue); - if (Mem.ReadByte(curObj + 0x15) == 0) - { - DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 80, 80, 120, Color.Orange); - } - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xAC242) // Broken Glyph Top repairing - { - uint subObj = Mem.ReadU24(curObj + 0x5); - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - Xpos = Mem.ReadS16(subObj + 0x24) - _camX; - Ypos = Mem.ReadS16(subObj + 0x28) - _camY; - var width = Mem.ReadS16(curObj + 0x44); - var height = Mem.ReadS16(curObj + 0x48); - DrawBoxMWH(Xmid, Ymid, width, height, Color.Gray); - Point[] rhombPoints = - { - new Point(Xpos - 3, Ypos), - new Point(Xpos, Ypos - 3), - new Point(Xpos + 3, Ypos), - new Point(Xpos, Ypos + 3) - }; - Gui.DrawPolygon(rhombPoints, Color.Orange, Color.FromArgb(63, Color.Orange)); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); - } - else if (type == 0xBE9C8) // Broken Glyph Top free - { - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Lime); Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xD9C0E) || (type == 0xDA9EA)) - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawBoxMWH(Xmid, Ymid, 0xA0, 0x70, Color.Red); - } - else if ((type == 0xBF204) || (type == 0xDA2C0)) - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xAF9CC) // Mirror Dolphin - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xpos = Mem.ReadS16(curObj + 0x1C) - _camX + (Mem.ReadByte(curObj + 0x15) == 0 ? 27 : -27); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54) + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58) + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - var width = Mem.ReadS16(curObj + 0x44); - var height = Mem.ReadS16(curObj + 0x48); - DrawBoxMWH(Xmid, Ymid, width, height, Color.Blue, 31); - if (Mem.ReadByte(curObj + 0x13) != 0xAC) - { - DrawBoxMWH(Xmid, Ymid, 96, 96, Color.Orange); - } - Gui.DrawLine(Xpos, 0, Xpos, 448, Color.Red); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xAF43E) // Vortex Lightning Trap - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - if (Mem.ReadByte(curObj + 0x15) != 0) - { - if (Mem.ReadS16(0xFFAA12) != 0) - { - Ymid -= 8; - } - DrawBoxMWH(Xmid, Ymid, 92, 16, Color.Red); - PutText(Mem.ReadByte(curObj + 0x15).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); - } - else - { - DrawBoxMWH(Xmid, Ymid, 92, 16, Color.Gray); - PutText(Mem.ReadByte(curObj + 0x7F).ToString(), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); - } - } - else if (type == 0xA6E24) // Barrier Glyph Forcefield - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = Mem.ReadS32(0xFFAA1A) - Xmid; - Yvec = Mem.ReadS32(0xFFAA1E) - Ymid; - var div = Math.Abs(Xvec) + Math.Abs(Yvec); - Xvec /= div; Yvec /= div; - Xvec += Xmid; Yvec += Ymid; - Xmid >>= 16; Ymid >>= 16; - Xvec >>= 16; Yvec >>= 16; - Xmid -= _camX; Ymid -= _camY; - Xvec -= _camX; Yvec -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xC4A44) || (type == 0xAA32C)) // Pulsar power-up and Vortex bullet-spawner - { - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue, 16); - } - else if (type == 0xC2F00) // Sky bubbles - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - var mode = Mem.ReadByte(curObj + 0x15); - switch (mode) - { - case 0: - DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 70, 70, 105, Color.Gray); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - break; - case 1: - DrawRectRhombusIntersection(new Point(Xmid, Ymid), new Point(Xmid, Ymid), 70, 70, 105, Color.Red); - break; - case 2: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); - break; - default: - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Gray); - break; - } - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0x9FA7E) //Air refiller/drainer - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Lime)); - } - else if (type == 0xBFC14) //Pushable fish - { - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - TickerText($"{Mem.ReadS32(curObj + 0x54) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x58) / 65536.0:0.######}", Color.Orange); - - } - else if ((type == 0xBE97C) //Slowing Kelp //Default Bounds nose-responsive - || (type == 0xACDAE)) //Metasphere - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xACB42) // Turtle - { - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - var mode = Mem.ReadByte(curObj + 0x15); - switch (mode) - { - case 0: - case 1: - case 2: - case 3: - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x4C)) >> 16) - _camX; - break; - case 4: - case 5: - case 6: - case 7: - Xvec = ((Xmid - Mem.ReadS32(curObj + 0x4C)) >> 16) - _camX; - break; - default: - Xvec = (Xmid >> 16) - _camX; - break; - } - Yvec = Ymid; - Xmid >>= 16; Xmid -= _camX; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - int width = Mem.ReadS16(curObj + 0x44) << 1; - DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); - TickerText($"{Mem.ReadS32(curObj + 0x4C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x50) / 65536.0:0.######}", Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xACA7E) // Retracting Turtle - { - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + (Mem.ReadS32(curObj + 0x4C) >> 1)) >> 16) - _camX; - Yvec = ((Ymid + (Mem.ReadS32(curObj + 0x50) >> 1)) >> 16) - _camY; - Xmid >>= 16; Xmid -= _camX; - Ymid >>= 16; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - int width = Mem.ReadS16(curObj + 0x44) << 1; - DrawBox(Xpos - width, Ypos - (width << 2), Xpos2 + width, Ypos2, Color.Lime); - TickerText($"{(Mem.ReadS32(curObj + 0x4C) >> 1) / 65536.0:0.######}:{(Mem.ReadS32(curObj + 0x50) >> 1) / 65536.0:0.######}", Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xB5134) || (type == 0xA7E0C) //Default Bounds sonar-responsive - || (type == 0xAF868) || (type == 0xAF960) || (type == 0xD8E5C) || (type == 0xAA5C6)) - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if ((type == 0xACCB4) || (type == 0xACD7E) //Default Baunds non-responsive - || (type == 0xD8D96) || (type == 0xA955E) || (type == 0xA92E4) || (type == 0xC05DC) - || (type == 0xC2684)) - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Gray); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0x9DE86) // Star Wreath - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Xpos = Mem.ReadS32(curObj + 0x1C); - Ypos = Mem.ReadS32(curObj + 0x20); - Xpos2 = ((Xpos + Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Ypos2 = ((Ypos + Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; Ypos -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - DrawBoxMWH(Xpos, Ypos, 1, 1, (Mem.ReadByte(curObj + 0x7F) == 0) ? Color.Blue : Color.Black, 0); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); - if (Mem.ReadByte(curObj + 0x12) % 7 == 0) - { - TickerText($"{Mem.ReadS32(curObj + 0x5C) / 65536.0:0.######}:{Mem.ReadS32(curObj + 0x60) / 65536.0:0.######}:{Mem.ReadByte(curObj + 0x7F)}", Color.Lime); - } - } - else if ((type == 0x9D774) || (type == 0x9DA26)) // Fish - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 0x14, 0x14, Color.Lime); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xAD87C) // Enemy dolphins in metamorph levels - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Mem.ReadS16(curObj + 0x1C) - _camX, Mem.ReadS16(curObj + 0x20) - _camY, 1024, 1024, Color.Orange, 0); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xC6128) // Drone attacking dolphin - { - Xmid = Mem.ReadS16(curObj + 0x4C) - _camX; - Ymid = Mem.ReadS16(curObj + 0x50) - _camY; - DrawEccoOct(Xmid, Ymid, 360, Color.Red, 0); - } - else if (type == 0xC605A) // Drone attacking dolphin sonar - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camY; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawBox(Xmid, Ymid - 1, Xmid + 32, Ymid + 1, Color.Orange); - } - else if (type == 0xB1BE0) // Globe - { - int mode = Mem.ReadS8(curObj + 0x15); - if (mode == 1) - { - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime, 0); - Gui.DrawLine(Xpos, Ypos2, Xpos2, Ypos, Color.Lime); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xB1A10) // Approaching globes - { - Xmid = Mem.ReadS16(0xFFAA1A) - _camX; - Ymid = Mem.ReadS16(0xFFAA1E) - _camY; - DrawEccoOct(Xmid - 56, Ymid, 8, Color.Orange); - DrawEccoOct(Xmid + 56, Ymid, 8, Color.Orange); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xpos = Mem.ReadS32(curObj + 0x4C); - Ypos = Mem.ReadS32(curObj + 0x50); - Xvec = ((Xmid - Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid - Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xpos2 = ((Xpos + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Ypos2 = ((Ypos + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Xpos >>= 16; Ypos >>= 16; - Xpos -= _camX; Ypos -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xpos2, Ypos2, Color.Orange); - } - else if (type == 0xB1920) // Orbiting globes - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xpos = Mem.ReadS16(curObj + 0x4C) - _camX; - Ypos = Mem.ReadS16(curObj + 0x50) - _camY; - Xvec = ((Xmid - Mem.ReadS32(curObj + 0x5C)) >> 16) - _camX; - Yvec = ((Ymid - Mem.ReadS32(curObj + 0x60)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - DrawBoxMWH(Xpos, Ypos, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xpos, Ypos, Xvec, Yvec, Color.Orange); - } - else if (type == 0xC28A0) // Control point in Four Islands/Dolphin that gives Rock-breaking song - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Mem.ReadByte(curObj + 0x15) == 0 ? Color.Orange : Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - // Crystal Springs merging glyphs - else if (type == 0xC651E) // Bound glyph - { - Xpos = Mem.ReadS16(curObj + 0x1C) - _camX; - Ypos = Mem.ReadS16(curObj + 0x20) - _camY; - DrawEccoRhomb(Xpos, Ypos, 4 << 4, Color.Orange); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xC67E4) // Freed glyph - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Blue); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xC6970) // Pulled glyph - { - uint subObj = Mem.ReadU24(curObj + 5); - Xvec = Mem.ReadS32(subObj + 0x54); - Yvec = Mem.ReadS32(subObj + 0x58); - for (i = 1; i < Mem.ReadByte(curObj + 0x7F); i++) - { - Xvec ^= Yvec; - Yvec ^= Xvec; - Xvec ^= Yvec; - Xvec = 0 - Xvec; - } - Xpos = (Xvec + Mem.ReadS32(subObj + 0x1C) >> 16) - _camX; - Ypos = (Yvec + Mem.ReadS32(subObj + 0x20) >> 16) - _camY; - DrawEccoRhomb(Xpos, Ypos, 3, Color.Orange); - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - } - else if (type == 0xC6BA8) // Delivery Point - { - Xvec = Mem.ReadS32(curObj + 0x54); - Yvec = Mem.ReadS32(curObj + 0x58); - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - for (i = 0; i < 4; i++) - { - Xpos = (Xvec + Mem.ReadS32(curObj + 0x1C) >> 16) - _camX; - Ypos = (Yvec + Mem.ReadS32(curObj + 0x20) >> 16) - _camY; - Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); - Xvec ^= Yvec; - Yvec ^= Xvec; - Xvec ^= Yvec; - Xvec = 0 - Xvec; - } - } - else if (type == 0xC6A6C) // Delivered glyph - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid - Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid - Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xC6F82) // Full delivery point - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawEccoOct(Xmid, Ymid, 3, Color.Orange); - } - else if (type == 0xC6A9E) // Merging glyph - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid - Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid - Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xC7052) { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS16(curObj + 0x24); - Ymid = Mem.ReadS16(curObj + 0x28); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - uint dropSpeed = Mem.ReadU8(curObj + 0x16); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xmid, Ymid + (int)(dropSpeed), Color.Orange); - } - else if ((type == 0xD8B7C) || (type == 0xD89EA) || (type == 0x9E3AA) || (type == 0x9E5A8) // GFX particles don't need displayed. - || (type == 0x9B5D8) || (type == 0x9E2A6) || (type == 0xACD1E) || (type == 0xD9678) - || (type == 0xD9A3C) || (type == 0xD9240) || (type == 0x9E1DE) || (type == 0xDF86A) - || (type == 0xB159A) || (type == 0xDA898) || (type == 0xDA720) || (type == 0xD9FDC) - || (type == 0xC0D4E) || (type == 0xC0D38) || (type == 0xDCDAC) || (type == 0xC0B42) - || (type == 0xE3CD2) || (type == 0xE385E) || (type == 0xC20E8) || (type == 0xC22A6) - || (type == 0xC31B4) || (type == 0xA9EF0) || (type == 0xA9D90) || (type == 0xC6304) - || (type == 0xC26E4) || (type == 0xAEE68) || (type == 0xD9B2A) || (type == 0xD95AE) - || (type == 0)) - { - // This space intentionally left blank - } - else if ((type == 0xC152C) || (type == 0xA75E8) //Objects with default bounds confirmed - || (type == 0x9D076) || (type == 0xA7092) || (type == 0xC02EA) || (type == 0xA5378) - || (type == 0xACA7E) || (type == 0x9D28C) || (type == 0xA2D42) || (type == 0xA975E) - || (type == 0xBE9C8) || (type == 0xBFDA4) || (type == 0xAC736) || (type == 0xB716E) - || (type == 0xB1BE0) || (type == 0xB1A10) || (type == 0x9E546) || (type == 0xC2CB8) - || (type == 0xA0F04) || (type == 0xA6ACA) || (type == 0xA35A6) || (type == 0xAA12E) - || (type == 0xC651E) || (type == 0x9CC06) || (type == 0xA9202) || (type == 0xA6FDE) - || (type == 0xA6F62) || (type == 0xA745C) || (type == 0xC3EF0) || (type == 0xC3F90) - || (type == 0xC3FFC) || (type == 0xC3DB8) || (type == 0xAC766) || (type == 0xC5F66) - || (type == 0xA306E) || (type == 0xB0C7E) || (type == 0xB17F2) || (type == 0xB0CDC) - || (type == 0xC2106) || (type == 0xC208C) || (type == 0xC1EBA) || (type == 0xC251C) - || (type == 0xC32C8) || (type == 0xAB5E6) || (type == 0xAC796) || (type == 0xAC9F2) - || (type == 0xA538A)) - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(255, 0, 127)); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); - if (type != 0xA975E) - { - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - if (HP > 2) - { - PutText($"{HP - 1}", Xmid, Ymid, 1, 1, -1, -9, Color.Blue, Color.Red); - } - } - else // Default bounds - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - PutText(type.ToString("X5"), Xmid, Ymid + 8, 1, 9, -1, -1, Color.Blue, Color.Red); - } - break; - } - case Modes.Ecco1: - type = Mem.ReadU32(curObj + 0x6); - Xpos = Mem.ReadS16(curObj + 0x17); - Xpos2 = Mem.ReadS16(curObj + 0x1F); - Ypos = Mem.ReadS16(curObj + 0x1B); - Ypos2 = Mem.ReadS16(curObj + 0x23); - Xmid = Mem.ReadS16(curObj + 0x0F); - Ymid = Mem.ReadS16(curObj + 0x13); - Xpos >>= 2; - Xpos2 >>= 2; - Ypos >>= 2; - Ypos2 >>= 2; - Xmid >>= 2; - Ymid >>= 2; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Lime); - PutText(type.ToString("X8"), Xmid, Ymid, 1, 1, -1, -1, Color.Blue, Color.Red); - break; - } - curObj = Mem.ReadU24(curObj+1); - } - //events - curObj = Mem.ReadU24(0xFFCFB5); - while (curObj != 0) - { - type = Mem.ReadU32(curObj + 0xC); - if ((type == 0) // Null object - || (type == 0x9C1FA) || (type == 0x9C6D0) // Skytubes BG Image manager - || (type == 0x9ED72) || (type == 0xA57F2) // And Miscellaneous GFX particles - || (type == 0xC3A42) || (type == 0xB33D8) // And Cutscene controller - || (type == 0xB308A) || (type == 0xA1676) || (type == 0xB6822) || (type == 0xD12E2)) { } - else if ((type == 0xA44EE) || (type == 0xD120C)) - { - Xmid = Mem.ReadS16(curObj + 0x1C) - _camX; - Ymid = Mem.ReadS16(curObj + 0x20) - _camY; - DrawEccoOct(Xmid, Ymid, 0x20, Color.Red); - } - else if (type == 0x9F0D0) // Water Current - { - int Xvec = Mem.ReadS32(curObj + 0x54); - int Yvec = Mem.ReadS32(curObj + 0x58); - if ((Xvec != 0) || (Yvec != 0)) - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - Xvec += Xmid; Yvec += Ymid; - Xmid >>= 16; Ymid >>= 16; - Xvec >>= 16; Yvec >>= 16; - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - Xvec -= _camX; Yvec -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63, Color.Red)); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - } - else if (type == 0xDEF94) - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawEccoOct(Xmid, Ymid, 0x18, Color.Cyan); - } - else if (type == 0xA6584) // Eagle - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawEccoOct(Xmid, Ymid, 0x10, Color.Red); - } - else if ((type == 0x9BA8A) // Autoscroller controller - || (type == 0xE27D4) || (type == 0xE270E) || (type == 0xE26C2)) - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - var Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - var Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Orange, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0x9B948) // Autoscroller waypoint - { - Xmid = Mem.ReadS32(curObj + 0x24); - Ymid = Mem.ReadS32(curObj + 0x28); - var Xvec = ((Xmid + Mem.ReadS32(curObj + 0x54)) >> 16) - _camX; - var Yvec = ((Ymid + Mem.ReadS32(curObj + 0x58)) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 8, 8, Color.Orange); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - else if (type == 0xA5448) // Bomb spawner - { - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - PutText($"{Mem.ReadU16(curObj + 0x6E)}", Xmid, Ymid, 1, 1, -1, -1, Color.White, Color.Blue); - } - else if ((type == 0xA529C) || (type == 0xA5236) || (type == 0xA51E6)) // Explosion - { - uint subObj = Mem.ReadU24(curObj + 5); - if (subObj != 0) - { - Xpos = Mem.ReadS16(subObj + 0x1C) - _camX; - Ypos = Mem.ReadS16(subObj + 0x28) - _camY; - int Width = Mem.ReadS16(subObj + 0x24) - Xpos - _camX; - DrawBoxMWH(Xpos, Ypos, Width, 16, Color.Red); - } - subObj = Mem.ReadU24(curObj + 9); - if (subObj != 0) - { - Xpos = Mem.ReadS16(subObj + 0x1C) - _camX; - Ypos = Mem.ReadS16(subObj + 0x28) - _camY; - int Width = Mem.ReadS16(subObj + 0x24) - Xpos - _camX; - DrawBoxMWH(Xpos, Ypos, Width, 16, Color.Red); - } - } - else if (type == 0x9B5D8) - { - var subtype = Mem.ReadByte(curObj + 0x13); - int width = 0; - int height = 0; - switch (subtype) - { - case 48: - case 49: - case 126: - case 145: - case 146: - case 213: - PutText($"{type:X5}:{subtype}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); - PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); - break; - case 59: - case 87: - case 181: - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - width = Mem.ReadS16(curObj + 0x44); - height = Mem.ReadS16(curObj + 0x48); - DrawEccoOct(Xmid, Ymid, (width + height) >> 1, Color.Lime); - break; - case 71: - case 72: - case 158: - case 159: - case 165: - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red); - break; - case 82: - case 83: - case 84: - case 85: - case 86: - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - width = Mem.ReadS16(curObj + 0x44); - height = Mem.ReadS16(curObj + 0x48); - DrawBoxMWH(Xmid, Ymid, width, height, Color.Red); - break; - case 210: - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - width = Mem.ReadS16(curObj + 0x44); - height = Mem.ReadS16(curObj + 0x48); - DrawBoxMWH(Xmid, Ymid, width, height, Color.Blue); - break; - case 107: - Xmid = (Mem.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; - Ymid = (Mem.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; - Xpos = (Mem.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; - Ypos = (Mem.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; - DrawBoxMWH(Xmid, Ymid, 64, 64, Color.Orange, 0); - DrawBoxMWH(Xpos, Ypos, 64, 64, Color.Orange, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); - break; - case 110: //Gravity conrol points - case 179: - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.FromArgb(63,Mem.ReadByte(curObj + 0x15) == 0 ? Color.Gray : Color.Red)); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); - int dir = Mem.ReadS8(curObj + 0x71) & 7; - int[] xtable = { 7, 4, -3, -10, -14, -11, -3, 4}; - int[] ytable = { 11, 4, 7, 4, -3, -11, -14, -11}; - Xmid = Mem.ReadS16(curObj + 0x24) - _camX; - Ymid = Mem.ReadS16(curObj + 0x28) - _camY; - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawImage(".\\dll\\gravitometer_bg.png", Xmid - 15, Ymid - 15); - Gui.DrawImage(".\\dll\\gravitometer_fg.png", Xmid + xtable[dir], Ymid + ytable[dir]); - break; - case 176: - Xmid = (Mem.ReadS16(curObj + 0x18) << 7) - _camX + 0x40; - Ymid = (Mem.ReadS16(curObj + 0x1A) << 7) - _camY + 0x40; - Xpos = (Mem.ReadS16(curObj + 0x64) << 7) - _camX + 0x40; - Ypos = (Mem.ReadS16(curObj + 0x66) << 7) - _camY + 0x40; - DrawEccoOct(Xmid, Ymid, 32, Color.Orange, 0); - DrawEccoOct(Xpos, Ypos, 32, Color.Orange, 0); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue, 0); - Gui.DrawLine(Xmid, Ymid, Xpos, Ypos, Color.Orange); - break; - case 194: // Kill plane - Xpos = Mem.ReadS16(curObj + 0x2C) - _camX; - Xpos2 = Mem.ReadS16(curObj + 0x34) - _camX; - Ypos = Mem.ReadS16(curObj + 0x30) - _camY; - Ypos2 = Mem.ReadS16(curObj + 0x38) - _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Black, 127); - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Red, 0); - break; - default: - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2 = Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2 = Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS16(curObj + 0x24); - Ymid = Mem.ReadS16(curObj + 0x28); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); - PutText($"{type:X5}:{subtype}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); - PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); - break; - } - } - else - { - Xpos = Mem.ReadS16(curObj + 0x2C); - Xpos2= Mem.ReadS16(curObj + 0x34); - Ypos = Mem.ReadS16(curObj + 0x30); - Ypos2= Mem.ReadS16(curObj + 0x38); - Xmid = Mem.ReadS16(curObj + 0x24); - Ymid = Mem.ReadS16(curObj + 0x28); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.Cyan); - PutText($"{type:X5}:{Mem.ReadByte(curObj + 0x13)}", Xmid, Ymid - 4, 1, 1, -1, -9, Color.White, Color.Blue); - PutText(curObj.ToString("X6"), Xmid, Ymid + 4, 1, 9, -1, -1, Color.White, Color.Blue); - } - curObj = Mem.ReadU24(curObj+1); - } - //Ecco head - Xpos = Mem.ReadS16(0xFFA8F8); - Xpos2 = Mem.ReadS16(0xFFA900); - Ypos = Mem.ReadS16(0xFFA8FC); - Ypos2 = Mem.ReadS16(0xFFA904); - Xmid = Mem.ReadS16(0xFFA8F0); - Ymid = Mem.ReadS16(0xFFA8F4); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.PowderBlue, 0); - //Ecco tail - Xpos = Mem.ReadS16(0xFFA978); - Xpos2 = Mem.ReadS16(0xFFA980); - Ypos = Mem.ReadS16(0xFFA97C); - Ypos2 = Mem.ReadS16(0xFFA984); - Xmid = Mem.ReadS16(0xFFA970); - Ymid = Mem.ReadS16(0xFFA974); - Xpos -= _camX; Xpos2 -= _camX; - Ypos -= _camY; Ypos2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - DrawBox(Xpos, Ypos, Xpos2, Ypos2, Color.PowderBlue); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.PowderBlue, 0); - //Ecco body - Xpos = Mem.ReadS32(0xFFAA22); - Ypos = Mem.ReadS32(0xFFAA26); - Xpos2 = Mem.ReadS32(0xFFAA2A); - Ypos2 = Mem.ReadS32(0xFFAA2E); - Xmid = Mem.ReadS16(0xFFAA1A); - Ymid = Mem.ReadS16(0xFFAA1E); - int Xvel = Mem.ReadS32(0xFFAA36); - if (Mem.ReadU32(0xFFA9D6) > 7) Xvel += Mem.ReadS32(0xFFA9D6); - if (Mem.ReadU32(0xFFAA3E) > 7) Xvel += Mem.ReadS32(0xFFAA3E); - int Yvel = Mem.ReadS32(0xFFAA3A); - if (Mem.ReadU32(0xFFA9DA) > 7) Yvel += Mem.ReadS32(0xFFA9DA); - if (Mem.ReadU32(0xFFAA42) > 7) Yvel += Mem.ReadS32(0xFFAA42); - int XV = ((Xpos + Xvel) >> 16) - _camX; - int YV = ((Ypos + Yvel) >> 16) - _camY; - int XV2 = ((Xpos2 + Xvel) >> 16) - _camX; - int YV2 = ((Ypos2 + Yvel) >> 16) - _camY; - X = Xpos >> 16; - X2 = Xpos2 >> 16; - Y = Ypos >> 16; - Y2 = Ypos2 >> 16; - X -= _camX; X2 -= _camX; - Y -= _camY; Y2 -= _camY; - Xmid -= _camX; Ymid -= _camY; - int X3 = (Xmid + X) >> 1; - int X4 = (Xmid + X2) >> 1; - int Y3 = (Ymid + Y) >> 1; - int Y4 = (Ymid + Y2) >> 1; - Gui.DrawLine(X, Y, Xmid, Ymid, Color.Green); - Gui.DrawLine(Xmid, Ymid, X2, Y2, Color.Green); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Red); - DrawBoxMWH(X, Y, 1, 1, Color.Lime); - DrawBoxMWH(X2, Y2, 1, 1, Color.Blue); - DrawBoxMWH(X3, Y3, 1, 1, Color.Yellow); - DrawBoxMWH(X4, Y4, 1, 1, Color.Yellow); - Gui.DrawLine(X, Y, XV, YV, Color.Orange); - Gui.DrawLine(X2, Y2, XV2, YV2, Color.Orange); - // sonar - if (Mem.ReadU8(0xFFAB77) != 0) - { - Xmid = Mem.ReadS32(0xFFA9EC); - Ymid = Mem.ReadS32(0xFFA9F0); - int Xvec = ((Mem.ReadS32(0xFFAA04) + Xmid) >> 16) - _camX; - int Yvec = ((Mem.ReadS32(0xFFAA08) + Ymid) >> 16) - _camY; - Xmid >>= 16; - Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - Width2 = Mem.ReadS16(0xFFA9FC); - Height2 = Mem.ReadS16(0xFFAA00); - color = ((Mem.ReadU8(0xFFAA0C) != 0) ? Color.FromArgb(255, 0, 127) : Color.FromArgb(0, 0, 255)); - DrawBoxMWH(Xmid, Ymid, Width2, Height2, color); - DrawBoxMWH(Xmid, Ymid, 1, 1, color, 0); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - //Pulsar - curObj = Mem.ReadU24(0xFFCFD1); - if ((curObj != 0) && ((Mem.ReadU32(curObj + 0xC) == 0xC9222) || (Mem.ReadU32(curObj + 0xC) == 0xC9456))) - { - curObj += 0x26; - for (int l = 0; l < 4; l++) - { - if (Mem.ReadU16(curObj + 0x12) != 0) - { - Xmid = Mem.ReadS32(curObj); - Ymid = Mem.ReadS32(curObj + 4); - int Xvec = (Xmid + Mem.ReadS32(curObj + 8) >> 16) - _camX; - int Yvec = (Ymid + Mem.ReadS32(curObj + 0xC) >> 16) - _camY; - Xmid >>= 16; Ymid >>= 16; - Xmid -= _camX; Ymid -= _camY; - DrawBoxMWH(Xmid, Ymid, 0x30, 0x30, Color.Red); - DrawBoxMWH(Xmid, Ymid, 1, 1, Color.Blue); - Gui.DrawLine(Xmid, Ymid, Xvec, Yvec, Color.Orange); - } - curObj += 0x14; - } - } - - //Water Level - int waterLevel = Mem.ReadS16(0xFFA7B2); - Gui.DrawLine(0, waterLevel - _camY, _left + 320 + _right, waterLevel - _camY, Color.Aqua); - - } - - void EccoAutofire(bool on) - { - //Modif N - ECCO HACK - make caps lock (weirdly) autofire player 1's C key - uint charge; - uint mode = Mem.ReadU8(0xFFA555); - int frameCount = Emu.FrameCount(); - int lagCount = Emu.LagCount(); - Joy.Set("Start", on, 1); - switch (mode) - { - case 0x00: - if (on) - { - if (Mem.ReadU16(0xFFF342) == 0xFFFD) - Joy.Set("C", true, 1); - else - Joy.Set("C", false, 1); - } - break; - case 0xE6: - if (Mem.ReadU16(0xFFD5E8) == 0x00000002) { - Dictionary buttons = new Dictionary(); - buttons["B"] = buttons["C"] = true; - Joy.Set(buttons, 1); - } - else - { - Dictionary buttons = new Dictionary(); - buttons["B"] = buttons["C"] = false; - Joy.Set(buttons, 1); - } - break; - case 0xF6: - charge = Mem.ReadU8(0xFFB19B); - if (on) - { - if ((charge <= 1) && ((Mem.ReadU8(0xFFB1A6) == 0) || (Mem.ReadU8(0xFFB1A9) != 0))) - Joy.Set("B", true, 1); - else if (charge > 1) - Joy.Set("B", false, 1); - Joy.Set("C", (Mem.ReadU16(0xFFA7C8) % 2) == 0, 1); - } - break; - case 0x20: - case 0x28: - case 0xAC: - if (on) - { - if ((Mem.ReadU8(0xFFAB72) & 3) == 0) - Joy.Set("C", (Mem.ReadS8(0xFFAA6E) < 11), 1); - } - break; - default: - break; - } - } - public override void Init(IApiContainer api) - { - base.Init(api); - Mem.SetBigEndian(); - string gameName = GI.GetRomName(); - if ((gameName == "ECCO - The Tides of Time (J) [!]") || - (gameName == "ECCO - The Tides of Time (U) [!]") || - (gameName == "ECCO - The Tides of Time (E) [!]")) - { - _mode = Modes.Ecco2; - _camXAddr = 0xFFAD9C; - _camYAddr = 0xFFAD9E; - _top = _bottom = 112; - _left = _right = 160; - ClientApi.SetGameExtraPadding(_left, _top, _right, _bottom); - } - else if ((gameName == "ECCO The Dolphin (J) [!]") || - (gameName == "ECCO The Dolphin (UE) [!]")) - - { - _mode = Modes.Ecco1; - _camXAddr = 0xFFB836; - _camYAddr = 0xFFB834; - _top = _bottom = 112; - _left = _right = 160; - ClientApi.SetGameExtraPadding(_left, _top, _right, _bottom); - } - else - { - _mode = Modes.disabled; - Running = false; - } - } - private Color BackdropColor() - { - uint color = Mem.ReadU16(0, "CRAM"); - int r = (int)(( color & 0x7) * 0x22); - int g = (int)(((color >> 3) & 0x7) * 0x22); - int b = (int)(((color >> 6) & 0x7) * 0x22); - return Color.FromArgb(r, g, b); - } - public override void PreFrameCallback() - { - Gui.ClearText(); - if (_mode != Modes.disabled) - { - _camX = Mem.ReadS16(_camXAddr) - _left; - _camY = Mem.ReadS16(_camYAddr) - _top; - EccoAutofire(Joy.Get(1)["Start"]); - if (_dumpMap == 0) - { - Color bg = BackdropColor(); - Gui.DrawRectangle(0, 0, _left + 320 + _right, _top, bg, bg); - Gui.DrawRectangle(0, 0, _left, _top + 224 + _bottom, bg, bg); - Gui.DrawRectangle(_left + 320, 0, _left + 320 + _right, _top + 224 + _bottom, bg, bg); - Gui.DrawRectangle(0, _top + 224, _left + 320 + _right, _top + 224 + _bottom, bg, bg); - } - uint mode = Mem.ReadByte(0xFFA555); - switch (mode) - { - case 0x20: - case 0x28: - case 0xAC: - //ClientApi.SetGameExtraPadding(160, 112, 160, 112); - if (_dumpMap <= 1) EccoDrawBoxes(); - // Uncomment the following block to enable mapdumping - if ((Mem.ReadU16(0xFFA7C8) > 1) && (Mem.ReadU16(0xFFA7C8) < 4)) - { - _dumpMap = 1; - _rowStateGuid = string.Empty; - _top = _bottom = _left = _right = 0; - ClientApi.SetGameExtraPadding(0, 0, 0, 0); - } - if (_dumpMap == 3) - { - var levelID = Mem.ReadS8(0xFFA7D0); - int[] nameGroupLengths = - { - 7,1,11,6, - 4,3,3,3, - 7,1,2,1, - 0,0,0,0 - }; - int[] nameStringPtrOffsets = - { - 0xECBD0, 0x106BC0, 0x10AF8C, 0x135A48, - 0x1558E8, 0x15F700, 0x16537C, 0x180B00, - 0x193920, 0x1B3ECC, 0x1D7A44, 0x1DBF70, - 0x2DF2, 0x2DF6, 0x2DFA, 0x2DFE - }; - int nameGroup = 0; - var i = levelID; - while ((i >= 0) && (nameGroup < nameGroupLengths.Length)) - { - i -= nameGroupLengths[nameGroup]; - if (i >= 0) nameGroup++; - } - string name = "map"; - if (i < 0) - { - i += nameGroupLengths[nameGroup]; - uint strOffset = Mem.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); - Console.WriteLine($"{i}"); - strOffset = Mem.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); - strOffset += 0x20; - List strTmp = new List(); - byte c; - do - { - c = (byte)Mem.ReadByte(strOffset++); - if (c != 0) - strTmp.Add(c); - } while (c != 0); - name = System.Text.Encoding.ASCII.GetString(strTmp.ToArray()); - TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; - name = textInfo.ToTitleCase(name).Replace(" ", string.Empty); - } - ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_top.png"); - _destX = _destY = 0; - ClientApi.SetGameExtraPadding(0, 0, 0, 0); - _dumpMap++; - } - if (_dumpMap == 6) - { - var levelID = Mem.ReadS8(0xFFA7D0); - int[] nameGroupLengths = - { - 7,1,11,6, - 4,3,3,3, - 7,1,2,1, - 0,0,0,0 - }; - int[] nameStringPtrOffsets = - { - 0xECBD0, 0x106BC0, 0x10AF8C, 0x135A48, - 0x1558E8, 0x15F700, 0x16537C, 0x180B00, - 0x193920, 0x1B3ECC, 0x1D7A44, 0x1DBF70, - 0x2DF2, 0x2DF6, 0x2DFA, 0x2DFE - }; - int nameGroup = 0; - var i = levelID; - while ((i >= 0) && (nameGroup < nameGroupLengths.Length)) - { - i -= nameGroupLengths[nameGroup]; - if (i >= 0) nameGroup++; - } - string name = "map"; - if (i < 0) - { - i += nameGroupLengths[nameGroup]; - uint strOffset = Mem.ReadU32(nameStringPtrOffsets[nameGroup] + 0x2E); - Console.WriteLine($"{i}"); - strOffset = Mem.ReadU32(strOffset + ((i << 3) + (i << 5)) + 0x22); - strOffset += 0x20; - List strTmp = new List(); - byte c; - do - { - c = (byte)Mem.ReadByte(strOffset++); - if (c != 0) - strTmp.Add(c); - } while (c != 0); - name = System.Text.Encoding.ASCII.GetString(strTmp.ToArray()); - TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; - name = textInfo.ToTitleCase(name).Replace(" ", string.Empty); - } - ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}_{name}_bottom.png"); - _destX = _destY = 0; - _left = _right = 160; - _top = _bottom = 112; - ClientApi.SetGameExtraPadding(_left, _top, _right, _bottom); - _dumpMap = 0; - } - break; - case 0xF6: - EccoDraw3D(); - break; - default: - break; - } - _prevF = Mem.ReadU32(0xFFA524); - } - } - public override void PostFrameCallback() - { - uint frame = Mem.ReadU32(0xFFA524); - if ((frame <= _prevF) && !Emu.IsLagged()) - { - Emu.SetIsLagged(true); - Emu.SetLagCount(Emu.LagCount() + 1); - } - uint mode = Mem.ReadByte(0xFFA555); - _tickerY = 81; - string valueTicker = $"{Mem.ReadU32(0xFFA520)}:{Mem.ReadU32(0xFFA524)}:{Mem.ReadU16(0xFFA7C8)}:{mode:X2}"; - TickerText(valueTicker); - switch (mode) - { - case 0x20: - case 0x28: - case 0xAC: - valueTicker = $"{Mem.ReadS16(0xFFAD9C)}:{Mem.ReadS16(0xFFAD9E)}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFAA1A) / 65536.0:0.######}:{Mem.ReadS32(0xFFAA1E) / 65536.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFAA32) / 65536.0:0.######}:{Mem.ReadU8(0xFFAA6D)}:{Mem.ReadU8(0xFFAA6E)}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFAA36) / 65536.0:0.######}:{Mem.ReadS32(0xFFAA3A) / 65536.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFA9D6) / 65536.0:0.######}:{Mem.ReadS32(0xFFA9DA) / 65536.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFAA3E) / 65536.0:0.######}:{Mem.ReadS32(0xFFAA42) / 65536.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{(Mem.ReadS32(0xFFAA36) + Mem.ReadS32(0xFFA9D6) + Mem.ReadS32(0xFFAA3E)) / 65536.0:0.######}:" + - $"{(Mem.ReadS32(0xFFAA3A) + Mem.ReadS32(0xFFA9DA) + Mem.ReadS32(0xFFAA42)) / 65536.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadU8(0xFFAB72)}:{Mem.ReadU8(0xFFAB70)}:{(short)Mem.ReadS16(0xFFAA52):X4}:{(short)Mem.ReadS16(0xFFAA5A):X4}"; - TickerText(valueTicker); - switch (Mem.ReadU8(0xFFA7D0)) - { - case 1: - case 2: - case 3: - case 30: - case 46: - var globeFlags = Mem.ReadU32(0xFFD434) >> 1; - var globeFlags2 = Mem.ReadU32(0xFFD438) >> 1; - int i, j = i = 0; - while (globeFlags > 0) - { - globeFlags >>= 1; - i++; - } - while (globeFlags2 > 0) - { - globeFlags2 >>= 1; - j++; - } - TickerText($"{i}:{j}", Color.Blue); - break; - default: - break; - } - if (_dumpMap != 0) - { - Mem.WriteS16(0xFFAA16, 7); - Mem.WriteS16(0xFFAA18, 56); - int PlayerX = Mem.ReadS16(0xFFAA1A) - _camX; - int PlayerY = Mem.ReadS16(0xFFAA1E) - _camY; - if ((PlayerX < -64) || (PlayerX > 384) || (PlayerY < -64) || (PlayerY > 288)) - { - Mem.WriteByte(0xFFAA70, 0xC); - Mem.WriteS16(0xFFA7CA, 1); - } - else - { - Mem.WriteByte(0xFFAA70, 0x0); - Mem.WriteS16(0xFFA7CA, 0); - } - } - if (_dumpMap == 1) - { - int levelWidth = Mem.ReadS16(0xFFA7A8); - int levelHeight = Mem.ReadS16(0xFFA7AC); - var levelID = Mem.ReadByte(0xFFA7D0); - var s = Emu.GetSettings() as GPGX.GPGXSettings; - s.DrawBGA = false; - s.DrawBGB = false; - s.DrawBGW = false; - s.DrawObj = false; - s.Backdrop = true; - Emu.PutSettings(s); - if ((_camX == _destX) && (_camY == _destY)) - { - if ((_prevX != _camX) || (_prevY != _camY)) - { - if (_destX == 0) - { - if (_rowStateGuid != string.Empty) - { - MemSS.DeleteState(_rowStateGuid); - } - _rowStateGuid = MemSS.SaveCoreStateToMemory(); - } - _snapPast = 1; - } - else - { - _snapPast--; - } - if (_snapPast == 0) - { - ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_top.png"); - if (_destX >= levelWidth - 320) - { - if (_destY < levelHeight - 224) - { - if (_rowStateGuid != string.Empty) - { - MemSS.LoadCoreStateFromMemory(_rowStateGuid); - } - _destX = 0; - _destY = Math.Min(_destY + 111, levelHeight - 224); - } - } - else - _destX = Math.Min(_destX + 159, levelWidth - 320); - if ((_prevX == _destX) && (_prevY == _destY)) - { - ClientApi.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); - _dumpMap++; - } - } - } - Mem.WriteS16(0xFFAD8C, _destX); - Mem.WriteS16(0xFFAD90, _destY); - } - else if (_dumpMap == 2) - { - if (_rowStateGuid != String.Empty) - MemSS.DeleteState(_rowStateGuid); - _rowStateGuid = String.Empty; - int levelWidth = Mem.ReadS16(0xFFA7A8); - int levelHeight = Mem.ReadS16(0xFFA7AC); - ClientApi.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); - var levelID = Mem.ReadS8(0xFFA7D0); - var s = Emu.GetSettings() as GPGX.GPGXSettings; - s.DrawBGA = false; - s.DrawBGB = false; - s.DrawBGW = false; - s.DrawObj = false; - s.Backdrop = true; - Emu.PutSettings(s); - - var a = Gui.GetAttributes(); - a.SetColorKey(Color.FromArgb(0, 0x11, 0x22, 0x33), Color.FromArgb(0, 0x11, 0x22, 0x33)); - Gui.SetAttributes(a); - Gui.ToggleCompositingMode(); - - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_top.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); - for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) - { - var dx = (x == 0) ? 0 : 2; - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_top.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); - } - for (int y = ((levelHeight - 224) / 111) * 111; y >= 0; y -= 111) - { - var dy = (y == 0) ? 0 : 2; - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_top.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); - for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) - { - var dx = (x == 0) ? 0 : 2; - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_top.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); - } - } - - Gui.ToggleCompositingMode(); - Gui.SetAttributes(new System.Drawing.Imaging.ImageAttributes()); - Gui.DrawFinish(); - _dumpMap++; - } - else if (_dumpMap == 4) - { - int levelWidth = Mem.ReadS16(0xFFA7A8); - int levelHeight = Mem.ReadS16(0xFFA7AC); - var levelID = Mem.ReadByte(0xFFA7D0); - var s = Emu.GetSettings() as GPGX.GPGXSettings; - s.DrawBGA = (levelID != 29); - s.DrawBGB = (levelID == 7); - s.DrawBGW = true; - s.DrawObj = true; - s.Backdrop = false; - Emu.PutSettings(s); - if ((_camX == _destX) && (_camY == _destY)) - { - if ((_prevX != _camX) || (_prevY != _camY)) - { - if (_destX == 0) - { - if (_rowStateGuid != string.Empty) - { - MemSS.DeleteState(_rowStateGuid); - } - _rowStateGuid = MemSS.SaveCoreStateToMemory(); - } - _snapPast = 1; - } - else - { - _snapPast--; - } - if (_snapPast == 0) - { - ClientApi.Screenshot($"c:\\Ecco2Maps\\{levelID}\\{_destY}_{_destX}_bottom.png"); - if (_destX >= levelWidth - 320) - { - if (_destY < levelHeight - 224) - { - if (_rowStateGuid != string.Empty) - { - MemSS.LoadCoreStateFromMemory(_rowStateGuid); - } - _destX = 0; - _destY = Math.Min(_destY + 111, levelHeight - 224); - } - } - else - _destX = Math.Min(_destX + 159, levelWidth - 320); - if ((_prevX == _destX) && (_prevY == _destY)) - { - ClientApi.SetGameExtraPadding(levelWidth - 320, levelHeight - 224, 0, 0); - _dumpMap++; - } - } - } - Mem.WriteS16(0xFFAD8C, _destX); - Mem.WriteS16(0xFFAD90, _destY); - } - else if (_dumpMap == 5) - { - if (_rowStateGuid != String.Empty) - MemSS.DeleteState(_rowStateGuid); - _rowStateGuid = String.Empty; - int levelWidth = Mem.ReadS16(0xFFA7A8); - int levelHeight = Mem.ReadS16(0xFFA7AC); - var levelID = Mem.ReadS8(0xFFA7D0); - var s = Emu.GetSettings() as GPGX.GPGXSettings; - s.DrawBGA = (levelID != 29); - s.DrawBGB = (levelID == 7); - s.DrawBGW = true; - s.DrawObj = true; - s.Backdrop = false; - Emu.PutSettings(s); - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{levelWidth - 320}_bottom.png", 2, 2, 318, 222, (levelWidth - 318), (levelHeight - 222), 318, 222); - for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) - { - var dx = (x == 0) ? 0 : 2; - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{levelHeight - 224}_{x}_bottom.png", dx, 2, 320 - dx, 222, x + dx, (levelHeight - 222), 320 - dx, 222); - } - for (int y = ((levelHeight - 224) / 111) * 111; y >= 0; y -= 111) - { - var dy = (y == 0) ? 0 : 2; - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{levelWidth - 320}_bottom.png", 2, dy, 318, 224 - 2, levelWidth - 318, y + dy, 318, 224 - dy); - for (int x = ((levelWidth - 320) / 159) * 159; x >= 0; x -= 159) - { - var dx = (x == 0) ? 0 : 2; - Gui.DrawImageRegion($"c:\\Ecco2Maps\\{levelID}\\{y}_{x}_bottom.png", dx, dy, 320 - dx, 224 - dy, x + dx, y + dy, 320 - dx, 224 - dy); - } - } - Gui.DrawFinish(); - _dumpMap++; - } - _prevX = _camX; - _prevY = _camY; - break; - case 0xF6: - valueTicker = $"{Mem.ReadS32(0xFFD5E0) / 4096.0:0.######}:{Mem.ReadS32(0xFFD5E8) / 4096.0:0.######}:{Mem.ReadS32(0xFFD5E4) / 2048.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFB13A) / 4096.0:0.######}:{Mem.ReadS32(0xFFB142) / 4096.0:0.######}:{Mem.ReadS32(0xFFB13E) / 2048.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadS32(0xFFB162) / 4096.0:0.######}:{Mem.ReadS32(0xFFB16A) / 4096.0:0.######}:{Mem.ReadS32(0xFFB166) / 2048.0:0.######}"; - TickerText(valueTicker); - valueTicker = $"{Mem.ReadU8(0xFFB19B)}:{Mem.ReadU8(0xFFB1A6)}:{Mem.ReadU8(0xFFB1A9)}"; - TickerText(valueTicker); - int SpawnZ = Mem.ReadS32(0xFFD5F0) + 0x180000; - int nextRingZ = SpawnZ; - while (((nextRingZ >> 17) & 0xF) != 0) - { - nextRingZ += 0x20000; - } - valueTicker = $"{Mem.ReadS32(0xFFD856) / 4096.0:0.######}:{Mem.ReadS32(0xFFD85A) / 4096.0:0.######}:{(nextRingZ - 0x160000) / 2048.0:0.######}:{nextRingZ / 2048.0:0.######}"; - TickerText(valueTicker); - var levelId = -1 - Mem.ReadS16(0xFFA79E); - bool spawn = false; - bool firstRand = true; - int SpawnX, SpawnY, z; - int CamX = (Mem.ReadS32(0xFFD5E0) >> 0xC) - _left; - int CamY = (Mem.ReadS32(0xFFD5E8) >> 0xC) + _top; - int CamZ = (Mem.ReadS32(0xFFD5E4) >> 0xC) + _top; - while (!spawn) - { - var temp = (SpawnZ >> 17) & 0xFF; - var controlList = Mem.ReadS32(0x7B54 + (levelId << 2)); - temp = Mem.ReadS16(controlList + (temp << 1)); - var v = temp & 0xFF; - var num = (temp >> 8) + v; - temp = v; - spawn = (num > 2); - if (spawn) for (; temp < num; temp++) - { - switch (temp) - { - case 0: - case 1: - case 13: - // Nothing important spawns - break; - case 2: - // Jellyfish - SpawnX = Mem.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); - firstRand = false; - SpawnY = -0xC0000 + (EccoRand() << 3); - z = SpawnZ + 0x20000;// ? - valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; - TickerText(valueTicker); - SpawnX = 160 + ((SpawnX >> 0xC) - CamX); - SpawnY = 112 - ((SpawnY >> 0xC) - CamY); - z = _top + 112 - ((z >> 0xC) - CamZ); - DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); - DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); - break; - case 3: - // Eagle - SpawnX = Mem.ReadS32(0xFFB13A) + 0x40000 - (EccoRand(firstRand) << 3); - firstRand = false; - SpawnY = 0x50000; - z = SpawnZ - 0x40000 + 0x20000;// ? - valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; - TickerText(valueTicker); - SpawnX = 160 + ((SpawnX >> 0xC) - CamX); - SpawnY = 112 - ((SpawnY >> 0xC) - CamY); - z = _top + 112 - ((z >> 0xC) - CamZ); - DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); - DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); - break; - case 4: - // Shark - bool left = (EccoRand(firstRand) > 0x8000); - firstRand = false; - var xdiff = 0xC0000 + (EccoRand() << 3); - SpawnX = Mem.ReadS32(0xFFB13A) + (left ? -xdiff : xdiff); - SpawnY = Math.Min(Mem.ReadS32(0xFFB142), -0x10000) - (EccoRand() + 0x10000); - z = SpawnZ + 0x20000; - valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{z / 2048.0:0.######}"; - TickerText(valueTicker); - SpawnX = 160 + ((SpawnX >> 0xC) - CamX); - SpawnY = 112 - ((SpawnY >> 0xC) - CamY); - z = _top + 112 - ((z >> 0xC) - CamZ); - DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); - DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); - break; - case 5: - case 6: - case 7: - case 8: - // Vine - EccoRand(firstRand); - firstRand = false; - if ((temp & 1) == 1) EccoRand(); - EccoRand(); - break; - case 9: - case 10: - case 11: - case 12: - // Unknown, possibly just rand incrementation? - EccoRand(firstRand); - firstRand = false; - if ((temp & 1) == 1) EccoRand(); - break; - case 14: - // Shell - SpawnX = Mem.ReadS32(0xFFB13A) - 0x20000 + (EccoRand(firstRand) << 2); - firstRand = false; - SpawnY = -0x80000; - z = SpawnZ + 0x20000; - EccoRand(); - valueTicker = $"{SpawnX / 4096.0:0.######}:{SpawnY / 4096.0:0.######}:{(z - 0x180000) / 2048.0:0.######}:{(z - 0x80000) / 2048.0:0.######}"; - TickerText(valueTicker); - SpawnX = 160 + ((SpawnX >> 0xC) - CamX); - SpawnY = 112 - ((SpawnY >> 0xC) - CamY); - z = _top + 112 - ((z >> 0xC) - CamZ); - DrawBoxMWH(SpawnX, SpawnY, 1, 1, Color.Gray); - DrawBoxMWH(SpawnX, z, 1, 1, Color.Gray); - break; - } - } - SpawnZ += 0x20000; - } - break; - } - Joy.Set("C", null, 1); - Joy.Set("Start", null, 1); - var color = _turnSignalColors[Mem.ReadS8(0xFFA7C9) & 7]; - Gui.DrawRectangle(_left - 48, _top - 112, 15, 15, color, color); - } - public override void LoadStateCallback(string name) - { - Gui.DrawNew("emu"); - PreFrameCallback(); - Gui.DrawFinish(); - } - } -} diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index d12517e315..fd0185f1b6 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -658,7 +658,6 @@ - From 8a9e8ceed21d8a9284d519bdc1b8485beb61fa75 Mon Sep 17 00:00:00 2001 From: upthorn Date: Fri, 4 Jan 2019 14:25:24 -0800 Subject: [PATCH 22/22] Fix appveyor build error by removing use of C#7 features. --- BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs b/BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs index 3677007d2b..a3cda9ed76 100644 --- a/BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs +++ b/BizHawk.Client.ApiHawk/Classes/Api/EmuApi.cs @@ -97,7 +97,8 @@ namespace BizHawk.Client.ApiHawk domain = MemoryDomains[name]; } - var d = DisassemblableCore.Disassemble(domain, pc, out int l); + int l; + var d = DisassemblableCore.Disassemble(domain, pc, out l); return new { disasm = d, length = l }; } catch (NotImplementedException)