Merge branch 'master' into MoreUnixMonoCompatWork
This doesn't compile because of Input.cs, didn't know what to do. Also search for Merge TODO for some commenting things that probably need to be deleted # Conflicts: # BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj # BizHawk.Client.EmuHawk/CustomControls/InputRoll.Drawing.cs # BizHawk.Client.EmuHawk/CustomControls/InputRoll/InputRoll.cs # BizHawk.Client.EmuHawk/Program.cs # BizHawk.Client.EmuHawk/tools/Lua/LuaConsole.cs # BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs # BizHawk.Client.EmuHawk/tools/ToolHelpers.cs # BizHawk.Client.EmuHawk/tools/ToolManager.cs # BizHawk.Client.EmuHawk/tools/TraceLogger.Designer.cs # BizHawk.Client.EmuHawk/tools/TraceLogger.cs # BizHawk.Client.EmuHawk/tools/Watch/RamSearch.Designer.cs # BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs # BizHawk.Common/BizInvoke/DynamicLibraryImportResolver.cs
This commit is contained in:
commit
6c7653e158
|
@ -2,3 +2,12 @@ root = true
|
|||
|
||||
[*]
|
||||
indent_style = tab
|
||||
|
||||
[*.cs]
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -555,8 +555,8 @@ A5359E35839B40C414EAE498CA633B28176629AA G Olympic Hockey 98 (Japan) N64 Glide_
|
|||
7592F4C16B8E040539B5DCC201FAB2965A5E8C8D G Onegai Monsters (Japan) N64
|
||||
133F17162B2734286F9E94F64ACB1538B11506B2 G Operation WinBack (Europe) (En,Fr,De,Es,It) N64
|
||||
B8F29E8EFCF51EE9A6A16E2A1E60442B4F304950 G Pachinko 365 Nichi (Japan) N64
|
||||
2111D39265A317414D359E35A7D971C4DFA5F9E1 G Paper Mario (Europe) (En,Fr,De,Es) N64 Glide_enable_hacks_for_game=15;Glide_fb_hires_buf_clear=false;Glide_fb_optimize_texrect=false;Glide_swapmode=2;Glide_fb_smart=true;Glide_fb_read_alpha=true;Glide64mk2_enable_hacks_for_game=20;Glide64mk2_hires_buf_clear=false;Glide64mk2_optimize_texrect=false;Glide64mk2_filtering=1;Glide64mk2_swapmode=2;Glide64mk2_fb_smart=true;Glide64mk2_fb_read_alpha=true;Jabo_Clear_Frame=1;GLideN64_CopyColorToRDRAM=2
|
||||
3837F44CDA784B466C9A2D99DF70D77C322B97A0 G Paper Mario (USA) N64 RiceFrameBufferOption=3;RiceRenderToTextureOption=3;RiceScreenUpdateSettingHack=4;Glide_enable_hacks_for_game=15;Glide_fb_hires_buf_clear=false;Glide_fb_optimize_texrect=false;Glide_swapmode=2;Glide_fb_smart=true;Glide_fb_read_alpha=true;Glide64mk2_enable_hacks_for_game=20;Glide64mk2_hires_buf_clear=false;Glide64mk2_optimize_texrect=false;Glide64mk2_filtering=1;Glide64mk2_swapmode=2;Glide64mk2_fb_smart=true;Glide64mk2_fb_read_alpha=true;Jabo_Clear_Frame=1;GLideN64_CopyColorToRDRAM=2
|
||||
2111D39265A317414D359E35A7D971C4DFA5F9E1 G Paper Mario (Europe) (En,Fr,De,Es) N64 Glide_enable_hacks_for_game=15;Glide_fb_hires_buf_clear=false;Glide_fb_optimize_texrect=false;Glide_swapmode=2;Glide_fb_smart=true;Glide_fb_read_alpha=true;Glide64mk2_enable_hacks_for_game=20;Glide64mk2_hires_buf_clear=false;Glide64mk2_optimize_texrect=false;Glide64mk2_filtering=1;Glide64mk2_swapmode=2;Glide64mk2_fb_smart=true;Glide64mk2_fb_read_alpha=true;Jabo_Clear_Frame=1;GLideN64_CopyColorToRDRAM=1
|
||||
3837F44CDA784B466C9A2D99DF70D77C322B97A0 G Paper Mario (USA) N64 RiceFrameBufferOption=3;RiceRenderToTextureOption=3;RiceScreenUpdateSettingHack=4;Glide_enable_hacks_for_game=15;Glide_fb_hires_buf_clear=false;Glide_fb_optimize_texrect=false;Glide_swapmode=2;Glide_fb_smart=true;Glide_fb_read_alpha=true;Glide64mk2_enable_hacks_for_game=20;Glide64mk2_hires_buf_clear=false;Glide64mk2_optimize_texrect=false;Glide64mk2_filtering=1;Glide64mk2_swapmode=2;Glide64mk2_fb_smart=true;Glide64mk2_fb_read_alpha=true;Jabo_Clear_Frame=1;GLideN64_CopyColorToRDRAM=1
|
||||
7DB4808042B9651B47592E814AC4C125B51D4D2F G Paperboy (Europe) N64
|
||||
B043C47B9758FA6BB289CA7DBA2068BDA6CAFA3A G Paperboy (USA) N64
|
||||
9887A0E4BFE3C5E85E31638853574069F6C41CD3 G Parlor! Pro 64 - Pachinko Jikki Simulation Game (Japan) N64 Glide_force_microcheck=true;Glide64mk2_force_microcheck=true;Glide64mk2_filtering=1
|
||||
|
|
|
@ -305,7 +305,6 @@ sha1:17473C223453D2D80FCB9DCFA317947287DC5C52 Xing He Zhan Shi (China) (Unl) NE
|
|||
sha1:B1C74236FD17FAB4AB9AA6AB28E38864C66D6255 Pocahontus (UNL) NES board=MAPPER182;PRG=256;CHR=256;WRAM=8;PAD_H=1
|
||||
sha1:5FA23F88432006DCF6874EA36E9E7DA8934427BE Super Donkey Kong (Unl) NES board=MAPPER182;PRG=128;CHR=128;WRAM=8;PAD_H=1
|
||||
sha1:8A7DAB8B78DA1C5EA159BA9EEC00FF97742245F1 B Super Donkey Kong (Unl) [b1] NES board=MAPPER182;PRG=128;CHR=128;WRAM=8;PAD_H=1
|
||||
sha1:8A7DAB8B78DA1C5EA159BA9EEC00FF97742245F1 O Super Donkey Kong (Unl) [o1] NES board=MAPPER182;PRG=128;CHR=128;WRAM=8;PAD_H=1
|
||||
|
||||
;wrong vram info
|
||||
sha1:32D71DD6C5A8D78A918FE1B9D6D6C4A570D9652D Oeka Kids Anpanman no Hiragana Daisuki (J) NES board=MAPPER096;VRAM=32
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
<NoWarn>1591</NoWarn><!-- don't bug us with "Missing XML comment [...]" until we have and enforce .stylecop.json i.e. when we care -->
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<NoWarn>1591</NoWarn>
|
||||
<!-- don't bug us with "Missing XML comment [...]" until we have and enforce .stylecop.json i.e. when we care -->
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp60</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp80</s:String></wpf:ResourceDictionary>
|
|
@ -117,6 +117,9 @@ namespace BizHawk.Client.ApiHawk
|
|||
case "GB4x":
|
||||
return CoreSystem.GB3x;
|
||||
|
||||
case "MAME":
|
||||
return CoreSystem.MAME;
|
||||
|
||||
case "VB":
|
||||
case "NGP":
|
||||
case "DNGP":
|
||||
|
|
|
@ -134,54 +134,54 @@ namespace SevenZip
|
|||
/// <param name="format">Archive format</param>
|
||||
public static void LoadLibrary(object user, Enum format)
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
if (_inArchives == null
|
||||
#if COMPRESS
|
||||
|| _outArchives == null
|
||||
#endif
|
||||
)
|
||||
lock (_syncRoot)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
if (_inArchives == null
|
||||
#if COMPRESS
|
||||
|| _outArchives == null
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
#if !WINCE && !MONO
|
||||
if (_modulePtr == IntPtr.Zero)
|
||||
{
|
||||
//zero 29-oct-2012 - this check isnt useful since LoadLibrary can pretty much check for the same thing. and it wrecks our dll relocation scheme
|
||||
//if (!File.Exists(_libraryFileName))
|
||||
//{
|
||||
// throw new SevenZipLibraryException("DLL file does not exist.");
|
||||
//}
|
||||
if ((_modulePtr = libLoader.LoadPlatformSpecific(_libraryFileName)) == IntPtr.Zero)
|
||||
if (_modulePtr == IntPtr.Zero)
|
||||
{
|
||||
//try a different directory
|
||||
string alternateFilename = Path.Combine(Path.Combine(Path.GetDirectoryName(_libraryFileName),"dll"),"7z.dll");
|
||||
if ((_modulePtr = libLoader.LoadPlatformSpecific(alternateFilename)) == IntPtr.Zero)
|
||||
throw new SevenZipLibraryException("failed to load library.");
|
||||
}
|
||||
if (libLoader.GetProcAddr(_modulePtr, "GetHandlerProperty") == IntPtr.Zero)
|
||||
{
|
||||
libLoader.FreePlatformSpecific(_modulePtr);
|
||||
throw new SevenZipLibraryException("library is invalid.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (format is InArchiveFormat)
|
||||
{
|
||||
InitUserInFormat(user, (InArchiveFormat) format);
|
||||
return;
|
||||
}
|
||||
#if COMPRESS
|
||||
if (format is OutArchiveFormat)
|
||||
{
|
||||
InitUserOutFormat(user, (OutArchiveFormat) format);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
throw new ArgumentException(
|
||||
"Enum " + format + " is not a valid archive format attribute!");
|
||||
}
|
||||
//zero 29-oct-2012 - this check isnt useful since LoadOrNull can pretty much check for the same thing. and it wrecks our dll relocation scheme
|
||||
//if (!File.Exists(_libraryFileName))
|
||||
//{
|
||||
// throw new SevenZipLibraryException("DLL file does not exist.");
|
||||
//}
|
||||
var newPtr = libLoader.LoadOrNull(_libraryFileName);
|
||||
if (!newPtr.HasValue)
|
||||
{
|
||||
//try a different directory
|
||||
newPtr = libLoader.LoadOrNull(Path.Combine(Path.Combine(Path.GetDirectoryName(_libraryFileName), "dll"), "7z.dll"));
|
||||
if (!newPtr.HasValue) throw new SevenZipLibraryException("failed to load library.");
|
||||
}
|
||||
_modulePtr = newPtr.Value;
|
||||
|
||||
if (libLoader.GetProcAddr(_modulePtr, "GetHandlerProperty") == IntPtr.Zero)
|
||||
{
|
||||
libLoader.FreeByPtr(_modulePtr);
|
||||
throw new SevenZipLibraryException("library is invalid.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (format is InArchiveFormat)
|
||||
{
|
||||
InitUserInFormat(user, (InArchiveFormat) format);
|
||||
return;
|
||||
}
|
||||
#if COMPRESS
|
||||
if (format is OutArchiveFormat)
|
||||
{
|
||||
InitUserOutFormat(user, (OutArchiveFormat) format);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
throw new ArgumentException("Enum " + format + " is not a valid archive format attribute!");
|
||||
}
|
||||
}
|
||||
|
||||
/*/// <summary>
|
||||
|
@ -435,7 +435,7 @@ namespace SevenZip
|
|||
if (_totalUsers == 0)
|
||||
{
|
||||
#if !WINCE && !MONO
|
||||
libLoader.FreePlatformSpecific(_modulePtr);
|
||||
libLoader.FreeByPtr(_modulePtr);
|
||||
|
||||
#endif
|
||||
_modulePtr = IntPtr.Zero;
|
||||
|
|
|
@ -34,8 +34,9 @@
|
|||
ZXSpectrum,
|
||||
AmstradCPC,
|
||||
GGL,
|
||||
ChannelF,
|
||||
GB3x,
|
||||
GB4x
|
||||
GB4x,
|
||||
ChannelF,
|
||||
MAME
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
|
@ -127,6 +128,7 @@
|
|||
<Compile Include="config\ConfigPersistAttribute.cs" />
|
||||
<Compile Include="config\ConfigService.cs" />
|
||||
<Compile Include="config\PathEntry.cs" />
|
||||
<Compile Include="config\RestoreDefaultsAttribute.cs" />
|
||||
<Compile Include="config\ToolDialogSettings.cs" />
|
||||
<Compile Include="ControllerBinding.cs" />
|
||||
<Compile Include="CoreFileProvider.cs" />
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp60</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp80</s:String></wpf:ResourceDictionary>
|
|
@ -36,6 +36,7 @@ namespace BizHawk.Client.Common
|
|||
public const string OpenRom = "OpenRom";
|
||||
public const string Libretro = "Libretro";
|
||||
public const string LibretroNoGame = "LibretroNoGame";
|
||||
public const string MAME = "MAME";
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,12 +56,33 @@ namespace BizHawk.Client.Common
|
|||
string type = text.Substring(0, idx);
|
||||
string token = text.Substring(idx + 1);
|
||||
IOpenAdvanced ioa;
|
||||
if (type == OpenAdvancedTypes.OpenRom) ioa = new OpenAdvanced_OpenRom();
|
||||
else if (type == OpenAdvancedTypes.Libretro) ioa = new OpenAdvanced_Libretro();
|
||||
else if (type == OpenAdvancedTypes.LibretroNoGame) ioa = new OpenAdvanced_LibretroNoGame();
|
||||
else ioa = null;
|
||||
if (ioa == null)
|
||||
throw new InvalidOperationException($"{nameof(IOpenAdvanced)} deserialization error");
|
||||
|
||||
if (type == OpenAdvancedTypes.OpenRom)
|
||||
{
|
||||
ioa = new OpenAdvanced_OpenRom();
|
||||
}
|
||||
else if (type == OpenAdvancedTypes.Libretro)
|
||||
{
|
||||
ioa = new OpenAdvanced_Libretro();
|
||||
}
|
||||
else if (type == OpenAdvancedTypes.LibretroNoGame)
|
||||
{
|
||||
ioa = new OpenAdvanced_LibretroNoGame();
|
||||
}
|
||||
else if (type == OpenAdvancedTypes.MAME)
|
||||
{
|
||||
ioa = new OpenAdvanced_MAME();
|
||||
}
|
||||
else
|
||||
{
|
||||
ioa = null;
|
||||
}
|
||||
|
||||
if (ioa == null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(IOpenAdvanced)} deserialization error");
|
||||
}
|
||||
|
||||
ioa.Deserialize(token);
|
||||
return ioa;
|
||||
}
|
||||
|
@ -161,4 +183,26 @@ namespace BizHawk.Client.Common
|
|||
tw.Write(Path);
|
||||
}
|
||||
}
|
||||
|
||||
public class OpenAdvanced_MAME : IOpenAdvanced
|
||||
{
|
||||
public OpenAdvanced_MAME()
|
||||
{ }
|
||||
|
||||
public string Path;
|
||||
|
||||
public string TypeName { get { return "MAME"; } }
|
||||
public string DisplayName { get { return Path; } }
|
||||
public string SimplePath { get { return Path; } }
|
||||
|
||||
public void Deserialize(string str)
|
||||
{
|
||||
Path = str;
|
||||
}
|
||||
|
||||
public void Serialize(TextWriter tw)
|
||||
{
|
||||
tw.Write(Path);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -89,17 +89,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (!Frozen)
|
||||
{
|
||||
var removed = false;
|
||||
foreach (var recent in recentlist.ToList())
|
||||
{
|
||||
if (string.Compare(newFile, recent, StringComparison.CurrentCultureIgnoreCase) == 0)
|
||||
{
|
||||
recentlist.Remove(newFile); // intentionally keeps iterating after this to remove duplicate instances, though those should never exist in the first place
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
return recentlist.RemoveAll(recent => string.Compare(newFile, recent, StringComparison.CurrentCultureIgnoreCase) == 0) != 0; // none removed => return false
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -24,6 +24,7 @@ using BizHawk.Emulation.Cores.Sega.Saturn;
|
|||
using BizHawk.Emulation.Cores.Sony.PSP;
|
||||
using BizHawk.Emulation.Cores.Sony.PSX;
|
||||
using BizHawk.Emulation.Cores.Computers.SinclairSpectrum;
|
||||
using BizHawk.Emulation.Cores.Arcades.MAME;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
|
||||
using GPGX64 = BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
|
||||
|
@ -171,7 +172,7 @@ namespace BizHawk.Client.Common
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool AsLibretro { get; set; }
|
||||
public AdvancedRomLoaderType AdvancedLoader { get; set; }
|
||||
|
||||
private bool HandleArchiveBinding(HawkFile file)
|
||||
{
|
||||
|
@ -268,8 +269,13 @@ namespace BizHawk.Client.Common
|
|||
// only try mounting a file if a filename was given
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
// lets not use this unless we need to
|
||||
// file.NonArchiveExtensions = romExtensions;
|
||||
// MAME uses these extensions for arcade ROMs, but also accepts all sorts of variations of archives, folders, and files. if we let archive loader handle this, it won't know where to stop, since it'd require MAME's ROM database (which contains ROM names and blob hashes) to look things up, and even then it might be confused by archive/folder structure
|
||||
// so assume the user provides the proper ROM directly, and handle possible errors later
|
||||
if (AdvancedLoader == AdvancedRomLoaderType.MAMELaunchGame)
|
||||
{
|
||||
file.NonArchiveExtensions = new[] { ".zip", ".7z" };
|
||||
}
|
||||
|
||||
file.Open(path);
|
||||
|
||||
// if the provided file doesnt even exist, give up!
|
||||
|
@ -289,7 +295,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
string ext = null;
|
||||
|
||||
if (AsLibretro)
|
||||
if (AdvancedLoader == AdvancedRomLoaderType.LibretroLaunchGame)
|
||||
{
|
||||
string codePathPart = Path.GetFileNameWithoutExtension(nextComm.LaunchLibretroCore);
|
||||
|
||||
|
@ -1152,6 +1158,9 @@ namespace BizHawk.Client.Common
|
|||
nextEmulator = new Octoshock(nextComm, null, null, rom.FileData, GetCoreSettings<Octoshock>(), GetCoreSyncSettings<Octoshock>());
|
||||
nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
|
||||
break;
|
||||
case "Arcade":
|
||||
nextEmulator = new MAME(nextComm, file.Directory, file.CanonicalName);
|
||||
break;
|
||||
case "GEN":
|
||||
if (Global.Config.CoreForcingViaGameDB && game.ForcedCore?.ToLower() == "pico")
|
||||
{
|
||||
|
|
|
@ -97,12 +97,6 @@ namespace BizHawk.Client.Common
|
|||
return _redo[slot];
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
ClearRedoList();
|
||||
Update();
|
||||
}
|
||||
|
||||
public void SwapBackupSavestate(string path)
|
||||
{
|
||||
// Takes the .state and .bak files and swaps them
|
||||
|
|
|
@ -223,6 +223,11 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
public static SystemInfo ChannelF { get; } = new SystemInfo("Channel F", CoreSystem.ChannelF, 2);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="SystemInfo"/> instance for MAME
|
||||
/// </summary>
|
||||
public static SystemInfo MAME { get; } = new SystemInfo("MAME", CoreSystem.MAME, 4);
|
||||
|
||||
#endregion Get SystemInfo
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -96,13 +96,8 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
List<Binding> entriesToRemove = (from entry in Bindings let binding = DefaultValues.FirstOrDefault(b => b.DisplayName == entry.DisplayName) where binding == null select entry).ToList();
|
||||
|
||||
// Remove entries that no longer exist in defaults
|
||||
foreach (Binding entry in entriesToRemove)
|
||||
{
|
||||
Bindings.Remove(entry);
|
||||
}
|
||||
Bindings.RemoveAll(entry => DefaultValues.All(b => b.DisplayName != entry.DisplayName));
|
||||
}
|
||||
|
||||
private static List<Binding> _defaultValues;
|
||||
|
|
|
@ -104,6 +104,8 @@ namespace BizHawk.Client.Common
|
|||
public int MainHeight = -1;
|
||||
public bool RunInBackground = true;
|
||||
public bool AcceptBackgroundInput = false;
|
||||
public bool AcceptBackgroundInputControllerOnly = false;
|
||||
public bool HandleAlternateKeyboardLayouts = false;
|
||||
public bool SingleInstanceMode = false;
|
||||
public bool AllowUD_LR = false;
|
||||
public bool ForbidUD_LR = false;
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
// Add missing displaynames
|
||||
var missingDisplayPaths = Paths.Where(p => p.SystemDisplayName == null).ToList();
|
||||
var missingDisplayPaths = Paths.Where(p => p.SystemDisplayName == null);
|
||||
foreach (PathEntry path in missingDisplayPaths)
|
||||
{
|
||||
path.SystemDisplayName = DefaultValues.First(p => p.System == path.System).SystemDisplayName;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a method to be called when a tool dialog's Restore Defaults method is called
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class RestoreDefaultsAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -50,78 +50,66 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void CallSaveStateEvent(string name)
|
||||
{
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnSavestateSave").ToList();
|
||||
if (lfs.Any())
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnSavestateSave");
|
||||
try
|
||||
{
|
||||
try
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
lf.Call(name);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onsavestate\nError message: {e.Message}");
|
||||
lf.Call(name);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onsavestate\nError message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void CallLoadStateEvent(string name)
|
||||
{
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnSavestateLoad").ToList();
|
||||
if (lfs.Any())
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnSavestateLoad");
|
||||
try
|
||||
{
|
||||
try
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
lf.Call(name);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onloadstate\nError message: {e.Message}");
|
||||
lf.Call(name);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onloadstate\nError message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void CallFrameBeforeEvent()
|
||||
{
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnFrameStart").ToList();
|
||||
if (lfs.Any())
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnFrameStart");
|
||||
try
|
||||
{
|
||||
try
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
lf.Call();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onframestart\nError message: {e.Message}");
|
||||
lf.Call();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onframestart\nError message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void CallFrameAfterEvent()
|
||||
{
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnFrameEnd").ToList();
|
||||
if (lfs.Any())
|
||||
var lfs = _luaFunctions.Where(l => l.Event == "OnFrameEnd");
|
||||
try
|
||||
{
|
||||
try
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
foreach (var lf in lfs)
|
||||
{
|
||||
lf.Call();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onframeend\nError message: {e.Message}");
|
||||
lf.Call();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"error running function attached by lua function event.onframeend\nError message: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private bool N64CoreTypeDynarec()
|
||||
|
|
|
@ -48,6 +48,11 @@
|
|||
|
||||
public void Stop()
|
||||
{
|
||||
if (Thread == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
State = RunState.Disabled;
|
||||
//if(NLua.Lua.WhichLua == "NLua")
|
||||
Thread.GetTable("keepalives")[Thread] = null;
|
||||
|
|
|
@ -140,11 +140,19 @@ namespace BizHawk.Client.Common
|
|||
var sb = new StringBuilder();
|
||||
foreach (var file in this)
|
||||
{
|
||||
sb
|
||||
.Append(file.Enabled ? "1" : "0")
|
||||
.Append(' ')
|
||||
.Append(PathManager.MakeRelativeTo(PathManager.MakeAbsolutePath(file.Path, ""), Path.GetDirectoryName(path)))
|
||||
.AppendLine();
|
||||
if (file.IsSeparator)
|
||||
{
|
||||
sb.AppendLine("---");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb
|
||||
.Append(file.Enabled ? "1" : "0")
|
||||
.Append(' ')
|
||||
.Append(PathManager.MakeRelativeTo(PathManager.MakeAbsolutePath(file.Path, "")
|
||||
, Path.GetDirectoryName(path)))
|
||||
.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
sw.Write(sb.ToString());
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
var def = Global.Emulator.ControllerDefinition;
|
||||
var trimmed = mnemonic.Replace("|", "");
|
||||
var buttons = Definition.ControlsOrdered.SelectMany(c => c).ToList();
|
||||
var buttons = Definition.ControlsOrdered.SelectMany(c => c);
|
||||
var iterator = 0;
|
||||
|
||||
foreach (var key in buttons)
|
||||
|
|
|
@ -338,7 +338,7 @@ namespace BizHawk.Client.Common.MovieConversionExtensions
|
|||
if (Global.Emulator is SMS && (Global.Emulator as SMS).IsSG1000)
|
||||
{
|
||||
movie.HeaderEntries.Add("IsSGMode", "1");
|
||||
}
|
||||
}
|
||||
|
||||
if (Global.Emulator is SMS && (Global.Emulator as SMS).IsGameGear)
|
||||
{
|
||||
|
|
|
@ -68,14 +68,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public class ImportResult
|
||||
{
|
||||
public ImportResult()
|
||||
{
|
||||
Warnings = new List<string>();
|
||||
Errors = new List<string>();
|
||||
}
|
||||
|
||||
public IList<string> Warnings { get; private set; }
|
||||
public IList<string> Errors { get; }
|
||||
public IList<string> Warnings { get; } = new List<string>();
|
||||
public IList<string> Errors { get; } = new List<string>();
|
||||
|
||||
public Bk2Movie Movie { get; set; }
|
||||
}
|
||||
|
@ -88,6 +82,6 @@ namespace BizHawk.Client.Common
|
|||
Extension = extension;
|
||||
}
|
||||
|
||||
public string Extension { get; private set; }
|
||||
public string Extension { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,23 +42,16 @@ namespace BizHawk.Client.Common
|
|||
public static void ProcessMovieImport(string fn, Action<string> conversionErrorCallback, Action<string> messageCallback)
|
||||
{
|
||||
var d = PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null);
|
||||
string errorMsg;
|
||||
string warningMsg;
|
||||
var m = ImportFile(fn, out errorMsg, out warningMsg);
|
||||
var m = ImportFile(fn, out var errorMsg, out var warningMsg);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(errorMsg))
|
||||
{
|
||||
conversionErrorCallback(errorMsg);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(warningMsg))
|
||||
{
|
||||
messageCallback(warningMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
messageCallback($"{Path.GetFileName(fn)} imported as {m.Filename}");
|
||||
}
|
||||
messageCallback(!string.IsNullOrWhiteSpace(warningMsg)
|
||||
? warningMsg
|
||||
: $"{Path.GetFileName(fn)} imported as {m.Filename}");
|
||||
|
||||
if (!Directory.Exists(d))
|
||||
{
|
||||
|
@ -67,7 +60,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
// Attempt to import another type of movie file into a movie object.
|
||||
public static Bk2Movie ImportFile(string path, out string errorMsg, out string warningMsg)
|
||||
public static IMovie ImportFile(string path, out string errorMsg, out string warningMsg)
|
||||
{
|
||||
errorMsg = "";
|
||||
warningMsg = "";
|
||||
|
@ -118,25 +111,15 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private static IEnumerable<Type> ImportersForExtension(string ext)
|
||||
{
|
||||
var info = typeof(MovieImport).Module;
|
||||
var importers = from t in info.GetTypes()
|
||||
where typeof(IMovieImport).IsAssignableFrom(t)
|
||||
&& TypeImportsExtension(t, ext)
|
||||
select t;
|
||||
|
||||
return importers;
|
||||
return typeof(MovieImport).Module
|
||||
.GetTypes()
|
||||
.Where(t => typeof(IMovieImport).IsAssignableFrom(t));
|
||||
}
|
||||
|
||||
private static bool TypeImportsExtension(Type t, string ext)
|
||||
{
|
||||
var attrs = (ImportExtensionAttribute[])t.GetCustomAttributes(typeof(ImportExtensionAttribute), inherit: false);
|
||||
|
||||
if (attrs.Any(a => a.Extension.ToUpper() == ext.ToUpper()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return attrs.Any(a => a.Extension.ToUpper() == ext.ToUpper());
|
||||
}
|
||||
|
||||
private static BkmMovie LegacyImportFile(string ext, string path, out string errorMsg, out string warningMsg)
|
||||
|
@ -252,9 +235,12 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private static IController EmptyLmsvFrame(string line)
|
||||
{
|
||||
var emptyController = new SimpleController { Definition = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
emptyController["Reset"] = false;
|
||||
emptyController["Power"] = false;
|
||||
var emptyController = new SimpleController
|
||||
{
|
||||
Definition = new ControllerDefinition { Name = "SNES Controller" }
|
||||
, ["Reset"] = false
|
||||
, ["Power"] = false
|
||||
};
|
||||
|
||||
string[] buttons = { "B", "Y", "Select", "Start", "Up", "Down", "Left", "Right", "A", "X", "L", "R" };
|
||||
string[] sections = line.Split('|');
|
||||
|
@ -263,9 +249,9 @@ namespace BizHawk.Client.Common
|
|||
int player = section - 1; // We start with 1
|
||||
string prefix = $"P{player} "; // "P1"
|
||||
|
||||
for (int button = 0; button < buttons.Length; button++)
|
||||
foreach (var b in buttons)
|
||||
{
|
||||
emptyController[prefix + buttons[button]] = false;
|
||||
emptyController[prefix + b] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void RemoveRange(IEnumerable<Cheat> cheats)
|
||||
{
|
||||
foreach (var cheat in cheats.ToList())
|
||||
foreach (var cheat in cheats.ToList()) // enumerate passed IEnumerable because it may depend on the value of _cheatList
|
||||
{
|
||||
_cheatList.Remove(cheat);
|
||||
}
|
||||
|
@ -232,12 +232,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void RemoveRange(IEnumerable<Watch> watches)
|
||||
{
|
||||
var removeList = _cheatList.Where(cheat => watches.Any(w => w == cheat)).ToList();
|
||||
foreach (var cheat in removeList)
|
||||
{
|
||||
_cheatList.Remove(cheat);
|
||||
}
|
||||
|
||||
_cheatList.RemoveAll(cheat => watches.Any(w => w == cheat));
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
@ -389,7 +384,9 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
// Set to hex for saving
|
||||
// Set to hex for saving
|
||||
var temp_cheat_type = cheat.Type;
|
||||
|
||||
cheat.SetType(DisplayType.Hex);
|
||||
|
||||
sb
|
||||
|
@ -404,6 +401,9 @@ namespace BizHawk.Client.Common
|
|||
.Append((cheat.BigEndian ?? false) ? '1' : '0').Append('\t')
|
||||
.Append(cheat.ComparisonType).Append('\t')
|
||||
.AppendLine();
|
||||
|
||||
cheat.SetType(temp_cheat_type);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -341,8 +341,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
var addresses = watches.Select(w => w.Address);
|
||||
var removeList = _watchList.Where(w => addresses.Contains(w.Address)).ToList();
|
||||
_watchList = _watchList.Except(removeList).ToList();
|
||||
_watchList.RemoveAll(w => addresses.Contains(w.Address));
|
||||
}
|
||||
|
||||
public void RemoveRange(IEnumerable<int> indices)
|
||||
|
|
|
@ -388,15 +388,8 @@ namespace BizHawk.Client.Common
|
|||
/// <returns><see cref="Watch"/> at the specified index</returns>
|
||||
public Watch this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _watchList[index];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_watchList[index] = value;
|
||||
}
|
||||
get => _watchList[index];
|
||||
set => _watchList[index] = value;
|
||||
}
|
||||
|
||||
#endregion IList<Watch>
|
||||
|
@ -607,14 +600,7 @@ namespace BizHawk.Client.Common
|
|||
CurrentFileName = path;
|
||||
}
|
||||
|
||||
if (!append)
|
||||
{
|
||||
Changes = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Changes = true;
|
||||
}
|
||||
Changes = append;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CSharp-SQLite">
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp60</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp80</s:String></wpf:ResourceDictionary>
|
|
@ -188,11 +188,11 @@ namespace BizHawk.Client.DBMan
|
|||
// process dump info flags and other info contained in []
|
||||
if (nameString.Contains("[") && nameString.Contains("]"))
|
||||
{
|
||||
List<string> e = nameString.ToString().Split('[', ']').ToList();
|
||||
// remove first entry (this is the bit before the [] entries start
|
||||
e.RemoveAt(0);
|
||||
// remove empty entries
|
||||
e = e.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
|
||||
var e = nameString.Split('[', ']')
|
||||
.Skip(1) // remove first entry (this is the bit before the [] entries start)
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s)) // remove empty entries
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (e.Count > 0)
|
||||
{
|
||||
|
|
|
@ -206,11 +206,11 @@ namespace BizHawk.Client.DBMan
|
|||
// process dump info flags and other info contained in []
|
||||
if (nameString.Contains("[") && nameString.Contains("]"))
|
||||
{
|
||||
List<string> e = nameString.ToString().Split('[', ']').ToList();
|
||||
// remove first entry (this is the bit before the [] entries start
|
||||
e.RemoveAt(0);
|
||||
// remove empty entries
|
||||
e = e.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
|
||||
var e = nameString.Split('[', ']')
|
||||
.Skip(1) // remove first entry (this is the bit before the [] entries start)
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s)) // remove empty entries
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (e.Count > 0)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoWin32Manifest>true</NoWin32Manifest>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp60</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp80</s:String></wpf:ResourceDictionary>
|
|
@ -23,15 +23,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
.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)));
|
||||
.Concat(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)
|
||||
{
|
||||
|
|
|
@ -48,8 +48,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
.Select(t => t.GetCustomAttributes(false).OfType<CoreAttribute>().FirstOrDefault())
|
||||
.Where(a => a != null)
|
||||
.Where(a => a.Released)
|
||||
.OrderByDescending(a => a.CoreName.ToLower())
|
||||
.ToList();
|
||||
.OrderByDescending(a => a.CoreName.ToLower());
|
||||
|
||||
foreach (var core in cores)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoWin32Manifest>true</NoWin32Manifest>
|
||||
|
@ -84,7 +85,7 @@
|
|||
<HintPath>..\output\dll\nlua\NLua.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="OpenTK, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||
<Reference Include="OpenTK, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\References\OpenTK.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -566,6 +567,8 @@
|
|||
<Compile Include="CoreFeatureAnalysis.Designer.cs">
|
||||
<DependentUpon>CoreFeatureAnalysis.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\ControlRenderer\GdiPlusRenderer.cs" />
|
||||
<Compile Include="CustomControls\ControlRenderer\IControlRenderer.cs" />
|
||||
<Compile Include="CustomControls\ExceptionBox.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -575,7 +578,7 @@
|
|||
<Compile Include="CustomControls\FolderBrowserDialogEx.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\GDIRenderer.cs" />
|
||||
<Compile Include="CustomControls\ControlRenderer\GDIRenderer.cs" />
|
||||
<Compile Include="CustomControls\HexTextBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
@ -585,21 +588,17 @@
|
|||
<Compile Include="CustomControls\InputConfigBase.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll.cs">
|
||||
<Compile Include="CustomControls\InputRoll\Cell.cs" />
|
||||
<Compile Include="CustomControls\InputRoll\ColumnType.cs" />
|
||||
<Compile Include="CustomControls\InputRoll\InputRoll.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll.Drawing.cs">
|
||||
<DependentUpon>InputRoll.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll.Drawing.GDI.cs">
|
||||
<DependentUpon>InputRoll.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll.Drawing.GDIP.cs">
|
||||
<Compile Include="CustomControls\InputRoll\InputRoll.Drawing.cs">
|
||||
<DependentUpon>InputRoll.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\InputRoll\RollColumn.cs" />
|
||||
<Compile Include="CustomControls\InputRoll\RollColumns.cs" />
|
||||
<Compile Include="CustomControls\MenuButton.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
@ -612,30 +611,6 @@
|
|||
<Compile Include="CustomControls\MsgBox.designer.cs">
|
||||
<DependentUpon>MsgBox.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.API.cs">
|
||||
<DependentUpon>PlatformAgnosticVirtualListView.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.Classes.cs">
|
||||
<DependentUpon>PlatformAgnosticVirtualListView.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.Drawing.cs">
|
||||
<DependentUpon>PlatformAgnosticVirtualListView.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.EventHandlers.cs">
|
||||
<DependentUpon>PlatformAgnosticVirtualListView.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.Helpers.cs">
|
||||
<DependentUpon>PlatformAgnosticVirtualListView.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.Properties.cs">
|
||||
<DependentUpon>PlatformAgnosticVirtualListView.cs</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PrereqsAlert.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -660,9 +635,6 @@
|
|||
<Compile Include="CustomControls\SmartTextBoxControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\TasListView.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\TextDebugView.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
@ -672,7 +644,6 @@
|
|||
<Compile Include="CustomControls\ViewportPanel.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\VirtualListView.cs" />
|
||||
<Compile Include="CustomControls\Win32.cs" />
|
||||
<Compile Include="DisplayManager\DisplayManager.cs" />
|
||||
<Compile Include="DisplayManager\DisplaySurface.cs" />
|
||||
|
@ -685,9 +656,11 @@
|
|||
<Compile Include="DisplayManager\RenderTargetFrugalizer.cs" />
|
||||
<Compile Include="DisplayManager\SwappableDisplaySurfaceSet.cs" />
|
||||
<Compile Include="DisplayManager\TextureFrugalizer.cs" />
|
||||
<Compile Include="EmuHawkUtil.cs" />
|
||||
<Compile Include="Extensions\ControlExtensions.cs" />
|
||||
<Compile Include="Extensions\CoreExtensions.cs" />
|
||||
<Compile Include="Extensions\ToolExtensions.cs" />
|
||||
<Compile Include="FileFilterEntry.cs" />
|
||||
<Compile Include="FileLoader.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -704,6 +677,7 @@
|
|||
<Compile Include="Input\GamePad.cs" />
|
||||
<Compile Include="Input\GamePad360.cs" />
|
||||
<Compile Include="Input\Input.cs" />
|
||||
<Compile Include="Input\KeyboardMapping.cs" />
|
||||
<Compile Include="Input\OTK_Gamepad.cs" />
|
||||
<Compile Include="Input\OTK_Keyboard.cs" />
|
||||
<Compile Include="IControlMainform.cs" />
|
||||
|
@ -779,9 +753,6 @@
|
|||
<Compile Include="OpenAdvancedChooser.Designer.cs">
|
||||
<DependentUpon>OpenAdvancedChooser.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="CustomControls\PlatformAgnosticVirtualListView.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="PlatformChooser.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -814,12 +785,6 @@
|
|||
<Compile Include="Sound\Utilities\SoundOutputProvider.cs" />
|
||||
<Compile Include="Throttle.cs" />
|
||||
<Compile Include="ToolAttribute.cs" />
|
||||
<Compile Include="tools\AutoHawk.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="tools\AutoHawk.Designer.cs">
|
||||
<DependentUpon>AutoHawk.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="tools\BasicBot\BasicBot.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -1553,9 +1518,6 @@
|
|||
<EmbeddedResource Include="CustomControls\QuickProgressPopup.resx">
|
||||
<DependentUpon>QuickProgressPopup.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="CustomControls\TasListView.resx">
|
||||
<DependentUpon>TasListView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -1584,9 +1546,6 @@
|
|||
<EmbeddedResource Include="RomStatusPicker.resx">
|
||||
<DependentUpon>RomStatusPicker.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="tools\AutoHawk.resx">
|
||||
<DependentUpon>AutoHawk.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="tools\BasicBot\BasicBot.resx">
|
||||
<DependentUpon>BasicBot.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
@ -1899,6 +1858,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="app.manifest" />
|
||||
<None Include="images\FindHS.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1926,6 +1886,8 @@
|
|||
<None Include="config\ControllerImages\GENController.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="images\StopButton.png" />
|
||||
<None Include="images\mame.png" />
|
||||
<None Include="Resources\MoveTop.png" />
|
||||
<None Include="Resources\MoveBottom.png" />
|
||||
<None Include="Resources\MoveTop.bmp" />
|
||||
|
@ -2255,6 +2217,7 @@
|
|||
<None Include="images\ESE.png" />
|
||||
<None Include="images\ControllerImages\NGPController.png" />
|
||||
<Content Include="config\ControllerImages\ZXSpectrumKeyboards.png" />
|
||||
<None Include="images\ControllerImages\ArcadeController.jpg" />
|
||||
<Content Include="images\logo.ico" />
|
||||
<None Include="images\Paste.png" />
|
||||
<None Include="images\reboot.png" />
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp60</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp80</s:String></wpf:ResourceDictionary>
|
|
@ -0,0 +1,505 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk.CustomControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for GDI rendering functions
|
||||
/// This class is not thread-safe as GDI functions should be called from the UI thread
|
||||
/// </summary>
|
||||
public sealed class GdiRenderer : IControlRenderer
|
||||
{
|
||||
// Cache of all the Fonts used, rather than create them again and again
|
||||
private readonly Dictionary<Font, FontCacheEntry> _fontsCache = new Dictionary<Font, FontCacheEntry>();
|
||||
|
||||
private class FontCacheEntry
|
||||
{
|
||||
public IntPtr HFont;
|
||||
public IntPtr RotatedHFont;
|
||||
}
|
||||
|
||||
// Cache of all the brushes used, rather than create them again and again
|
||||
private readonly Dictionary<Color, IntPtr> _brushCache = new Dictionary<Color, IntPtr>();
|
||||
|
||||
private Graphics _g;
|
||||
private IntPtr _hdc;
|
||||
private IntPtr _currentBrush = IntPtr.Zero;
|
||||
|
||||
#region Construct and Destroy
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var brush in _brushCache)
|
||||
{
|
||||
if (brush.Value != IntPtr.Zero)
|
||||
{
|
||||
DeleteObject(brush.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var fc in _fontsCache)
|
||||
{
|
||||
DeleteObject(fc.Value.HFont);
|
||||
DeleteObject(fc.Value.RotatedHFont);
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.Assert(_hdc == IntPtr.Zero, "Disposed a GDIRenderer while it held an HDC");
|
||||
System.Diagnostics.Debug.Assert(_g == null, "Disposed a GDIRenderer while it held a Graphics");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Api
|
||||
|
||||
public void DrawBitmap(Bitmap bitmap, Point point)
|
||||
{
|
||||
IntPtr hBmp = bitmap.GetHbitmap();
|
||||
var bitHdc = CreateCompatibleDC(CurrentHdc);
|
||||
IntPtr old = SelectObject(bitHdc, hBmp);
|
||||
AlphaBlend(CurrentHdc, point.X, point.Y, bitmap.Width, bitmap.Height, bitHdc, 0, 0, bitmap.Width, bitmap.Height, new BLENDFUNCTION(AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA));
|
||||
SelectObject(bitHdc, old);
|
||||
DeleteDC(bitHdc);
|
||||
DeleteObject(hBmp);
|
||||
}
|
||||
|
||||
public IDisposable LockGraphics(Graphics g, int width, int height)
|
||||
{
|
||||
_g = g;
|
||||
_hdc = g.GetHdc();
|
||||
SetBkMode(_hdc, BkModes.TRANSPARENT);
|
||||
var l = new GdiGraphicsLock(this);
|
||||
StartOffScreenBitmap(width, height);
|
||||
return l;
|
||||
}
|
||||
|
||||
public Size MeasureString(string str, Font font)
|
||||
{
|
||||
SetFont(font);
|
||||
|
||||
var size = new Size();
|
||||
GetTextExtentPoint32(CurrentHdc, str, str.Length, ref size);
|
||||
return size;
|
||||
}
|
||||
|
||||
public void DrawString(string str, Point point)
|
||||
{
|
||||
TextOut(CurrentHdc, point.X, point.Y, str, str.Length);
|
||||
}
|
||||
|
||||
public static IntPtr CreateNormalHFont(Font font, int width)
|
||||
{
|
||||
var logFont = new LOGFONT();
|
||||
font.ToLogFont(logFont);
|
||||
logFont.lfWidth = width;
|
||||
logFont.lfOutPrecision = (byte)FontPrecision.OUT_TT_ONLY_PRECIS;
|
||||
var ret = CreateFontIndirect(logFont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//this returns an IntPtr font because .net's Font class will erase the relevant properties when using its Font.FromLogFont()
|
||||
//note that whether this is rotated clockwise or CCW might affect how you have to position the text (right-aligned sometimes?, up or down by the height of the font?)
|
||||
public static IntPtr CreateRotatedHFont(Font font, bool cw)
|
||||
{
|
||||
LOGFONT logF = new LOGFONT();
|
||||
font.ToLogFont(logF);
|
||||
logF.lfEscapement = cw ? 2700 : 900;
|
||||
logF.lfOrientation = logF.lfEscapement;
|
||||
logF.lfOutPrecision = (byte)FontPrecision.OUT_TT_ONLY_PRECIS;
|
||||
|
||||
var ret = CreateFontIndirect(logF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: this should go away and be abstracted internally
|
||||
public static void DestroyHFont(IntPtr hFont)
|
||||
{
|
||||
DeleteObject(hFont);
|
||||
}
|
||||
|
||||
public void PrepDrawString(Font font, Color color, bool rotate = false)
|
||||
{
|
||||
var fontEntry = GetCachedHFont(font);
|
||||
SetGraphicsMode(CurrentHdc, 2); // shouldn't be necessary.. cant hurt
|
||||
SelectObject(CurrentHdc, rotate ? fontEntry.RotatedHFont : fontEntry.HFont);
|
||||
SetTextColor(color);
|
||||
}
|
||||
|
||||
// Set the text color of the device context
|
||||
private void SetTextColor(Color color)
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
SetTextColor(CurrentHdc, rgb);
|
||||
}
|
||||
|
||||
public void DrawRectangle(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
|
||||
{
|
||||
Rectangle(CurrentHdc, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
||||
}
|
||||
|
||||
public void SetBrush(Color color)
|
||||
{
|
||||
if (_brushCache.ContainsKey(color))
|
||||
{
|
||||
_currentBrush = _brushCache[color];
|
||||
}
|
||||
else
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
var newBrush = CreateSolidBrush(rgb);
|
||||
_brushCache.Add(color, newBrush);
|
||||
_currentBrush = newBrush;
|
||||
}
|
||||
}
|
||||
|
||||
public void FillRectangle(int x, int y, int w, int h)
|
||||
{
|
||||
var r = new GDIRect(new Rectangle(x, y, w, h));
|
||||
FillRect(CurrentHdc, ref r, _currentBrush);
|
||||
}
|
||||
|
||||
public void SetSolidPen(Color color)
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
SelectObject(CurrentHdc, GetStockObject((int)PaintObjects.DC_PEN));
|
||||
SetDCPenColor(CurrentHdc, rgb);
|
||||
}
|
||||
|
||||
public void Line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
MoveToEx(CurrentHdc, x1, y1, IntPtr.Zero);
|
||||
LineTo(CurrentHdc, x2, y2);
|
||||
}
|
||||
|
||||
private IntPtr CurrentHdc => _bitHdc != IntPtr.Zero ? _bitHdc : _hdc;
|
||||
|
||||
private IntPtr _bitMap = IntPtr.Zero;
|
||||
private IntPtr _bitHdc = IntPtr.Zero;
|
||||
private int _bitW;
|
||||
private int _bitH;
|
||||
|
||||
private void StartOffScreenBitmap(int width, int height)
|
||||
{
|
||||
_bitW = width;
|
||||
_bitH = height;
|
||||
|
||||
_bitHdc = CreateCompatibleDC(_hdc);
|
||||
_bitMap = CreateCompatibleBitmap(_hdc, width, height);
|
||||
SelectObject(_bitHdc, _bitMap);
|
||||
SetBkMode(_bitHdc, BkModes.TRANSPARENT);
|
||||
}
|
||||
|
||||
private void EndOffScreenBitmap()
|
||||
{
|
||||
_bitW = 0;
|
||||
_bitH = 0;
|
||||
|
||||
DeleteObject(_bitMap);
|
||||
DeleteObject(_bitHdc);
|
||||
|
||||
_bitHdc = IntPtr.Zero;
|
||||
_bitMap = IntPtr.Zero;
|
||||
}
|
||||
|
||||
private void CopyToScreen()
|
||||
{
|
||||
BitBlt(_hdc, 0, 0, _bitW, _bitH, _bitHdc, 0, 0, 0x00CC0020);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
// Set a resource (e.g. a font) for the current device context.
|
||||
private void SetFont(Font font)
|
||||
{
|
||||
var blah = GetCachedHFont(font);
|
||||
SelectObject(CurrentHdc, blah.HFont);
|
||||
}
|
||||
|
||||
private FontCacheEntry GetCachedHFont(Font font)
|
||||
{
|
||||
FontCacheEntry fontEntry;
|
||||
var result = _fontsCache.TryGetValue(font, out fontEntry);
|
||||
if (!result)
|
||||
{
|
||||
// Hack! The 6 is hardcoded to make tastudio look like taseditor, because taseditor is so perfect and wonderful
|
||||
fontEntry = new FontCacheEntry
|
||||
{
|
||||
HFont = CreateNormalHFont(font, 6),
|
||||
RotatedHFont = CreateRotatedHFont(font, true)
|
||||
};
|
||||
_fontsCache.Add(font, fontEntry);
|
||||
}
|
||||
|
||||
return fontEntry;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
// ReSharper disable IdentifierTypo
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr CreateFontIndirect(
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)]LOGFONT lplf
|
||||
);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int Rectangle(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int FillRect(IntPtr hdc, [In] ref GDIRect lprc, IntPtr hbr);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int SetBkMode(IntPtr hdc, BkModes mode);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
|
||||
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiObj);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int SetTextColor(IntPtr hdc, int color);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "GetTextExtentPoint32W")]
|
||||
private static extern int GetTextExtentPoint32(IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] string str, int len, ref Size size);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "TextOutW")]
|
||||
private static extern bool TextOut(IntPtr hdc, int x, int y, [MarshalAs(UnmanagedType.LPWStr)] string str, int len);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
public static extern int SetGraphicsMode(IntPtr hdc, int iMode);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern bool DeleteObject(IntPtr hObject);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateSolidBrush(int color);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, IntPtr point);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr LineTo(IntPtr hdc, int nXEnd, int nYEnd);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr GetStockObject(int fnObject);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr SetDCPenColor(IntPtr hdc, int crColor);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
|
||||
public static extern bool DeleteDC([In] IntPtr hdc);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "GdiAlphaBlend")]
|
||||
static extern bool AlphaBlend(IntPtr hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, BLENDFUNCTION blendFunction);
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
// ReSharper disable UnusedMember.Global
|
||||
// ReSharper disable UnusedMember.Local
|
||||
// ReSharper disable NotAccessedField.Local
|
||||
// ReSharper disable ArrangeTypeMemberModifiers
|
||||
public enum FontPrecision : byte
|
||||
{
|
||||
|
||||
OUT_DEFAULT_PRECIS = 0,
|
||||
OUT_STRING_PRECIS = 1,
|
||||
OUT_CHARACTER_PRECIS = 2,
|
||||
OUT_STROKE_PRECIS = 3,
|
||||
OUT_TT_PRECIS = 4,
|
||||
OUT_DEVICE_PRECIS = 5,
|
||||
OUT_RASTER_PRECIS = 6,
|
||||
OUT_TT_ONLY_PRECIS = 7,
|
||||
OUT_OUTLINE_PRECIS = 8,
|
||||
OUT_SCREEN_OUTLINE_PRECIS = 9,
|
||||
OUT_PS_ONLY_PRECIS = 10,
|
||||
}
|
||||
|
||||
// It is important for this to be the right declaration
|
||||
// See more here http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.drawing/2004-04/0319.html
|
||||
// If it's wrong (I had a wrong one from pinvoke.net) then ToLogFont will fail mysteriously
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
class LOGFONT
|
||||
{
|
||||
public int lfHeight = 0;
|
||||
public int lfWidth = 0;
|
||||
public int lfEscapement = 0;
|
||||
public int lfOrientation = 0;
|
||||
public int lfWeight = 0;
|
||||
public byte lfItalic = 0;
|
||||
public byte lfUnderline = 0;
|
||||
public byte lfStrikeOut = 0;
|
||||
public byte lfCharSet = 0;
|
||||
public byte lfOutPrecision = 0;
|
||||
public byte lfClipPrecision = 0;
|
||||
public byte lfQuality = 0;
|
||||
public byte lfPitchAndFamily = 0;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string lfFaceName = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The graphics mode that can be set by SetGraphicsMode.
|
||||
/// </summary>
|
||||
public enum GraphicsMode : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the graphics mode that is compatible with 16-bit Windows. This is the default mode. If
|
||||
/// this value is specified, the application can only modify the world-to-device transform by
|
||||
/// calling functions that set window and viewport extents and origins, but not by using
|
||||
/// SetWorldTransform or ModifyWorldTransform; calls to those functions will fail.
|
||||
/// Examples of functions that set window and viewport extents and origins are SetViewportExtEx
|
||||
/// and SetWindowExtEx.
|
||||
/// </summary>
|
||||
GM_COMPATIBLE = 1,
|
||||
/// <summary>
|
||||
/// Sets the advanced graphics mode that allows world transformations. This value must be
|
||||
/// specified if the application will set or modify the world transformation for the specified
|
||||
/// device context. In this mode all graphics, including text output, fully conform to the
|
||||
/// world-to-device transformation specified in the device context.
|
||||
/// </summary>
|
||||
GM_ADVANCED = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The XFORM structure specifies a world-space to page-space transformation.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XFORM
|
||||
{
|
||||
public float eM11;
|
||||
public float eM12;
|
||||
public float eM21;
|
||||
public float eM22;
|
||||
public float eDx;
|
||||
public float eDy;
|
||||
|
||||
public XFORM(float eM11, float eM12, float eM21, float eM22, float eDx, float eDy)
|
||||
{
|
||||
this.eM11 = eM11;
|
||||
this.eM12 = eM12;
|
||||
this.eM21 = eM21;
|
||||
this.eM22 = eM22;
|
||||
this.eDx = eDx;
|
||||
this.eDy = eDy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows implicit conversion to a managed transformation matrix.
|
||||
/// </summary>
|
||||
public static implicit operator System.Drawing.Drawing2D.Matrix(XFORM xf)
|
||||
{
|
||||
return new System.Drawing.Drawing2D.Matrix(xf.eM11, xf.eM12, xf.eM21, xf.eM22, xf.eDx, xf.eDy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows implicit conversion from a managed transformation matrix.
|
||||
/// </summary>
|
||||
public static implicit operator XFORM(System.Drawing.Drawing2D.Matrix m)
|
||||
{
|
||||
float[] elems = m.Elements;
|
||||
return new XFORM(elems[0], elems[1], elems[2], elems[3], elems[4], elems[5]);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BLENDFUNCTION
|
||||
{
|
||||
byte BlendOp;
|
||||
byte BlendFlags;
|
||||
byte SourceConstantAlpha;
|
||||
byte AlphaFormat;
|
||||
|
||||
public BLENDFUNCTION(byte op, byte flags, byte alpha, byte format)
|
||||
{
|
||||
BlendOp = op;
|
||||
BlendFlags = flags;
|
||||
SourceConstantAlpha = alpha;
|
||||
AlphaFormat = format;
|
||||
}
|
||||
}
|
||||
|
||||
const byte AC_SRC_OVER = 0x00;
|
||||
const byte AC_SRC_ALPHA = 0x01;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Classes, Structs, and Enums
|
||||
|
||||
private class GdiGraphicsLock : IDisposable
|
||||
{
|
||||
private readonly GdiRenderer _gdi;
|
||||
|
||||
public GdiGraphicsLock(GdiRenderer gdi)
|
||||
{
|
||||
_gdi = gdi;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_gdi.CopyToScreen();
|
||||
_gdi.EndOffScreenBitmap();
|
||||
_gdi._g.ReleaseHdc(_gdi._hdc);
|
||||
_gdi._hdc = IntPtr.Zero;
|
||||
_gdi._g = null;
|
||||
}
|
||||
}
|
||||
|
||||
private struct GDIRect
|
||||
{
|
||||
private int left;
|
||||
private int top;
|
||||
private int right;
|
||||
private int bottom;
|
||||
|
||||
public GDIRect(Rectangle r)
|
||||
{
|
||||
left = r.Left;
|
||||
top = r.Top;
|
||||
bottom = r.Bottom;
|
||||
right = r.Right;
|
||||
}
|
||||
}
|
||||
|
||||
private enum PaintObjects
|
||||
{
|
||||
WHITE_BRUSH = 0,
|
||||
LTGRAY_BRUSH = 1,
|
||||
GRAY_BRUSH = 2,
|
||||
DKGRAY_BRUSH = 3,
|
||||
BLACK_BRUSH = 4,
|
||||
NULL_BRUSH = 5,
|
||||
WHITE_PEN = 6,
|
||||
BLACK_PEN = 7,
|
||||
NULL_PEN = 8,
|
||||
OEM_FIXED_FONT = 10,
|
||||
ANSI_FIXED_FONT = 11,
|
||||
ANSI_VAR_FONT = 12,
|
||||
SYSTEM_FONT = 13,
|
||||
DEVICE_DEFAULT_FONT = 14,
|
||||
DEFAULT_PALETTE = 15,
|
||||
SYSTEM_FIXED_FONT = 16,
|
||||
DC_BRUSH = 18,
|
||||
DC_PEN = 19,
|
||||
}
|
||||
|
||||
private enum BkModes : int
|
||||
{
|
||||
TRANSPARENT = 1,
|
||||
OPAQUE = 2
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk.CustomControls
|
||||
{
|
||||
public class GdiPlusRenderer : IControlRenderer
|
||||
{
|
||||
private Graphics _graphics;
|
||||
|
||||
private readonly Pen _currentPen = new Pen(Color.Black);
|
||||
private readonly SolidBrush _currentBrush = new SolidBrush(Color.Black);
|
||||
private readonly SolidBrush _currentStringBrush = new SolidBrush(Color.Black);
|
||||
private readonly Font _defaultFont = new Font("Arial", 8, FontStyle.Bold);
|
||||
private Font _currentFont;
|
||||
private bool _rotateString;
|
||||
|
||||
public GdiPlusRenderer()
|
||||
{
|
||||
_currentFont = _defaultFont;
|
||||
}
|
||||
|
||||
private class GdiPlusGraphicsLock : IDisposable
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
// Nothing to do
|
||||
// Other drawing methods need a way to dispose on demand, hence the need for
|
||||
// this dummy class
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_currentPen.Dispose();
|
||||
_currentBrush.Dispose();
|
||||
_currentStringBrush.Dispose();
|
||||
_defaultFont.Dispose();
|
||||
}
|
||||
|
||||
public void DrawBitmap(Bitmap bitmap, Point point)
|
||||
{
|
||||
_graphics.DrawImage(bitmap, point);
|
||||
}
|
||||
|
||||
public void DrawRectangle(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
|
||||
{
|
||||
_graphics.DrawRectangle(
|
||||
_currentPen,
|
||||
new Rectangle(nLeftRect, nTopRect, nRightRect - nLeftRect, nBottomRect - nTopRect));
|
||||
}
|
||||
|
||||
public void DrawString(string str, Point point)
|
||||
{
|
||||
if (_rotateString)
|
||||
{
|
||||
_graphics.TranslateTransform(point.X, point.Y);
|
||||
_graphics.RotateTransform(90);
|
||||
_graphics.DrawString(str, _currentFont, _currentStringBrush, Point.Empty);
|
||||
_graphics.ResetTransform();
|
||||
}
|
||||
else
|
||||
{
|
||||
_graphics.DrawString(str, _currentFont, _currentStringBrush, point);
|
||||
}
|
||||
}
|
||||
|
||||
public void FillRectangle(int x, int y, int w, int h)
|
||||
{
|
||||
_graphics.FillRectangle(
|
||||
_currentBrush,
|
||||
new Rectangle(x, y, w, h));
|
||||
}
|
||||
|
||||
public void Line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
_graphics.DrawLine(_currentPen, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public IDisposable LockGraphics(Graphics g, int width, int height)
|
||||
{
|
||||
_graphics = g;
|
||||
return new GdiPlusGraphicsLock();
|
||||
}
|
||||
|
||||
public Size MeasureString(string str, Font font)
|
||||
{
|
||||
var size = _graphics.MeasureString(str, font);
|
||||
return new Size((int)(size.Width + 0.5), (int)(size.Height + 0.5));
|
||||
}
|
||||
|
||||
public void PrepDrawString(Font font, Color color, bool rotate = false)
|
||||
{
|
||||
_currentFont = font;
|
||||
_currentStringBrush.Color = color;
|
||||
_rotateString = rotate;
|
||||
}
|
||||
|
||||
public void SetBrush(Color color)
|
||||
{
|
||||
_currentBrush.Color = color;
|
||||
}
|
||||
|
||||
public void SetSolidPen(Color color)
|
||||
{
|
||||
_currentPen.Color = color;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk.CustomControls
|
||||
{
|
||||
public interface IControlRenderer : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Required to use before calling drawing methods
|
||||
/// </summary>
|
||||
IDisposable LockGraphics(Graphics g, int width, int height);
|
||||
|
||||
/// <summary>
|
||||
/// Measure the width and height of string <paramref name="str"/> when drawn
|
||||
/// using the given font <paramref name="font"/>
|
||||
/// </summary>
|
||||
Size MeasureString(string str, Font font);
|
||||
|
||||
void SetBrush(Color color);
|
||||
void SetSolidPen(Color color);
|
||||
|
||||
void PrepDrawString(Font font, Color color, bool rotate = false);
|
||||
|
||||
/// <summary>
|
||||
/// Draw the given string using the given font and foreground color at given location
|
||||
/// </summary>
|
||||
void DrawString(string str, Point point);
|
||||
|
||||
void DrawRectangle(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
|
||||
void FillRectangle(int x, int y, int w, int h);
|
||||
|
||||
/// <summary>
|
||||
/// Draw a bitmap object at the given position
|
||||
/// </summary>
|
||||
void DrawBitmap(Bitmap bitmap, Point point);
|
||||
void Line(int x1, int y1, int x2, int y2);
|
||||
}
|
||||
}
|
|
@ -1,769 +0,0 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk.CustomControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for GDI rendering functions
|
||||
/// This class is not thread-safe as GDI functions should be called from the UI thread
|
||||
/// </summary>
|
||||
public sealed class GDIRenderer : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// used for <see cref="MeasureString(string, System.Drawing.Font, float, out int, out int)"/> calculation.
|
||||
/// </summary>
|
||||
private static readonly int[] CharFit = new int[1];
|
||||
|
||||
/// <summary>
|
||||
/// used for <see cref="MeasureString(string, System.Drawing.Font,float, out int, out int)"/> calculation
|
||||
/// </summary>
|
||||
private static readonly int[] CharFitWidth = new int[1000];
|
||||
|
||||
/// <summary>
|
||||
/// Cache of all the HFONTs used, rather than create them again and again
|
||||
/// </summary>
|
||||
private readonly Dictionary<Font, FontCacheEntry> FontsCache = new Dictionary<Font, FontCacheEntry>();
|
||||
|
||||
class FontCacheEntry
|
||||
{
|
||||
public IntPtr HFont;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cache of all the brushes used, rather than create them again and again
|
||||
/// </summary>
|
||||
private readonly Dictionary<Color, IntPtr> BrushCache = new Dictionary<Color, IntPtr>();
|
||||
|
||||
private Graphics _g;
|
||||
private IntPtr _hdc;
|
||||
private IntPtr _currentBrush = IntPtr.Zero;
|
||||
|
||||
#region Construct and Destroy
|
||||
|
||||
public GDIRenderer()
|
||||
{
|
||||
//zero 04-16-2016 : this can't be legal, theres no HDC yet
|
||||
//SetBkMode(_hdc, BkModes.OPAQUE);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var brush in BrushCache)
|
||||
{
|
||||
if (brush.Value != IntPtr.Zero)
|
||||
{
|
||||
DeleteObject(brush.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var fc in FontsCache)
|
||||
DeleteObject(fc.Value.HFont);
|
||||
|
||||
EndOffScreenBitmap();
|
||||
|
||||
System.Diagnostics.Debug.Assert(_hdc == IntPtr.Zero, "Disposed a GDIRenderer while it held an HDC");
|
||||
System.Diagnostics.Debug.Assert(_g == null, "Disposed a GDIRenderer while it held a Graphics");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Api
|
||||
|
||||
/// <summary>
|
||||
/// Draw a bitmap object at the given position
|
||||
/// </summary>
|
||||
public void DrawBitmap(Bitmap bitmap, Point point, bool blend = false)
|
||||
{
|
||||
IntPtr hbmp = bitmap.GetHbitmap();
|
||||
var bitHDC = CreateCompatibleDC(CurrentHDC);
|
||||
IntPtr old = SelectObject(bitHDC, hbmp);
|
||||
if (blend)
|
||||
{
|
||||
AlphaBlend(CurrentHDC, point.X, point.Y, bitmap.Width, bitmap.Height, bitHDC, 0, 0, bitmap.Width, bitmap.Height, new BLENDFUNCTION(AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA));
|
||||
}
|
||||
else
|
||||
{
|
||||
BitBlt(CurrentHDC, point.X, point.Y, bitmap.Width, bitmap.Height, bitHDC, 0, 0, 0xCC0020);
|
||||
}
|
||||
SelectObject(bitHDC, old);
|
||||
DeleteDC(bitHDC);
|
||||
DeleteObject(hbmp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Required to use before calling drawing methods
|
||||
/// </summary>
|
||||
public GdiGraphicsLock LockGraphics(Graphics g)
|
||||
{
|
||||
_g = g;
|
||||
_hdc = g.GetHdc();
|
||||
SetBkMode(_hdc, BkModes.TRANSPARENT);
|
||||
return new GdiGraphicsLock(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
|
||||
/// using the given font <paramref name="font"/>
|
||||
/// </summary>
|
||||
public Size MeasureString(string str, Font font)
|
||||
{
|
||||
SetFont(font);
|
||||
|
||||
var size = new Size();
|
||||
GetTextExtentPoint32(CurrentHDC, str, str.Length, ref size);
|
||||
return size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
|
||||
/// using the given font <paramref name="font"/>
|
||||
/// Restrict the width of the string and get the number of characters able to fit in the restriction and
|
||||
/// the width those characters take
|
||||
/// </summary>
|
||||
/// <param name="maxWidth">the max width to render the string in</param>
|
||||
/// <param name="charFit">the number of characters that will fit under <see cref="maxWidth"/> restriction</param>
|
||||
public Size MeasureString(string str, Font font, float maxWidth, out int charFit, out int charFitWidth)
|
||||
{
|
||||
SetFont(font);
|
||||
|
||||
var size = new Size();
|
||||
GetTextExtentExPoint(CurrentHDC, str, str.Length, (int)Math.Round(maxWidth), CharFit, CharFitWidth, ref size);
|
||||
charFit = CharFit[0];
|
||||
charFitWidth = charFit > 0 ? CharFitWidth[charFit - 1] : 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
public void DrawString(string str, Point point)
|
||||
{
|
||||
TextOut(CurrentHDC, point.X, point.Y, str, str.Length);
|
||||
}
|
||||
|
||||
public static IntPtr CreateNormalHFont(Font font, int width)
|
||||
{
|
||||
LOGFONT logf = new LOGFONT();
|
||||
font.ToLogFont(logf);
|
||||
logf.lfWidth = width;
|
||||
logf.lfOutPrecision = (byte)FontPrecision.OUT_TT_ONLY_PRECIS;
|
||||
var ret = CreateFontIndirect(logf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//this returns an IntPtr HFONT because .net's Font class will erase the relevant properties when using its Font.FromLogFont()
|
||||
//note that whether this is rotated clockwise or CCW might affect how you have to position the text (right-aligned sometimes?, up or down by the height of the font?)
|
||||
public static IntPtr CreateRotatedHFont(Font font, bool CW)
|
||||
{
|
||||
LOGFONT logf = new LOGFONT();
|
||||
font.ToLogFont(logf);
|
||||
logf.lfEscapement = CW ? 2700 : 900;
|
||||
logf.lfOrientation = logf.lfEscapement;
|
||||
logf.lfOutPrecision = (byte)FontPrecision.OUT_TT_ONLY_PRECIS;
|
||||
|
||||
//this doesnt work! .net erases the relevant propreties.. it seems?
|
||||
//return Font.FromLogFont(logf);
|
||||
|
||||
var ret = CreateFontIndirect(logf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void DestroyHFont(IntPtr hfont)
|
||||
{
|
||||
DeleteObject(hfont);
|
||||
}
|
||||
|
||||
public void PrepDrawString(IntPtr hfont, Color color)
|
||||
{
|
||||
SetGraphicsMode(CurrentHDC, 2); //shouldnt be necessary.. cant hurt
|
||||
SelectObject(CurrentHDC, hfont);
|
||||
SetTextColor(color);
|
||||
}
|
||||
|
||||
public void PrepDrawString(Font font, Color color)
|
||||
{
|
||||
SetFont(font);
|
||||
SetTextColor(color);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Draw the given string using the given font and foreground color at given location
|
||||
/// See [http://msdn.microsoft.com/en-us/library/windows/desktop/dd162498(v=vs.85).aspx][15]
|
||||
/// </summary>
|
||||
public void DrawString(string str, Font font, Color color, Rectangle rect, TextFormatFlags flags)
|
||||
{
|
||||
SetFont(font);
|
||||
SetTextColor(color);
|
||||
|
||||
var rect2 = new Rect(rect);
|
||||
DrawText(CurrentHDC, str, str.Length, ref rect2, (uint)flags);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the text color of the device context
|
||||
/// </summary>
|
||||
public void SetTextColor(Color color)
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
SetTextColor(CurrentHDC, rgb);
|
||||
}
|
||||
|
||||
public void SetBackgroundColor(Color color)
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
SetBkColor(CurrentHDC, rgb);
|
||||
}
|
||||
|
||||
public void DrawRectangle(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect)
|
||||
{
|
||||
Rectangle(CurrentHDC, nLeftRect, nTopRect, nRightRect, nBottomRect);
|
||||
}
|
||||
|
||||
public void SetBrush(Color color)
|
||||
{
|
||||
if (BrushCache.ContainsKey(color))
|
||||
{
|
||||
_currentBrush = BrushCache[color];
|
||||
}
|
||||
else
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
var newBrush = CreateSolidBrush(rgb);
|
||||
BrushCache.Add(color, newBrush);
|
||||
_currentBrush = newBrush;
|
||||
}
|
||||
}
|
||||
|
||||
public void FillRectangle(int x, int y, int w, int h)
|
||||
{
|
||||
var r = new GDIRect(new Rectangle(x, y, w, h));
|
||||
FillRect(CurrentHDC, ref r, _currentBrush);
|
||||
}
|
||||
|
||||
public void SetPenPosition(int x, int y)
|
||||
{
|
||||
MoveToEx(CurrentHDC, x, y, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public void SetSolidPen(Color color)
|
||||
{
|
||||
int rgb = (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R;
|
||||
SelectObject(CurrentHDC, GetStockObject((int)PaintObjects.DC_PEN));
|
||||
SetDCPenColor(CurrentHDC, rgb);
|
||||
}
|
||||
|
||||
public void Line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
MoveToEx(CurrentHDC, x1, y1, IntPtr.Zero);
|
||||
LineTo(CurrentHDC, x2, y2);
|
||||
}
|
||||
|
||||
private IntPtr CurrentHDC
|
||||
{
|
||||
get { return _bitHDC != IntPtr.Zero ? _bitHDC : _hdc; }
|
||||
}
|
||||
|
||||
private IntPtr _bitMap = IntPtr.Zero;
|
||||
private IntPtr _bitHDC = IntPtr.Zero;
|
||||
private int _bitW;
|
||||
private int _bitH;
|
||||
|
||||
public void StartOffScreenBitmap(int width, int height)
|
||||
{
|
||||
_bitW = width;
|
||||
_bitH = height;
|
||||
|
||||
_bitHDC = CreateCompatibleDC(_hdc);
|
||||
_bitMap = CreateCompatibleBitmap(_hdc, width, height);
|
||||
SelectObject(_bitHDC, _bitMap);
|
||||
SetBkMode(_bitHDC, BkModes.TRANSPARENT);
|
||||
}
|
||||
|
||||
public void EndOffScreenBitmap()
|
||||
{
|
||||
_bitW = 0;
|
||||
_bitH = 0;
|
||||
|
||||
DeleteObject(_bitMap);
|
||||
DeleteObject(_bitHDC);
|
||||
|
||||
_bitHDC = IntPtr.Zero;
|
||||
_bitMap = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public void CopyToScreen()
|
||||
{
|
||||
BitBlt(_hdc, 0, 0, _bitW, _bitH, _bitHDC, 0, 0, 0x00CC0020);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Set a resource (e.g. a font) for the specified device context.
|
||||
/// </summary>
|
||||
private void SetFont(Font font)
|
||||
{
|
||||
SelectObject(CurrentHDC, GetCachedHFont(font));
|
||||
}
|
||||
|
||||
private IntPtr GetCachedHFont(Font font)
|
||||
{
|
||||
//the original code struck me as bad. attempting to ID fonts by picking a subset of their fields is not gonna work.
|
||||
//don't call this.Font in InputRoll.cs, it is probably slow.
|
||||
//consider Fonts to be a jealously guarded resource (they need to be disposed, after all) and manage them carefully.
|
||||
//this cache maintains the HFONTs only.
|
||||
FontCacheEntry ce;
|
||||
if (!FontsCache.TryGetValue(font, out ce))
|
||||
{
|
||||
FontsCache[font] = ce = new FontCacheEntry();
|
||||
ce.HFont = font.ToHfont();
|
||||
}
|
||||
return ce.HFont;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetDC(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr BeginPaint(IntPtr hWnd, ref IntPtr lpPaint);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr EndPaint(IntPtr hWnd, IntPtr lpPaint);
|
||||
|
||||
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr CreateFontIndirect(
|
||||
[In, MarshalAs(UnmanagedType.LPStruct)]LOGFONT lplf
|
||||
);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int Rectangle(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int FillRect(IntPtr hdc, [In] ref GDIRect lprc, IntPtr hbr);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int SetBkMode(IntPtr hdc, BkModes mode);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiObj);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int SetTextColor(IntPtr hdc, int color);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int SetBkColor(IntPtr hdc, int color);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "GetTextExtentPoint32W")]
|
||||
private static extern int GetTextExtentPoint32(IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] string str, int len, ref Size size);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "GetTextExtentExPointW")]
|
||||
private static extern bool GetTextExtentExPoint(IntPtr hDc, [MarshalAs(UnmanagedType.LPWStr)]string str, int nLength, int nMaxExtent, int[] lpnFit, int[] alpDx, ref Size size);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "TextOutW")]
|
||||
private static extern bool TextOut(IntPtr hdc, int x, int y, [MarshalAs(UnmanagedType.LPWStr)] string str, int len);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
public static extern int SetGraphicsMode(IntPtr hdc, int iMode);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "DrawTextW")]
|
||||
private static extern int DrawText(IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] string str, int len, ref Rect rect, uint uFormat);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "ExtTextOutW")]
|
||||
private static extern bool ExtTextOut(IntPtr hdc, int X, int Y, uint fuOptions, uint cbCount, [In] IntPtr lpDx);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
static extern bool SetWorldTransform(IntPtr hdc, [In] ref XFORM lpXform);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern int SelectClipRgn(IntPtr hdc, IntPtr hrgn);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern bool DeleteObject(IntPtr hObject);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateSolidBrush(int color);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreatePen(int fnPenStyle, int nWidth, int color);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, IntPtr point);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr LineTo(IntPtr hdc, int nXEnd, int nYEnd);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr GetStockObject(int fnObject);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr SetDCPenColor(IntPtr hdc, int crColor);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
|
||||
public static extern bool DeleteDC([In] IntPtr hdc);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
|
||||
|
||||
[DllImport("gdi32.dll", EntryPoint = "GdiAlphaBlend")]
|
||||
static extern bool AlphaBlend(IntPtr hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, BLENDFUNCTION blendFunction);
|
||||
|
||||
public enum FontWeight : int
|
||||
{
|
||||
FW_DONTCARE = 0,
|
||||
FW_THIN = 100,
|
||||
FW_EXTRALIGHT = 200,
|
||||
FW_LIGHT = 300,
|
||||
FW_NORMAL = 400,
|
||||
FW_MEDIUM = 500,
|
||||
FW_SEMIBOLD = 600,
|
||||
FW_BOLD = 700,
|
||||
FW_EXTRABOLD = 800,
|
||||
FW_HEAVY = 900,
|
||||
}
|
||||
public enum FontCharSet : byte
|
||||
{
|
||||
ANSI_CHARSET = 0,
|
||||
DEFAULT_CHARSET = 1,
|
||||
SYMBOL_CHARSET = 2,
|
||||
SHIFTJIS_CHARSET = 128,
|
||||
HANGEUL_CHARSET = 129,
|
||||
HANGUL_CHARSET = 129,
|
||||
GB2312_CHARSET = 134,
|
||||
CHINESEBIG5_CHARSET = 136,
|
||||
OEM_CHARSET = 255,
|
||||
JOHAB_CHARSET = 130,
|
||||
HEBREW_CHARSET = 177,
|
||||
ARABIC_CHARSET = 178,
|
||||
GREEK_CHARSET = 161,
|
||||
TURKISH_CHARSET = 162,
|
||||
VIETNAMESE_CHARSET = 163,
|
||||
THAI_CHARSET = 222,
|
||||
EASTEUROPE_CHARSET = 238,
|
||||
RUSSIAN_CHARSET = 204,
|
||||
MAC_CHARSET = 77,
|
||||
BALTIC_CHARSET = 186,
|
||||
}
|
||||
public enum FontPrecision : byte
|
||||
{
|
||||
OUT_DEFAULT_PRECIS = 0,
|
||||
OUT_STRING_PRECIS = 1,
|
||||
OUT_CHARACTER_PRECIS = 2,
|
||||
OUT_STROKE_PRECIS = 3,
|
||||
OUT_TT_PRECIS = 4,
|
||||
OUT_DEVICE_PRECIS = 5,
|
||||
OUT_RASTER_PRECIS = 6,
|
||||
OUT_TT_ONLY_PRECIS = 7,
|
||||
OUT_OUTLINE_PRECIS = 8,
|
||||
OUT_SCREEN_OUTLINE_PRECIS = 9,
|
||||
OUT_PS_ONLY_PRECIS = 10,
|
||||
}
|
||||
public enum FontClipPrecision : byte
|
||||
{
|
||||
CLIP_DEFAULT_PRECIS = 0,
|
||||
CLIP_CHARACTER_PRECIS = 1,
|
||||
CLIP_STROKE_PRECIS = 2,
|
||||
CLIP_MASK = 0xf,
|
||||
CLIP_LH_ANGLES = (1 << 4),
|
||||
CLIP_TT_ALWAYS = (2 << 4),
|
||||
CLIP_DFA_DISABLE = (4 << 4),
|
||||
CLIP_EMBEDDED = (8 << 4),
|
||||
}
|
||||
public enum FontQuality : byte
|
||||
{
|
||||
DEFAULT_QUALITY = 0,
|
||||
DRAFT_QUALITY = 1,
|
||||
PROOF_QUALITY = 2,
|
||||
NONANTIALIASED_QUALITY = 3,
|
||||
ANTIALIASED_QUALITY = 4,
|
||||
CLEARTYPE_QUALITY = 5,
|
||||
CLEARTYPE_NATURAL_QUALITY = 6,
|
||||
}
|
||||
[Flags]
|
||||
public enum FontPitchAndFamily : byte
|
||||
{
|
||||
DEFAULT_PITCH = 0,
|
||||
FIXED_PITCH = 1,
|
||||
VARIABLE_PITCH = 2,
|
||||
FF_DONTCARE = (0 << 4),
|
||||
FF_ROMAN = (1 << 4),
|
||||
FF_SWISS = (2 << 4),
|
||||
FF_MODERN = (3 << 4),
|
||||
FF_SCRIPT = (4 << 4),
|
||||
FF_DECORATIVE = (5 << 4),
|
||||
}
|
||||
|
||||
//it is important for this to be the right declaration
|
||||
//see more here http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.drawing/2004-04/0319.html
|
||||
//if it's wrong (I had a wrong one from pinvoke.net) then ToLogFont will fail mysteriously
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
class LOGFONT
|
||||
{
|
||||
public int lfHeight = 0;
|
||||
public int lfWidth = 0;
|
||||
public int lfEscapement = 0;
|
||||
public int lfOrientation = 0;
|
||||
public int lfWeight = 0;
|
||||
public byte lfItalic = 0;
|
||||
public byte lfUnderline = 0;
|
||||
public byte lfStrikeOut = 0;
|
||||
public byte lfCharSet = 0;
|
||||
public byte lfOutPrecision = 0;
|
||||
public byte lfClipPrecision = 0;
|
||||
public byte lfQuality = 0;
|
||||
public byte lfPitchAndFamily = 0;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
||||
public string lfFaceName = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The graphics mode that can be set by SetGraphicsMode.
|
||||
/// </summary>
|
||||
public enum GraphicsMode : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the graphics mode that is compatible with 16-bit Windows. This is the default mode. If
|
||||
/// this value is specified, the application can only modify the world-to-device transform by
|
||||
/// calling functions that set window and viewport extents and origins, but not by using
|
||||
/// SetWorldTransform or ModifyWorldTransform; calls to those functions will fail.
|
||||
/// Examples of functions that set window and viewport extents and origins are SetViewportExtEx
|
||||
/// and SetWindowExtEx.
|
||||
/// </summary>
|
||||
GM_COMPATIBLE = 1,
|
||||
/// <summary>
|
||||
/// Sets the advanced graphics mode that allows world transformations. This value must be
|
||||
/// specified if the application will set or modify the world transformation for the specified
|
||||
/// device context. In this mode all graphics, including text output, fully conform to the
|
||||
/// world-to-device transformation specified in the device context.
|
||||
/// </summary>
|
||||
GM_ADVANCED = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The XFORM structure specifies a world-space to page-space transformation.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XFORM
|
||||
{
|
||||
public float eM11;
|
||||
public float eM12;
|
||||
public float eM21;
|
||||
public float eM22;
|
||||
public float eDx;
|
||||
public float eDy;
|
||||
|
||||
public XFORM(float eM11, float eM12, float eM21, float eM22, float eDx, float eDy)
|
||||
{
|
||||
this.eM11 = eM11;
|
||||
this.eM12 = eM12;
|
||||
this.eM21 = eM21;
|
||||
this.eM22 = eM22;
|
||||
this.eDx = eDx;
|
||||
this.eDy = eDy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows implicit converstion to a managed transformation matrix.
|
||||
/// </summary>
|
||||
public static implicit operator System.Drawing.Drawing2D.Matrix(XFORM xf)
|
||||
{
|
||||
return new System.Drawing.Drawing2D.Matrix(xf.eM11, xf.eM12, xf.eM21, xf.eM22, xf.eDx, xf.eDy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows implicit converstion from a managed transformation matrix.
|
||||
/// </summary>
|
||||
public static implicit operator XFORM(System.Drawing.Drawing2D.Matrix m)
|
||||
{
|
||||
float[] elems = m.Elements;
|
||||
return new XFORM(elems[0], elems[1], elems[2], elems[3], elems[4], elems[5]);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BLENDFUNCTION
|
||||
{
|
||||
byte BlendOp;
|
||||
byte BlendFlags;
|
||||
byte SourceConstantAlpha;
|
||||
byte AlphaFormat;
|
||||
|
||||
public BLENDFUNCTION(byte op, byte flags, byte alpha, byte format)
|
||||
{
|
||||
BlendOp = op;
|
||||
BlendFlags = flags;
|
||||
SourceConstantAlpha = alpha;
|
||||
AlphaFormat = format;
|
||||
}
|
||||
}
|
||||
|
||||
const byte AC_SRC_OVER = 0x00;
|
||||
const byte AC_SRC_ALPHA = 0x01;
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
static extern int SetBitmapBits(IntPtr hbmp, uint cBytes, byte[] lpBits);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Classes, Structs, and Enums
|
||||
|
||||
public class GdiGraphicsLock : IDisposable
|
||||
{
|
||||
private readonly GDIRenderer Gdi;
|
||||
|
||||
public GdiGraphicsLock(GDIRenderer gdi)
|
||||
{
|
||||
this.Gdi = gdi;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Gdi._g.ReleaseHdc(Gdi._hdc);
|
||||
Gdi._hdc = IntPtr.Zero;
|
||||
Gdi._g = null;
|
||||
}
|
||||
}
|
||||
|
||||
private struct Rect
|
||||
{
|
||||
private int _left;
|
||||
private int _top;
|
||||
private int _right;
|
||||
private int _bottom;
|
||||
|
||||
public Rect(Rectangle r)
|
||||
{
|
||||
_left = r.Left;
|
||||
_top = r.Top;
|
||||
_bottom = r.Bottom;
|
||||
_right = r.Right;
|
||||
}
|
||||
}
|
||||
|
||||
private struct GDIRect
|
||||
{
|
||||
private int left;
|
||||
private int top;
|
||||
private int right;
|
||||
private int bottom;
|
||||
|
||||
public GDIRect(Rectangle r)
|
||||
{
|
||||
left = r.Left;
|
||||
top = r.Top;
|
||||
bottom = r.Bottom;
|
||||
right = r.Right;
|
||||
}
|
||||
}
|
||||
|
||||
private struct GDIPoint
|
||||
{
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
private GDIPoint(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ETOOptions : uint
|
||||
{
|
||||
CLIPPED = 0x4,
|
||||
GLYPH_INDEX = 0x10,
|
||||
IGNORELANGUAGE = 0x1000,
|
||||
NUMERICSLATIN = 0x800,
|
||||
NUMERICSLOCAL = 0x400,
|
||||
OPAQUE = 0x2,
|
||||
PDY = 0x2000,
|
||||
RTLREADING = 0x800,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See [http://msdn.microsoft.com/en-us/library/windows/desktop/dd162498(v=vs.85).aspx][15]
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum TextFormatFlags : uint
|
||||
{
|
||||
Default = 0x00000000,
|
||||
Center = 0x00000001,
|
||||
Right = 0x00000002,
|
||||
VCenter = 0x00000004,
|
||||
Bottom = 0x00000008,
|
||||
WordBreak = 0x00000010,
|
||||
SingleLine = 0x00000020,
|
||||
ExpandTabs = 0x00000040,
|
||||
TabStop = 0x00000080,
|
||||
NoClip = 0x00000100,
|
||||
ExternalLeading = 0x00000200,
|
||||
CalcRect = 0x00000400,
|
||||
NoPrefix = 0x00000800,
|
||||
Internal = 0x00001000,
|
||||
EditControl = 0x00002000,
|
||||
PathEllipsis = 0x00004000,
|
||||
EndEllipsis = 0x00008000,
|
||||
ModifyString = 0x00010000,
|
||||
RtlReading = 0x00020000,
|
||||
WordEllipsis = 0x00040000,
|
||||
NoFullWidthCharBreak = 0x00080000,
|
||||
HidePrefix = 0x00100000,
|
||||
ProfixOnly = 0x00200000,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum PenStyles
|
||||
{
|
||||
PS_SOLID = 0x00000000
|
||||
// TODO
|
||||
}
|
||||
|
||||
public enum PaintObjects
|
||||
{
|
||||
WHITE_BRUSH = 0,
|
||||
LTGRAY_BRUSH = 1,
|
||||
GRAY_BRUSH = 2,
|
||||
DKGRAY_BRUSH = 3,
|
||||
BLACK_BRUSH = 4,
|
||||
NULL_BRUSH = 5,
|
||||
WHITE_PEN = 6,
|
||||
BLACK_PEN = 7,
|
||||
NULL_PEN = 8,
|
||||
OEM_FIXED_FONT = 10,
|
||||
ANSI_FIXED_FONT = 11,
|
||||
ANSI_VAR_FONT = 12,
|
||||
SYSTEM_FONT = 13,
|
||||
DEVICE_DEFAULT_FONT = 14,
|
||||
DEFAULT_PALETTE = 15,
|
||||
SYSTEM_FIXED_FONT = 16,
|
||||
DC_BRUSH = 18,
|
||||
DC_PEN = 19,
|
||||
}
|
||||
|
||||
public enum BkModes : int
|
||||
{
|
||||
TRANSPARENT = 1,
|
||||
OPAQUE = 2
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public class HexView : Control
|
||||
{
|
||||
private readonly GDIRenderer Gdi;
|
||||
//private readonly IControlRenderer _renderer;
|
||||
private readonly Font NormalFont;
|
||||
private Size _charSize;
|
||||
|
||||
|
@ -27,18 +27,18 @@ namespace BizHawk.Client.EmuHawk
|
|||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
SetStyle(ControlStyles.Opaque, true);
|
||||
|
||||
Gdi = new GDIRenderer();
|
||||
//_renderer = new GdiRenderer();
|
||||
|
||||
using (var g = CreateGraphics())
|
||||
using (var LCK = Gdi.LockGraphics(g))
|
||||
{
|
||||
_charSize = Gdi.MeasureString("A", NormalFont); // TODO make this a property so changing it updates other values.
|
||||
}
|
||||
//using (var g = CreateGraphics())
|
||||
//using (var LCK = _renderer.LockGraphics(g))
|
||||
//{
|
||||
// _charSize = _renderer.MeasureString("A", NormalFont); // TODO make this a property so changing it updates other values.
|
||||
//}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
Gdi.Dispose();
|
||||
//_renderer.Dispose();
|
||||
|
||||
NormalFont.Dispose();
|
||||
|
||||
|
@ -49,21 +49,21 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
using (var LCK = Gdi.LockGraphics(e.Graphics))
|
||||
{
|
||||
Gdi.StartOffScreenBitmap(Width, Height);
|
||||
//using (var lck = _renderer.LockGraphics(e.Graphics))
|
||||
//{
|
||||
// _renderer.StartOffScreenBitmap(Width, Height);
|
||||
|
||||
// White Background
|
||||
Gdi.SetBrush(Color.White);
|
||||
Gdi.SetSolidPen(Color.White);
|
||||
Gdi.FillRectangle(0, 0, Width, Height);
|
||||
// // White Background
|
||||
// _renderer.SetBrush(Color.White);
|
||||
// _renderer.SetSolidPen(Color.White);
|
||||
// _renderer.FillRectangle(0, 0, Width, Height);
|
||||
|
||||
|
||||
Gdi.DrawString("Hello World", new Point(10, 10));
|
||||
// _renderer.DrawString("Hello World", new Point(10, 10));
|
||||
|
||||
Gdi.CopyToScreen();
|
||||
Gdi.EndOffScreenBitmap();
|
||||
}
|
||||
// _renderer.CopyToScreen();
|
||||
// _renderer.EndOffScreenBitmap();
|
||||
//}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a single cell of the <seealso cref="InputRoll"/>
|
||||
/// </summary>
|
||||
public class Cell
|
||||
{
|
||||
public RollColumn Column { get; internal set; }
|
||||
public int? RowIndex { get; internal set; }
|
||||
public string CurrentText { get; internal set; }
|
||||
|
||||
public Cell() { }
|
||||
|
||||
public Cell(Cell cell)
|
||||
{
|
||||
Column = cell.Column;
|
||||
RowIndex = cell.RowIndex;
|
||||
}
|
||||
|
||||
public bool IsDataCell => Column != null && RowIndex.HasValue;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var cell = obj as Cell;
|
||||
if (cell != null)
|
||||
{
|
||||
return Column == cell.Column && RowIndex == cell.RowIndex;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Column.GetHashCode() + RowIndex.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(Cell a, Cell b)
|
||||
{
|
||||
if (ReferenceEquals(a, null))
|
||||
{
|
||||
return ReferenceEquals(b, null);
|
||||
}
|
||||
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
public static bool operator !=(Cell a, Cell b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SortCell : IComparer<Cell>
|
||||
{
|
||||
int IComparer<Cell>.Compare(Cell c1, Cell c2)
|
||||
{
|
||||
if (c1 == null && c2 == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c2 == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c1 == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c1.RowIndex.HasValue)
|
||||
{
|
||||
if (c2.RowIndex.HasValue)
|
||||
{
|
||||
int row = c1.RowIndex.Value.CompareTo(c2.RowIndex.Value);
|
||||
return row == 0
|
||||
? c1.Column.Name.CompareTo(c2.Column.Name)
|
||||
: row;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c2.RowIndex.HasValue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return c1.Column.Name.CompareTo(c2.Column.Name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the type of column of a <see cref="RollColumn"/>
|
||||
/// </summary>
|
||||
public enum ColumnType
|
||||
{
|
||||
Boolean, Float, Text, Image
|
||||
}
|
||||
}
|
|
@ -0,0 +1,697 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public partial class InputRoll
|
||||
{
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
using (_renderer.LockGraphics(e.Graphics, Width, Height))
|
||||
{
|
||||
// White Background
|
||||
_renderer.SetBrush(Color.White);
|
||||
_renderer.SetSolidPen(Color.White);
|
||||
_renderer.FillRectangle(0, 0, Width, Height);
|
||||
|
||||
// Lag frame calculations
|
||||
SetLagFramesArray();
|
||||
|
||||
var visibleColumns = _columns.VisibleColumns.ToList();
|
||||
|
||||
CalculateHorizontalColumnPositions(visibleColumns);
|
||||
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
DrawColumnBg(visibleColumns);
|
||||
DrawColumnText(visibleColumns);
|
||||
}
|
||||
|
||||
// Background
|
||||
DrawBg(visibleColumns);
|
||||
|
||||
// Foreground
|
||||
DrawData(visibleColumns);
|
||||
|
||||
DrawColumnDrag(visibleColumns);
|
||||
DrawCellDrag(visibleColumns);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawString(string text, int? width, Point point)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (width.HasValue)
|
||||
{
|
||||
var max = (width.Value - CellWidthPadding) / _charSize.Width;
|
||||
if (text.Length >= max)
|
||||
{
|
||||
text = text.Substring(0, max);
|
||||
}
|
||||
}
|
||||
|
||||
_renderer.DrawString(text, point);
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
// Do nothing, and this should never be called
|
||||
}
|
||||
|
||||
private void CalculateHorizontalColumnPositions(List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (!HorizontalOrientation)
|
||||
{
|
||||
_horizontalColumnHeights = null;
|
||||
_horizontalColumnTops = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_horizontalColumnHeights = new int[visibleColumns.Count];
|
||||
_horizontalColumnTops = new int[visibleColumns.Count];
|
||||
|
||||
int top = 0;
|
||||
int startRow = FirstVisibleRow;
|
||||
for (int j = 0; j < visibleColumns.Count; j++)
|
||||
{
|
||||
RollColumn col = visibleColumns[j];
|
||||
int height = CellHeight;
|
||||
if (col.Rotatable && col.RotatedHeight != null)
|
||||
{
|
||||
height = Math.Max(height, col.RotatedHeight.Value);
|
||||
}
|
||||
else if (col.Rotatable)
|
||||
{
|
||||
string text;
|
||||
int strOffsetX = 0;
|
||||
int strOffsetY = 0;
|
||||
QueryItemText(startRow, col, out text, ref strOffsetX, ref strOffsetY);
|
||||
int textWidth = _renderer.MeasureString(text, _font).Width;
|
||||
height = Math.Max(height, textWidth + (CellWidthPadding * 2));
|
||||
}
|
||||
_horizontalColumnHeights[j] = height;
|
||||
_horizontalColumnTops[j] = top;
|
||||
top += height;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawColumnDrag(List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (_columnDown?.Width != null && _columnDownMoved && _currentX.HasValue && _currentY.HasValue && IsHoveringOnColumnCell)
|
||||
{
|
||||
int columnWidth = _columnDown.Width.Value;
|
||||
int columnHeight = CellHeight;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int columnIndex = visibleColumns.IndexOf(_columnDown);
|
||||
columnWidth = ColumnWidth;
|
||||
columnHeight = GetHColHeight(columnIndex);
|
||||
}
|
||||
int x1 = _currentX.Value - (columnWidth / 2);
|
||||
int y1 = _currentY.Value - (columnHeight / 2);
|
||||
int x2 = x1 + columnWidth;
|
||||
int y2 = y1 + columnHeight;
|
||||
int textOffsetY = CellHeightPadding;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int textHeight = _renderer.MeasureString(_columnDown.Text, _font).Height;
|
||||
textOffsetY = (columnHeight - textHeight) / 2;
|
||||
}
|
||||
|
||||
_renderer.SetSolidPen(_backColor);
|
||||
_renderer.DrawRectangle(x1, y1, x2, y2);
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
_renderer.DrawString(_columnDown.Text, new Point(x1 + CellWidthPadding, y1 + textOffsetY));
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCellDrag(List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (_draggingCell != null && _draggingCell.RowIndex.HasValue && _draggingCell.Column.Width.HasValue
|
||||
&& _currentX.HasValue && _currentY.HasValue)
|
||||
{
|
||||
var text = "";
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
QueryItemText?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, out text, ref offsetX, ref offsetY);
|
||||
|
||||
Color bgColor = _backColor;
|
||||
QueryItemBkColor?.Invoke(_draggingCell.RowIndex.Value, _draggingCell.Column, ref bgColor);
|
||||
|
||||
int columnHeight = CellHeight;
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int columnIndex = visibleColumns.IndexOf(_draggingCell.Column);
|
||||
columnHeight = GetHColHeight(columnIndex);
|
||||
}
|
||||
int x1 = _currentX.Value - (_draggingCell.Column.Width.Value / 2);
|
||||
int y1 = _currentY.Value - (columnHeight / 2);
|
||||
int x2 = x1 + _draggingCell.Column.Width.Value;
|
||||
int y2 = y1 + columnHeight;
|
||||
|
||||
_renderer.SetBrush(bgColor);
|
||||
_renderer.FillRectangle(x1, y1, x2 - x1, y2 - y1);
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
_renderer.DrawString(text, new Point(x1 + CellWidthPadding + offsetX, y1 + CellHeightPadding + offsetY));
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawColumnText(List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int y = -_vBar.Value;
|
||||
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
|
||||
for(int j = 0; j < visibleColumns.Count; j++)
|
||||
{
|
||||
var column = visibleColumns[j];
|
||||
var columnHeight = GetHColHeight(j);
|
||||
var textHeight = _renderer.MeasureString(column.Text, _font).Height;
|
||||
var point = new Point(CellWidthPadding, y + ((columnHeight - textHeight) / 2));
|
||||
|
||||
if (IsHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
_renderer.PrepDrawString(_font, SystemColors.HighlightText);
|
||||
DrawString(column.Text, column.Width, point);
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawString(column.Text, column.Width, point);
|
||||
}
|
||||
|
||||
y += columnHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
var point = new Point(column.Left.Value + 2 * CellWidthPadding - _hBar.Value, CellHeightPadding); // TODO: fix this CellPadding issue (2 * CellPadding vs just CellPadding)
|
||||
|
||||
if (IsHoveringOnColumnCell && column == CurrentCell.Column)
|
||||
{
|
||||
_renderer.PrepDrawString(_font, SystemColors.HighlightText);
|
||||
DrawString(column.Text, column.Width, point);
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawString(column.Text, column.Width, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawData(List<RollColumn> visibleColumns)
|
||||
{
|
||||
// Prevent exceptions with small TAStudio windows
|
||||
if (visibleColumns.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (QueryItemText != null)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int startRow = FirstVisibleRow;
|
||||
int range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
int lastVisible = LastVisibleColumnIndex;
|
||||
for (int j = FirstVisibleColumn; j <= lastVisible; j++)
|
||||
{
|
||||
RollColumn col = visibleColumns[j];
|
||||
int colHeight = GetHColHeight(j);
|
||||
|
||||
for (int i = 0, f = 0; f < range; i++, f++)
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
|
||||
int baseX = RowsToPixels(i) + (col.Rotatable ? CellWidth : 0);
|
||||
int baseY = GetHColTop(j) - _vBar.Value;
|
||||
|
||||
if (!col.Rotatable)
|
||||
{
|
||||
Bitmap image = null;
|
||||
int bitmapOffsetX = 0;
|
||||
int bitmapOffsetY = 0;
|
||||
|
||||
QueryItemIcon?.Invoke(f + startRow, col, ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
int x = baseX + CellWidthPadding + bitmapOffsetX;
|
||||
int y = baseY + CellHeightPadding + bitmapOffsetY;
|
||||
_renderer.DrawBitmap(image, new Point(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
string text;
|
||||
int strOffsetX = 0;
|
||||
int strOffsetY = 0;
|
||||
QueryItemText(f + startRow, col, out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
int textWidth = _renderer.MeasureString(text, _font).Width;
|
||||
if (col.Rotatable)
|
||||
{
|
||||
// Center Text
|
||||
int textX = Math.Max(((colHeight - textWidth) / 2), CellWidthPadding) + strOffsetX;
|
||||
int textY = CellWidthPadding + strOffsetY;
|
||||
var point = new Point(baseX - textY, baseY + textX);
|
||||
|
||||
_renderer.PrepDrawString(_font, _foreColor, rotate: true);
|
||||
DrawString(text, null, point);
|
||||
_renderer.PrepDrawString(_font, _foreColor, rotate: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Center Text
|
||||
int textX = Math.Max(((CellWidth - textWidth) / 2), CellWidthPadding) + strOffsetX;
|
||||
int textY = CellHeightPadding + strOffsetY;
|
||||
var point = new Point(baseX + textX, baseY + textY);
|
||||
|
||||
DrawString(text, ColumnWidth, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int startRow = FirstVisibleRow;
|
||||
int range = Math.Min(LastVisibleRow, RowCount - 1) - startRow + 1;
|
||||
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
int xPadding = CellWidthPadding + 1 - _hBar.Value;
|
||||
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
int lastVisible = LastVisibleColumnIndex;
|
||||
for (int j = FirstVisibleColumn; j <= lastVisible; j++) // Horizontal
|
||||
{
|
||||
RollColumn col = visibleColumns[j];
|
||||
|
||||
string text;
|
||||
int strOffsetX = 0;
|
||||
int strOffsetY = 0;
|
||||
Point point = new Point(col.Left.Value + xPadding, RowsToPixels(i) + CellHeightPadding);
|
||||
|
||||
Bitmap image = null;
|
||||
int bitmapOffsetX = 0;
|
||||
int bitmapOffsetY = 0;
|
||||
|
||||
QueryItemIcon?.Invoke(f + startRow, visibleColumns[j], ref image, ref bitmapOffsetX, ref bitmapOffsetY);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
_renderer.DrawBitmap(image, new Point(point.X + bitmapOffsetX, point.Y + bitmapOffsetY + CellHeightPadding));
|
||||
}
|
||||
|
||||
QueryItemText(f + startRow, visibleColumns[j], out text, ref strOffsetX, ref strOffsetY);
|
||||
|
||||
bool rePrep = false;
|
||||
if (_selectedItems.Contains(new Cell { Column = visibleColumns[j], RowIndex = f + startRow }))
|
||||
{
|
||||
_renderer.PrepDrawString(_font, SystemColors.HighlightText);
|
||||
rePrep = true;
|
||||
}
|
||||
|
||||
DrawString(text, col.Width, new Point(point.X + strOffsetX, point.Y + strOffsetY));
|
||||
|
||||
if (rePrep)
|
||||
{
|
||||
_renderer.PrepDrawString(_font, _foreColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawColumnBg(List<RollColumn> visibleColumns)
|
||||
{
|
||||
_renderer.SetBrush(SystemColors.ControlLight);
|
||||
_renderer.SetSolidPen(Color.Black);
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
_renderer.FillRectangle(0, 0, ColumnWidth + 1, DrawHeight + 1);
|
||||
|
||||
int y = -_vBar.Value;
|
||||
for (int j = 0; j < visibleColumns.Count; j++)
|
||||
{
|
||||
_renderer.Line(1, y, ColumnWidth, y);
|
||||
y += GetHColHeight(j);
|
||||
}
|
||||
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
_renderer.Line(1, y, ColumnWidth, y);
|
||||
}
|
||||
|
||||
_renderer.Line(0, 0, 0, y + 1);
|
||||
_renderer.Line(ColumnWidth, 0, ColumnWidth, y + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int bottomEdge = RowsToPixels(0);
|
||||
|
||||
// Gray column box and black line underneath
|
||||
_renderer.FillRectangle(0, 0, Width + 1, bottomEdge + 1);
|
||||
_renderer.Line(0, 0, TotalColWidth.Value + 1, 0);
|
||||
_renderer.Line(0, bottomEdge, TotalColWidth.Value + 1, bottomEdge);
|
||||
|
||||
// Vertical black separators
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
int pos = column.Left.Value - _hBar.Value;
|
||||
_renderer.Line(pos, 0, pos, bottomEdge);
|
||||
}
|
||||
|
||||
// Draw right most line
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
int right = TotalColWidth.Value - _hBar.Value;
|
||||
_renderer.Line(right, 0, right, bottomEdge);
|
||||
}
|
||||
}
|
||||
|
||||
// Emphasis
|
||||
foreach (var column in visibleColumns.Where(c => c.Emphasis))
|
||||
{
|
||||
_renderer.SetBrush(SystemColors.ActiveBorder);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
int columnIndex = visibleColumns.IndexOf(column);
|
||||
_renderer.FillRectangle(1, GetHColTop(columnIndex) + 1, ColumnWidth - 1, GetHColHeight(columnIndex) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_renderer.FillRectangle(column.Left.Value + 1 - _hBar.Value, 1, column.Width.Value - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// If the user is hovering over a column
|
||||
if (IsHoveringOnColumnCell)
|
||||
{
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (int i = 0; i < visibleColumns.Count; i++)
|
||||
{
|
||||
if (visibleColumns[i] != CurrentCell.Column)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int top = GetHColTop(i) - _vBar.Value;
|
||||
int height = GetHColHeight(i);
|
||||
|
||||
_renderer.SetBrush(CurrentCell.Column.Emphasis
|
||||
? SystemColors.Highlight.Add(0x00222222)
|
||||
: SystemColors.Highlight);
|
||||
|
||||
_renderer.FillRectangle(1, top + 1, ColumnWidth - 1, height - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO multiple selected columns
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
if (column == CurrentCell.Column)
|
||||
{
|
||||
// Left of column is to the right of the viewable area or right of column is to the left of the viewable area
|
||||
if (column.Left.Value - _hBar.Value > Width || column.Right.Value - _hBar.Value < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int left = column.Left.Value - _hBar.Value;
|
||||
int width = column.Right.Value - _hBar.Value - left;
|
||||
|
||||
_renderer.SetBrush(CurrentCell.Column.Emphasis
|
||||
? SystemColors.Highlight.Add(0x00550000)
|
||||
: SystemColors.Highlight);
|
||||
|
||||
_renderer.FillRectangle(left + 1, 1, width - 1, ColumnHeight - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO refactor this and DoBackGroundCallback functions.
|
||||
/// <summary>
|
||||
/// Draw Gridlines and background colors using QueryItemBkColor.
|
||||
/// </summary>
|
||||
private void DrawBg(List<RollColumn> visibleColumns)
|
||||
{
|
||||
if (UseCustomBackground && QueryItemBkColor != null)
|
||||
{
|
||||
DoBackGroundCallback(visibleColumns);
|
||||
}
|
||||
|
||||
if (GridLines)
|
||||
{
|
||||
_renderer.SetSolidPen(SystemColors.ControlLight);
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
// Columns
|
||||
for (int i = 1; i < VisibleRows + 1; i++)
|
||||
{
|
||||
int x = RowsToPixels(i);
|
||||
_renderer.Line(x, 1, x, DrawHeight);
|
||||
}
|
||||
|
||||
// Rows
|
||||
for (int i = 0; i < visibleColumns.Count + 1; i++)
|
||||
{
|
||||
int y = GetHColTop(i) - _vBar.Value;
|
||||
_renderer.Line(RowsToPixels(0) + 1, y, DrawWidth, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Columns
|
||||
int y = ColumnHeight + 1;
|
||||
foreach (var column in visibleColumns)
|
||||
{
|
||||
int x = (column.Left ?? 0) - _hBar.Value;
|
||||
_renderer.Line(x, y, x, Height - 1);
|
||||
}
|
||||
|
||||
if (visibleColumns.Any())
|
||||
{
|
||||
int x = (TotalColWidth ?? 0) - _hBar.Value;
|
||||
_renderer.Line(x, y, x, Height - 1);
|
||||
}
|
||||
|
||||
// Rows
|
||||
for (int i = 1; i < VisibleRows + 1; i++)
|
||||
{
|
||||
_renderer.Line(0, RowsToPixels(i), Width + 1, RowsToPixels(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_selectedItems.Any())
|
||||
{
|
||||
DoSelectionBG(visibleColumns);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoSelectionBG(List<RollColumn> visibleColumns)
|
||||
{
|
||||
Color rowColor = Color.White;
|
||||
int lastVisibleRow = LastVisibleRow;
|
||||
int lastRow = -1;
|
||||
foreach (Cell cell in _selectedItems)
|
||||
{
|
||||
if (cell.RowIndex > lastVisibleRow || cell.RowIndex < FirstVisibleRow || !VisibleColumns.Contains(cell.Column))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Cell relativeCell = new Cell
|
||||
{
|
||||
RowIndex = cell.RowIndex - FirstVisibleRow,
|
||||
Column = cell.Column,
|
||||
};
|
||||
relativeCell.RowIndex -= CountLagFramesAbsolute(relativeCell.RowIndex.Value);
|
||||
|
||||
if (QueryRowBkColor != null && lastRow != cell.RowIndex.Value)
|
||||
{
|
||||
QueryRowBkColor(cell.RowIndex.Value, ref rowColor);
|
||||
lastRow = cell.RowIndex.Value;
|
||||
}
|
||||
|
||||
Color cellColor = rowColor;
|
||||
QueryItemBkColor?.Invoke(cell.RowIndex.Value, cell.Column, ref cellColor);
|
||||
|
||||
// Alpha layering for cell before selection
|
||||
float alpha = (float)cellColor.A / 255;
|
||||
if (cellColor.A != 255 && cellColor.A != 0)
|
||||
{
|
||||
cellColor = Color.FromArgb(rowColor.R - (int)((rowColor.R - cellColor.R) * alpha),
|
||||
rowColor.G - (int)((rowColor.G - cellColor.G) * alpha),
|
||||
rowColor.B - (int)((rowColor.B - cellColor.B) * alpha));
|
||||
}
|
||||
|
||||
// Alpha layering for selection
|
||||
alpha = 0.33f;
|
||||
cellColor = Color.FromArgb(cellColor.R - (int)((cellColor.R - SystemColors.Highlight.R) * alpha),
|
||||
cellColor.G - (int)((cellColor.G - SystemColors.Highlight.G) * alpha),
|
||||
cellColor.B - (int)((cellColor.B - SystemColors.Highlight.B) * alpha));
|
||||
DrawCellBG(cellColor, relativeCell, visibleColumns);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a cell with RowIndex in between 0 and VisibleRows, it draws the background color specified. Do not call with absolute row indices.
|
||||
/// </summary>
|
||||
private void DrawCellBG(Color color, Cell cell, List<RollColumn> visibleColumns)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
x = RowsToPixels(cell.RowIndex.Value) + 1;
|
||||
if (x < ColumnWidth)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int columnIndex = visibleColumns.IndexOf(cell.Column);
|
||||
w = CellWidth - 1;
|
||||
y = GetHColTop(columnIndex) - _vBar.Value + 1; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
|
||||
h = GetHColHeight(columnIndex) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = RowsToPixels(cell.RowIndex.Value) + 1; // We can't draw without row and column, so assume they exist and fail catastrophically if they don't
|
||||
if (y < ColumnHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
x = cell.Column.Left.Value - _hBar.Value + 1;
|
||||
w = cell.Column.Width.Value - 1;
|
||||
h = CellHeight - 1;
|
||||
}
|
||||
|
||||
// Don't draw if off screen.
|
||||
if (x > DrawWidth || y > DrawHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_renderer.SetBrush(color);
|
||||
_renderer.FillRectangle(x, y, w, h);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls QueryItemBkColor callback for all visible cells and fills in the background of those cells.
|
||||
/// </summary>
|
||||
private void DoBackGroundCallback(List<RollColumn> visibleColumns)
|
||||
{
|
||||
int startIndex = FirstVisibleRow;
|
||||
int range = Math.Min(LastVisibleRow, RowCount - 1) - startIndex + 1;
|
||||
int lastVisibleColumn = LastVisibleColumnIndex;
|
||||
int firstVisibleColumn = FirstVisibleColumn;
|
||||
|
||||
// Prevent exceptions with small TAStudio windows
|
||||
if (firstVisibleColumn < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HorizontalOrientation)
|
||||
{
|
||||
for (int i = 0, f = 0; f < range; i++, f++)
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
|
||||
Color rowColor = Color.White;
|
||||
QueryRowBkColor?.Invoke(f + startIndex, ref rowColor);
|
||||
|
||||
for (int j = firstVisibleColumn; j <= lastVisibleColumn; j++)
|
||||
{
|
||||
Color itemColor = Color.White;
|
||||
QueryItemBkColor?.Invoke(f + startIndex, visibleColumns[j], ref itemColor);
|
||||
if (itemColor == Color.White)
|
||||
{
|
||||
itemColor = rowColor;
|
||||
}
|
||||
else if (itemColor.A != 255 && itemColor.A != 0)
|
||||
{
|
||||
float alpha = (float)itemColor.A / 255;
|
||||
itemColor = Color.FromArgb(rowColor.R - (int)((rowColor.R - itemColor.R) * alpha),
|
||||
rowColor.G - (int)((rowColor.G - itemColor.G) * alpha),
|
||||
rowColor.B - (int)((rowColor.B - itemColor.B) * alpha));
|
||||
}
|
||||
|
||||
if (itemColor != Color.White) // An easy optimization, don't draw unless the user specified something other than the default
|
||||
{
|
||||
var cell = new Cell
|
||||
{
|
||||
Column = visibleColumns[j],
|
||||
RowIndex = i
|
||||
};
|
||||
DrawCellBG(itemColor, cell, visibleColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0, f = 0; f < range; i++, f++) // Vertical
|
||||
{
|
||||
f += _lagFrames[i];
|
||||
|
||||
Color rowColor = Color.White;
|
||||
QueryRowBkColor?.Invoke(f + startIndex, ref rowColor);
|
||||
|
||||
for (int j = FirstVisibleColumn; j <= lastVisibleColumn; j++) // Horizontal
|
||||
{
|
||||
Color itemColor = Color.White;
|
||||
QueryItemBkColor?.Invoke(f + startIndex, visibleColumns[j], ref itemColor);
|
||||
if (itemColor == Color.White)
|
||||
{
|
||||
itemColor = rowColor;
|
||||
}
|
||||
else if (itemColor.A != 255 && itemColor.A != 0)
|
||||
{
|
||||
float alpha = (float)itemColor.A / 255;
|
||||
itemColor = Color.FromArgb(rowColor.R - (int)((rowColor.R - itemColor.R) * alpha),
|
||||
rowColor.G - (int)((rowColor.G - itemColor.G) * alpha),
|
||||
rowColor.B - (int)((rowColor.B - itemColor.B) * alpha));
|
||||
}
|
||||
|
||||
if (itemColor != Color.White) // An easy optimization, don't draw unless the user specified something other than the default
|
||||
{
|
||||
var cell = new Cell
|
||||
{
|
||||
Column = visibleColumns[j],
|
||||
RowIndex = i
|
||||
};
|
||||
DrawCellBG(itemColor, cell, visibleColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public class RollColumn
|
||||
{
|
||||
public string Group { get; set; }
|
||||
public int? Width { get; set; }
|
||||
public int? Left { get; set; }
|
||||
public int? Right { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Text { get; set; }
|
||||
public ColumnType Type { get; set; }
|
||||
public bool Visible { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Column will be drawn with an emphasized look, if true
|
||||
/// </summary>
|
||||
public bool Emphasis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Column header text will be drawn rotated, if true
|
||||
/// </summary>
|
||||
public bool Rotatable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If drawn rotated, specifies the desired height, or null to auto-size
|
||||
/// </summary>
|
||||
public int? RotatedHeight { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public class RollColumns : List<RollColumn>
|
||||
{
|
||||
public RollColumn this[string name] => this.SingleOrDefault(column => column.Name == name);
|
||||
|
||||
public IEnumerable<RollColumn> VisibleColumns => this.Where(c => c.Visible);
|
||||
|
||||
public Action ChangedCallback { get; set; }
|
||||
|
||||
// TODO: this shouldn't be exposed. But in order to not expose it, each RollColumn must have a change callback, and all property changes must call it, it is quicker and easier to just call this when needed
|
||||
public void ColumnsChanged()
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
foreach (var col in VisibleColumns)
|
||||
{
|
||||
col.Left = pos;
|
||||
pos += col.Width ?? 0;
|
||||
col.Right = pos;
|
||||
}
|
||||
|
||||
ChangedCallback?.Invoke();
|
||||
}
|
||||
|
||||
public new void Add(RollColumn column)
|
||||
{
|
||||
if (this.Any(c => c.Name == column.Name))
|
||||
{
|
||||
// The designer sucks, doing nothing for now
|
||||
return;
|
||||
//throw new InvalidOperationException("A column with this name already exists.");
|
||||
}
|
||||
|
||||
base.Add(column);
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public new void AddRange(IEnumerable<RollColumn> collection)
|
||||
{
|
||||
var items = collection.ToList();
|
||||
foreach (var column in items)
|
||||
{
|
||||
if (this.Any(c => c.Name == column.Name))
|
||||
{
|
||||
// The designer sucks, doing nothing for now
|
||||
return;
|
||||
|
||||
throw new InvalidOperationException("A column with this name already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
base.AddRange(items);
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public new void Insert(int index, RollColumn column)
|
||||
{
|
||||
if (this.Any(c => c.Name == column.Name))
|
||||
{
|
||||
// The designer sucks, doing nothing for now
|
||||
return;
|
||||
|
||||
throw new InvalidOperationException("A column with this name already exists.");
|
||||
}
|
||||
|
||||
base.Insert(index, column);
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public new void InsertRange(int index, IEnumerable<RollColumn> collection)
|
||||
{
|
||||
var items = collection.ToList();
|
||||
foreach (var column in items)
|
||||
{
|
||||
if (this.Any(c => c.Name == column.Name))
|
||||
{
|
||||
throw new InvalidOperationException("A column with this name already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
base.InsertRange(index, items);
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public new bool Remove(RollColumn column)
|
||||
{
|
||||
var result = base.Remove(column);
|
||||
ColumnsChanged();
|
||||
return result;
|
||||
}
|
||||
|
||||
public new int RemoveAll(Predicate<RollColumn> match)
|
||||
{
|
||||
var result = base.RemoveAll(match);
|
||||
ColumnsChanged();
|
||||
return result;
|
||||
}
|
||||
|
||||
public new void RemoveAt(int index)
|
||||
{
|
||||
base.RemoveAt(index);
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public new void RemoveRange(int index, int count)
|
||||
{
|
||||
base.RemoveRange(index, count);
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public new void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
ColumnsChanged();
|
||||
}
|
||||
|
||||
public IEnumerable<string> Groups => this
|
||||
.Select(x => x.Group)
|
||||
.Distinct();
|
||||
}
|
||||
}
|
|
@ -47,6 +47,7 @@ namespace BizHawk.Client.EmuHawk.CustomControls
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.ControlBox = false; // Do not set in designer (causes problems with auto scaling)
|
||||
this.messageLbl.Text = message;
|
||||
this.Text = title;
|
||||
this.m_sysIcon = icon;
|
||||
|
@ -58,7 +59,7 @@ namespace BizHawk.Client.EmuHawk.CustomControls
|
|||
public void SetMessageToAutoSize()
|
||||
{
|
||||
this.messageLbl.AutoSize = true;
|
||||
this.messageLbl.MaximumSize = new Size(this.MaximumSize.Width - this.m_sysIcon.Width - 25, this.MaximumSize.Height);
|
||||
this.messageLbl.MaximumSize = new Size(this.MaximumSize.Width - this.m_sysIcon.Width - UIHelper.ScaleX(25), this.MaximumSize.Height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -220,11 +221,11 @@ namespace BizHawk.Client.EmuHawk.CustomControls
|
|||
|
||||
}
|
||||
|
||||
const int FORM_Y_MARGIN = 10;
|
||||
const int FORM_X_MARGIN = 16;
|
||||
const int BUTTON_SPACE = 5;
|
||||
const int CHECKBOX_SPACE = 15;
|
||||
const int TEXT_Y_MARGIN = 30;
|
||||
private static readonly int FORM_Y_MARGIN = UIHelper.ScaleY(10);
|
||||
private static readonly int FORM_X_MARGIN = UIHelper.ScaleX(16);
|
||||
private static readonly int BUTTON_SPACE = UIHelper.ScaleX(5);
|
||||
private static readonly int CHECKBOX_SPACE = UIHelper.ScaleX(15);
|
||||
private static readonly int TEXT_Y_MARGIN = UIHelper.ScaleY(30);
|
||||
|
||||
/// <summary>
|
||||
/// Auto fits the dialog box to fit the text and the buttons.
|
||||
|
|
|
@ -105,7 +105,6 @@
|
|||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btn1;
|
||||
this.ClientSize = new System.Drawing.Size(485, 149);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.btn3);
|
||||
this.Controls.Add(this.chkBx);
|
||||
this.Controls.Add(this.btn1);
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public class TasListView : VirtualListView
|
||||
{
|
||||
public class Cell
|
||||
{
|
||||
public int? RowIndex;
|
||||
public string Column;
|
||||
|
||||
// Convenience hack
|
||||
public override string ToString()
|
||||
{
|
||||
return string.IsNullOrEmpty(Column) ? "?" : $"{Column} - {(RowIndex.HasValue ? RowIndex.ToString() : "?")}";
|
||||
}
|
||||
}
|
||||
|
||||
public bool RightButtonHeld { get; set; }
|
||||
|
||||
public int? LastSelectedIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SelectedIndices.Count > 0)
|
||||
{
|
||||
return SelectedIndices
|
||||
.OfType<int>()
|
||||
.OrderBy(x => x)
|
||||
.Last();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Cell _currentPointedCell = new Cell();
|
||||
public Cell CurrentCell
|
||||
{
|
||||
get { return _currentPointedCell; }
|
||||
}
|
||||
|
||||
private Cell _lastPointedCell = new Cell();
|
||||
public Cell LastCell
|
||||
{
|
||||
get { return _lastPointedCell; }
|
||||
}
|
||||
|
||||
public bool InputPaintingMode { get; set; }
|
||||
public bool IsPaintDown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the column name and row number that the point (x, y) lies in.
|
||||
/// </summary>
|
||||
/// <param name="x">X coordinate</param>
|
||||
/// <param name="y">Y coordinate</param>
|
||||
private void CalculatePointedCell(int x, int y)
|
||||
{
|
||||
int? newRow;
|
||||
string newColumn = "";
|
||||
|
||||
var accumulator = 0;
|
||||
foreach (ColumnHeader column in Columns)
|
||||
{
|
||||
accumulator += column.Width;
|
||||
if (accumulator < x)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
newColumn = column.Name;
|
||||
break;
|
||||
}
|
||||
|
||||
var rowHeight = this.LineHeight;// 5 (in VirtualListView) and 6 work here for me, but are they always dependable, how can I get the padding?
|
||||
var headerHeight = rowHeight + 6;
|
||||
|
||||
newRow = ((y - headerHeight) / rowHeight) + this.VScrollPos;
|
||||
if (newRow >= ItemCount)
|
||||
{
|
||||
newRow = null;
|
||||
}
|
||||
|
||||
if (newColumn != CurrentCell.Column || newRow != CurrentCell.RowIndex)
|
||||
{
|
||||
LastCell.Column = CurrentCell.Column;
|
||||
LastCell.RowIndex = CurrentCell.RowIndex;
|
||||
|
||||
CurrentCell.Column = newColumn;
|
||||
CurrentCell.RowIndex = newRow;
|
||||
|
||||
CellChanged(LastCell, CurrentCell);
|
||||
}
|
||||
}
|
||||
|
||||
public class CellEventArgs
|
||||
{
|
||||
public CellEventArgs(Cell oldCell, Cell newCell)
|
||||
{
|
||||
OldCell = oldCell;
|
||||
NewCell = newCell;
|
||||
}
|
||||
|
||||
public Cell OldCell { get; private set; }
|
||||
public Cell NewCell { get; private set; }
|
||||
}
|
||||
|
||||
public delegate void CellChangeEventHandler(object sender, CellEventArgs e);
|
||||
public event CellChangeEventHandler PointedCellChanged;
|
||||
|
||||
private void CellChanged(Cell oldCell, Cell newCell)
|
||||
{
|
||||
if (PointedCellChanged != null)
|
||||
{
|
||||
PointedCellChanged(this, new CellEventArgs(oldCell, newCell));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
_currentPointedCell.Column = "";
|
||||
_currentPointedCell.RowIndex = null;
|
||||
IsPaintDown = false;
|
||||
base.OnMouseLeave(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
CalculatePointedCell(e.X, e.Y);
|
||||
base.OnMouseMove(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left && InputPaintingMode)
|
||||
{
|
||||
IsPaintDown = true;
|
||||
}
|
||||
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
RightButtonHeld = true;
|
||||
}
|
||||
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
{
|
||||
IsPaintDown = false;
|
||||
RightButtonHeld = false;
|
||||
|
||||
base.OnMouseUp(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
if (RightButtonHeld)
|
||||
{
|
||||
DoRightMouseScroll(this, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnMouseWheel(e);
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void RightMouseScrollEventHandler(object sender, MouseEventArgs e);
|
||||
public event RightMouseScrollEventHandler RightMouseScrolled;
|
||||
|
||||
private void DoRightMouseScroll(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (RightMouseScrolled != null)
|
||||
{
|
||||
RightMouseScrolled(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="RightClickMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -1,854 +0,0 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
#region win32interop
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct LvDispInfo
|
||||
{
|
||||
public NmHdr Hdr;
|
||||
public LvItem Item;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NmHdr
|
||||
{
|
||||
public IntPtr HwndFrom;
|
||||
public IntPtr IdFrom;
|
||||
public int Code;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NmItemActivate
|
||||
{
|
||||
public NmHdr Hdr;
|
||||
public int Item;
|
||||
public int SubItem;
|
||||
public uint NewState;
|
||||
public uint OldState;
|
||||
public uint uChanged;
|
||||
public POINT Action;
|
||||
public uint lParam;
|
||||
public uint KeyFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct RECT
|
||||
{
|
||||
public int Top;
|
||||
public int Left;
|
||||
public int Bottom;
|
||||
public int Right;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NmCustomDrawInfo
|
||||
{
|
||||
public NmHdr Hdr;
|
||||
public uint dwDrawStage;
|
||||
public IntPtr Hdc;
|
||||
public RECT Rect;
|
||||
public IntPtr dwItemSpec;
|
||||
public uint ItemState;
|
||||
private int _pad64bits;
|
||||
public IntPtr lItemlParam;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NmLvCustomDraw
|
||||
{
|
||||
public NmCustomDrawInfo Nmcd;
|
||||
public int ClearText;
|
||||
public int ClearTextBackground;
|
||||
public int SubItem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
internal struct LvItem
|
||||
{
|
||||
public uint Mask;
|
||||
public int Item;
|
||||
public int SubItem;
|
||||
public uint State;
|
||||
public uint StateMask;
|
||||
public IntPtr PszText;
|
||||
public int cchTextMax;
|
||||
public int Image;
|
||||
public IntPtr lParam;
|
||||
public int Indent;
|
||||
}
|
||||
|
||||
[FlagsAttribute]
|
||||
internal enum CustomDrawReturnFlags
|
||||
{
|
||||
CDRF_DODEFAULT = 0x00000000,
|
||||
CDRF_NEWFONT = 0x00000002,
|
||||
CDRF_SKIPDEFAULT = 0x00000004,
|
||||
CDRF_NOTIFYPOSTPAINT = 0x00000010,
|
||||
CDRF_NOTIFYITEMDRAW = 0x00000020,
|
||||
CDRF_NOTIFYSUBITEMDRAW = 0x00000020,
|
||||
CDRF_NOTIFYPOSTERASE = 0x00000040,
|
||||
}
|
||||
|
||||
[FlagsAttribute]
|
||||
internal enum CustomDrawDrawStageFlags
|
||||
{
|
||||
CDDS_PREPAINT = 0x00000001,
|
||||
CDDS_POSTPAINT = 0x00000002,
|
||||
CDDS_PREERASE = 0x00000003,
|
||||
CDDS_POSTERASE = 0x00000004,
|
||||
|
||||
// the 0x000010000 bit means it's individual item specific
|
||||
CDDS_ITEM = 0x00010000,
|
||||
CDDS_ITEMPREPAINT = (CDDS_ITEM | CDDS_PREPAINT),
|
||||
CDDS_ITEMPOSTPAINT = (CDDS_ITEM | CDDS_POSTPAINT),
|
||||
CDDS_ITEMPREERASE = (CDDS_ITEM | CDDS_PREERASE),
|
||||
CDDS_ITEMPOSTERASE = (CDDS_ITEM | CDDS_POSTERASE),
|
||||
CDDS_SUBITEM = 0x00020000,
|
||||
CDDS_SUBITEMPREPAINT = (CDDS_SUBITEM | CDDS_ITEMPREPAINT),
|
||||
CDDS_SUBITEMPOSTPAINT = (CDDS_SUBITEM | CDDS_ITEMPOSTPAINT),
|
||||
CDDS_SUBITEMPREERASE = (CDDS_SUBITEM | CDDS_ITEMPREERASE),
|
||||
CDDS_SUBITEMPOSTERASE = (CDDS_SUBITEM | CDDS_ITEMPOSTERASE),
|
||||
}
|
||||
|
||||
[FlagsAttribute]
|
||||
internal enum LvHitTestFlags
|
||||
{
|
||||
LVHT_NOWHERE = 0x0001,
|
||||
LVHT_ONITEMICON = 0x0002,
|
||||
LVHT_ONITEMLABEL = 0x0004,
|
||||
LVHT_ONITEMSTATEICON = 0x0008,
|
||||
LVHT_ONITEM = (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON),
|
||||
|
||||
LVHT_ABOVE = 0x0008,
|
||||
LVHT_BELOW = 0x0010,
|
||||
LVHT_TORIGHT = 0x0020,
|
||||
LVHT_TOLEFT = 0x0040
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct POINT
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class LvHitTestInfo
|
||||
{
|
||||
public POINT Point;
|
||||
public uint Flags;
|
||||
public int Item;
|
||||
public int SubItem;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NMLISTVIEW
|
||||
{
|
||||
public NmHdr hdr;
|
||||
public int iItem;
|
||||
public int iSubItem;
|
||||
public uint uNewState;
|
||||
public uint uOldState;
|
||||
public uint uChanged;
|
||||
public POINT ptAction;
|
||||
public IntPtr lParam;
|
||||
}
|
||||
|
||||
|
||||
internal enum ListViewItemMask : short
|
||||
{
|
||||
LVIF_TEXT = 0x0001,
|
||||
LVIF_IMAGE = 0x0002,
|
||||
LVIF_PARAM = 0x0004,
|
||||
LVIF_STATE = 0x0008,
|
||||
|
||||
LVIF_INDENT = 0x0010,
|
||||
LVIF_NORECOMPUTE = 0x0800,
|
||||
LVIF_GROUPID = 0x0100,
|
||||
LVIF_COLUMNS = 0x0200
|
||||
}
|
||||
|
||||
internal enum LvNi
|
||||
{
|
||||
ALL = 0x0000,
|
||||
FOCUSED = 0x0001,
|
||||
SELECTED = 0x0002,
|
||||
CUT = 0x0004,
|
||||
DROPHILITED = 0x0008,
|
||||
|
||||
ABOVE = 0x0100,
|
||||
BELOW = 0x0200,
|
||||
TOLEFT = 0x0400,
|
||||
TORIGHT = 0x0800
|
||||
}
|
||||
|
||||
internal enum ListViewMessages
|
||||
{
|
||||
LVM_FIRST = 0x1000,
|
||||
LVM_GETITEMCOUNT = (LVM_FIRST + 4),
|
||||
LVM_SETCALLBACKMASK = (LVM_FIRST + 11),
|
||||
LVM_GETNEXTITEM = (LVM_FIRST + 12),
|
||||
LVM_HITTEST = (LVM_FIRST + 18),
|
||||
LVM_ENSUREVISIBLE = (LVM_FIRST + 19),
|
||||
LVM_SETITEMSTATE = (LVM_FIRST + 43),
|
||||
LVM_GETITEMSTATE = (LVM_FIRST + 44),
|
||||
LVM_SETITEMCOUNT = (LVM_FIRST + 47),
|
||||
LVM_GETSUBITEMRECT = (LVM_FIRST + 56)
|
||||
}
|
||||
|
||||
internal enum ListViewStyles : short
|
||||
{
|
||||
LVS_OWNERDATA = 0x1000,
|
||||
LVS_SORTASCENDING = 0x0010,
|
||||
LVS_SORTDESCENDING = 0x0020,
|
||||
LVS_SHAREIMAGELISTS = 0x0040,
|
||||
LVS_NOLABELWRAP = 0x0080,
|
||||
LVS_AUTOARRANGE = 0x0100
|
||||
}
|
||||
|
||||
internal enum ListViewStylesICF : uint
|
||||
{
|
||||
LVSICF_NOINVALIDATEALL = 0x00000001,
|
||||
LVSICF_NOSCROLL = 0x00000002
|
||||
}
|
||||
|
||||
internal enum WindowsMessage : uint
|
||||
{
|
||||
WM_ERASEBKGND = 0x0014,
|
||||
WM_SCROLL = 0x115,
|
||||
WM_LBUTTONDOWN = 0x0201,
|
||||
WM_LBUTTONUP = 0x0202,
|
||||
WM_LBUTTONDBLCLK = 0x0203,
|
||||
WM_RBUTTONDOWN = 0x0204,
|
||||
WM_RBUTTONUP = 0x0205,
|
||||
WM_RBUTTONDBLCLK = 0x0206,
|
||||
WM_SETFOCUS = 0x0007,
|
||||
WM_NOTIFY = 0x004E,
|
||||
WM_USER = 0x0400,
|
||||
WM_REFLECT = WM_USER + 0x1c00
|
||||
}
|
||||
|
||||
internal enum Notices
|
||||
{
|
||||
NM_FIRST = 0,
|
||||
NM_CUSTOMDRAW = NM_FIRST - 12,
|
||||
NM_CLICK = NM_FIRST - 2,
|
||||
NM_DBLCLICK = NM_FIRST - 3,
|
||||
}
|
||||
|
||||
internal enum ListViewNotices
|
||||
{
|
||||
LVN_FIRST = (0 - 100),
|
||||
LVN_LAST = (0 - 199),
|
||||
LVN_BEGINDRAG = LVN_FIRST - 9,
|
||||
LVN_BEGINRDRAG = LVN_FIRST - 11,
|
||||
LVN_GETDISPINFOA = LVN_FIRST - 50,
|
||||
LVN_GETDISPINFOW = LVN_FIRST - 77,
|
||||
LVN_SETDISPINFOA = LVN_FIRST - 51,
|
||||
LVN_SETDISPINFOW = LVN_FIRST - 78,
|
||||
LVN_ODCACHEHINT = LVN_FIRST - 13,
|
||||
LVN_ODFINDITEMW = LVN_FIRST - 79
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum ListViewCallBackMask : uint
|
||||
{
|
||||
LVIS_FOCUSED = 0x0001,
|
||||
LVIS_SELECTED = 0x0002,
|
||||
LVIS_CUT = 0x0004,
|
||||
LVIS_DROPHILITED = 0x0008,
|
||||
LVIS_GLOW = 0x0010,
|
||||
LVIS_ACTIVATING = 0x0020,
|
||||
|
||||
LVIS_OVERLAYMASK = 0x0F00,
|
||||
LVIS_STATEIMAGEMASK = 0xF000,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region VirtualListView Delegates
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the background color for a Listview cell (item and subitem).
|
||||
/// </summary>
|
||||
/// <param name="item">Listview item (row).</param>
|
||||
/// <param name="subItem">Listview subitem (column).</param>
|
||||
/// <param name="color">Background color to use</param>
|
||||
public delegate void QueryItemBkColorHandler(int item, int subItem, ref Color color);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the text for a Listview cell (item and subitem).
|
||||
/// </summary>
|
||||
/// <param name="item">Listview item (row).</param>
|
||||
/// <param name="subItem">Listview subitem (column).</param>
|
||||
/// <param name="text">Text to display.</param>
|
||||
public delegate void QueryItemTextHandler(int item, int subItem, out string text);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the image index for a Listview item.
|
||||
/// </summary>
|
||||
/// <param name="item">Listview item (row).</param>
|
||||
/// <param name="subItem">Listview subitem (column) - should always be zero.</param>
|
||||
/// <param name="imageIndex">Index of associated ImageList.</param>
|
||||
public delegate void QueryItemImageHandler(int item, int subItem, out int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the indent for a Listview item. The indent is always width of an image.
|
||||
/// For example, 1 indents the Listview item one image width.
|
||||
/// </summary>
|
||||
/// <param name="item">Listview item (row).</param>
|
||||
/// <param name="itemIndent">The amount to indent the Listview item.</param>
|
||||
public delegate void QueryItemIndentHandler(int item, out int itemIndent);
|
||||
|
||||
public delegate void QueryItemHandler(int idx, out ListViewItem item);
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// VirtualListView is a virtual Listview which allows for a large number of items(rows)
|
||||
/// to be displayed. The virtual Listview contains very little actual information -
|
||||
/// mainly item selection and focus information.
|
||||
/// </summary>
|
||||
public class VirtualListView : ListView
|
||||
{
|
||||
// store the item count to prevent the call to SendMessage(LVM_GETITEMCOUNT)
|
||||
private int _itemCount;
|
||||
|
||||
#region Display query callbacks
|
||||
|
||||
/// <summary>
|
||||
/// Fire the QueryItemBkColor event which requests the background color for the passed Listview cell
|
||||
/// </summary>
|
||||
public event QueryItemBkColorHandler QueryItemBkColor;
|
||||
|
||||
/// <summary>
|
||||
/// Fire the QueryItemText event which requests the text for the passed Listview cell.
|
||||
/// </summary>
|
||||
[Category("Data")]
|
||||
public event QueryItemTextHandler QueryItemText;
|
||||
|
||||
/// <summary>
|
||||
/// Fire the QueryItemImage event which requests the ImageIndex for the passed Listview item.
|
||||
/// </summary>
|
||||
[Category("Data")]
|
||||
public event QueryItemImageHandler QueryItemImage;
|
||||
|
||||
/// <summary>
|
||||
/// Fire the QueryItemIndent event which requests the indent for the passed Listview item.
|
||||
/// </summary>
|
||||
[Category("Data")]
|
||||
public event QueryItemIndentHandler QueryItemIndent;
|
||||
|
||||
[Category("Data")]
|
||||
public event QueryItemHandler QueryItem;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sets the virtual number of items to be displayed.
|
||||
/// </summary>
|
||||
[Category("Behavior")]
|
||||
public int ItemCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _itemCount;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_itemCount = value;
|
||||
|
||||
// If the virtual item count is set before the handle is created
|
||||
// then the image lists don't get loaded properly
|
||||
if (!IsHandleCreated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetVirtualItemCount();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets how list items are to be displayed.
|
||||
/// Hide the ListView.View property.
|
||||
/// Virtual Listviews only allow Details or List.
|
||||
/// </summary>
|
||||
public new View View
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.View;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value == View.LargeIcon ||
|
||||
value == View.SmallIcon)
|
||||
{
|
||||
throw new ArgumentException($"Icon views are invalid for virtual {nameof(ListView)}s", nameof(View));
|
||||
}
|
||||
|
||||
base.View = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the required creation parameters when the control handle is created.
|
||||
/// Use LVS_OWNERDATA to set this as a virtual Listview.
|
||||
/// </summary>
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
var cp = base.CreateParams;
|
||||
|
||||
// LVS_OWNERDATA style must be set when the control is created
|
||||
cp.Style |= (int)ListViewStyles.LVS_OWNERDATA;
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public int LineHeight { get; private set; }
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]
|
||||
public int NumberOfVisibleRows
|
||||
{
|
||||
get
|
||||
{
|
||||
return Height / LineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="VirtualListView"/> class.
|
||||
/// Create a new instance of this control.
|
||||
/// </summary>
|
||||
public VirtualListView()
|
||||
{
|
||||
// virtual listviews must be Details or List view with no sorting
|
||||
View = View.Details;
|
||||
Sorting = SortOrder.None;
|
||||
|
||||
UseCustomBackground = true;
|
||||
|
||||
ptrlvhti = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LvHitTestInfo)));
|
||||
|
||||
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
|
||||
SetStyle(ControlStyles.Opaque, true);
|
||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||
|
||||
LineHeight = this.Font.Height + 5;
|
||||
}
|
||||
|
||||
~VirtualListView()
|
||||
{
|
||||
Marshal.FreeHGlobal(ptrlvhti);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>
|
||||
/// Set the state of the passed Listview item's index.
|
||||
/// </summary>
|
||||
/// <param name="index">Listview item's index.</param>
|
||||
/// <param name="selected">Select the passed item?</param>
|
||||
public void SelectItem(int index, bool selected)
|
||||
{
|
||||
var ptrItem = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
// Determine whether selecting or unselecting.
|
||||
uint select = selected ? (uint)ListViewCallBackMask.LVIS_SELECTED : 0;
|
||||
|
||||
// Fill in the LVITEM structure with state fields.
|
||||
var stateItem = new LvItem
|
||||
{
|
||||
Mask = (uint)ListViewItemMask.LVIF_STATE,
|
||||
Item = index,
|
||||
SubItem = 0,
|
||||
State = @select,
|
||||
StateMask = (uint)ListViewCallBackMask.LVIS_SELECTED
|
||||
};
|
||||
|
||||
// Copy the structure to unmanaged memory.
|
||||
ptrItem = Marshal.AllocHGlobal(Marshal.SizeOf(stateItem.GetType()));
|
||||
Marshal.StructureToPtr(stateItem, ptrItem, true);
|
||||
|
||||
// Send the message to the control window.
|
||||
Win32.SendMessage(
|
||||
this.Handle,
|
||||
(int)ListViewMessages.LVM_SETITEMSTATE,
|
||||
(IntPtr)index,
|
||||
ptrItem);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Trace.WriteLine($"VirtualListView.SetItemState error={ex.Message}");
|
||||
|
||||
// TODO: should this eat any exceptions?
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Always release the unmanaged memory.
|
||||
if (ptrItem != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(ptrItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetVirtualItemCount()
|
||||
{
|
||||
Win32.SendMessage(
|
||||
this.Handle,
|
||||
(int)ListViewMessages.LVM_SETITEMCOUNT,
|
||||
(IntPtr)this._itemCount,
|
||||
IntPtr.Zero);
|
||||
}
|
||||
|
||||
protected void OnDispInfoNotice(ref Message m, bool useAnsi)
|
||||
{
|
||||
var info = (LvDispInfo)m.GetLParam(typeof(LvDispInfo));
|
||||
|
||||
if ((info.Item.Mask & (uint)ListViewItemMask.LVIF_TEXT) > 0)
|
||||
{
|
||||
if (QueryItemText != null)
|
||||
{
|
||||
string lvtext;
|
||||
QueryItemText(info.Item.Item, info.Item.SubItem, out lvtext);
|
||||
if (lvtext != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
int maxIndex = Math.Min(info.Item.cchTextMax - 1, lvtext.Length);
|
||||
var data = new char[maxIndex + 1];
|
||||
lvtext.CopyTo(0, data, 0, lvtext.Length);
|
||||
data[maxIndex] = '\0';
|
||||
Marshal.Copy(data, 0, info.Item.PszText, data.Length);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine($"Failed to copy text name from client: {e}", $"{nameof(VirtualListView)}.{nameof(OnDispInfoNotice)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((info.Item.Mask & (uint)ListViewItemMask.LVIF_IMAGE) > 0)
|
||||
{
|
||||
int imageIndex = 0;
|
||||
if (QueryItemImage != null)
|
||||
{
|
||||
QueryItemImage(info.Item.Item, info.Item.SubItem, out imageIndex);
|
||||
}
|
||||
|
||||
info.Item.Image = imageIndex;
|
||||
Marshal.StructureToPtr(info, m.LParam, false);
|
||||
}
|
||||
|
||||
if ((info.Item.Mask & (uint)ListViewItemMask.LVIF_INDENT) > 0)
|
||||
{
|
||||
int itemIndent = 0;
|
||||
if (QueryItemIndent != null)
|
||||
{
|
||||
QueryItemIndent(info.Item.Item, out itemIndent);
|
||||
}
|
||||
|
||||
info.Item.Indent = itemIndent;
|
||||
Marshal.StructureToPtr(info, m.LParam, false);
|
||||
}
|
||||
|
||||
m.Result = new IntPtr(0);
|
||||
}
|
||||
|
||||
protected void OnCustomDrawNotice(ref Message m)
|
||||
{
|
||||
var cd = (NmLvCustomDraw)m.GetLParam(typeof(NmLvCustomDraw));
|
||||
switch (cd.Nmcd.dwDrawStage)
|
||||
{
|
||||
case (int)CustomDrawDrawStageFlags.CDDS_ITEMPREPAINT:
|
||||
case (int)CustomDrawDrawStageFlags.CDDS_PREPAINT:
|
||||
m.Result = new IntPtr((int)CustomDrawReturnFlags.CDRF_NOTIFYSUBITEMDRAW);
|
||||
break;
|
||||
case (int)CustomDrawDrawStageFlags.CDDS_SUBITEMPREPAINT:
|
||||
if (QueryItemBkColor != null)
|
||||
{
|
||||
var color = Color.FromArgb(cd.ClearTextBackground & 0xFF, (cd.ClearTextBackground >> 8) & 0xFF, (cd.ClearTextBackground >> 16) & 0xFF);
|
||||
QueryItemBkColor(cd.Nmcd.dwItemSpec.ToInt32(), cd.SubItem, ref color);
|
||||
cd.ClearTextBackground = (color.B << 16) | (color.G << 8) | color.R;
|
||||
Marshal.StructureToPtr(cd, m.LParam, false);
|
||||
}
|
||||
|
||||
m.Result = new IntPtr((int)CustomDrawReturnFlags.CDRF_DODEFAULT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event to be fired whenever the control scrolls
|
||||
/// </summary>
|
||||
public event ScrollEventHandler Scroll;
|
||||
protected virtual void OnScroll(ScrollEventArgs e)
|
||||
{
|
||||
var handler = this.Scroll;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern int GetScrollPos(IntPtr hWnd, Orientation nBar);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Vertical Scroll position of the control.
|
||||
/// </summary>
|
||||
public int VScrollPos
|
||||
{
|
||||
get { return GetScrollPos(this.Handle, Orientation.Vertical); }
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
var messageProcessed = false;
|
||||
switch (m.Msg)
|
||||
{
|
||||
case (int)WindowsMessage.WM_REFLECT + (int)WindowsMessage.WM_NOTIFY:
|
||||
var nm1 = (NmHdr)m.GetLParam(typeof(NmHdr));
|
||||
switch (nm1.Code)
|
||||
{
|
||||
case (int)Notices.NM_CUSTOMDRAW:
|
||||
OnCustomDrawNotice(ref m);
|
||||
messageProcessed = true;
|
||||
|
||||
if (QueryItemBkColor == null || !UseCustomBackground)
|
||||
{
|
||||
m.Result = (IntPtr)0;
|
||||
}
|
||||
|
||||
break;
|
||||
case (int)ListViewNotices.LVN_GETDISPINFOW:
|
||||
OnDispInfoNotice(ref m, false);
|
||||
messageProcessed = true;
|
||||
break;
|
||||
case (int)ListViewNotices.LVN_BEGINDRAG:
|
||||
OnBeginItemDrag(MouseButtons.Left, ref m);
|
||||
messageProcessed = true;
|
||||
break;
|
||||
case (int)ListViewNotices.LVN_BEGINRDRAG:
|
||||
OnBeginItemDrag(MouseButtons.Right, ref m);
|
||||
messageProcessed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case (int)WindowsMessage.WM_SCROLL:
|
||||
// http://stackoverflow.com/questions/1851620/handling-scroll-event-on-listview-in-c-sharp
|
||||
OnScroll(new ScrollEventArgs((ScrollEventType)(m.WParam.ToInt32() & 0xffff), m.WParam.ToInt32()));
|
||||
break;
|
||||
case (int)WindowsMessage.WM_ERASEBKGND:
|
||||
if (BlazingFast)
|
||||
{
|
||||
messageProcessed = true;
|
||||
m.Result = new IntPtr(1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!messageProcessed)
|
||||
{
|
||||
try
|
||||
{
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine($"Message {m} caused an exception: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool BlazingFast { get; set; }
|
||||
public bool UseCustomBackground { get; set; }
|
||||
|
||||
protected ListViewItem GetItem(int idx)
|
||||
{
|
||||
ListViewItem item = null;
|
||||
if (QueryItem != null)
|
||||
{
|
||||
QueryItem(idx, out item);
|
||||
}
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentException($"cannot find item {idx} via {nameof(QueryItem)} event");
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
protected void OnBeginItemDrag(MouseButtons mouseButton, ref Message m)
|
||||
{
|
||||
var info = (NMLISTVIEW)m.GetLParam(typeof(NMLISTVIEW));
|
||||
ListViewItem item = null;
|
||||
if (QueryItem != null)
|
||||
{
|
||||
QueryItem(info.iItem, out item);
|
||||
}
|
||||
|
||||
OnItemDrag(new ItemDragEventArgs(mouseButton, item));
|
||||
}
|
||||
|
||||
protected override void OnHandleCreated(EventArgs e)
|
||||
{
|
||||
base.OnHandleCreated(e);
|
||||
|
||||
// ensure the value for ItemCount is sent to the control properly if the user set it
|
||||
// before the handle was created
|
||||
SetVirtualItemCount();
|
||||
}
|
||||
|
||||
protected override void OnHandleDestroyed(EventArgs e)
|
||||
{
|
||||
// the ListView OnHandleDestroyed accesses the Items list for all selected items
|
||||
ItemCount = 0;
|
||||
base.OnHandleDestroyed(e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
LvHitTestInfo lvhti = new LvHitTestInfo();
|
||||
IntPtr ptrlvhti;
|
||||
int selection = -1;
|
||||
|
||||
public int hitTest(int x, int y)
|
||||
{
|
||||
lvhti.Point.X = x;
|
||||
lvhti.Point.Y = y;
|
||||
Marshal.StructureToPtr(lvhti, ptrlvhti, true);
|
||||
int z = (int)Win32.SendMessage(this.Handle, (int)ListViewMessages.LVM_HITTEST, (IntPtr)0, ptrlvhti);
|
||||
Marshal.PtrToStructure(ptrlvhti, lvhti);
|
||||
return z;
|
||||
}
|
||||
|
||||
public void ensureVisible(int index)
|
||||
{
|
||||
Win32.SendMessage(Handle, (int)ListViewMessages.LVM_ENSUREVISIBLE, (IntPtr)index, (IntPtr)1);
|
||||
}
|
||||
|
||||
public void ensureVisible()
|
||||
{
|
||||
ensureVisible(selectedItem);
|
||||
}
|
||||
|
||||
public void setSelection(int index)
|
||||
{
|
||||
clearSelection();
|
||||
selection = index;
|
||||
SelectItem(selection, true);
|
||||
}
|
||||
|
||||
public int selectedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SelectedIndices.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SelectedIndices[0];
|
||||
}
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
setSelection(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSelection()
|
||||
{
|
||||
if (selection != -1)
|
||||
{
|
||||
SelectItem(selection, false);
|
||||
}
|
||||
|
||||
selection = -1;
|
||||
}
|
||||
|
||||
// Informs user that a select all event is in place, can be used in change events to wait until this is false
|
||||
public bool SelectAllInProgress { get; set; }
|
||||
|
||||
public void SelectAll()
|
||||
{
|
||||
this.BeginUpdate();
|
||||
SelectAllInProgress = true;
|
||||
|
||||
for (var i = 0; i < _itemCount; i++)
|
||||
{
|
||||
if (i == _itemCount - 1)
|
||||
{
|
||||
SelectAllInProgress = false;
|
||||
}
|
||||
|
||||
this.SelectItem(i, true);
|
||||
}
|
||||
|
||||
this.EndUpdate();
|
||||
}
|
||||
|
||||
public void DeselectAll()
|
||||
{
|
||||
this.BeginUpdate();
|
||||
SelectAllInProgress = true;
|
||||
|
||||
for (var i = 0; i < _itemCount; i++)
|
||||
{
|
||||
if (i == _itemCount - 1)
|
||||
{
|
||||
SelectAllInProgress = false;
|
||||
}
|
||||
|
||||
this.SelectItem(i, false);
|
||||
}
|
||||
|
||||
this.EndUpdate();
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.A && e.Control && !e.Alt && !e.Shift) // Select All
|
||||
{
|
||||
SelectAll();
|
||||
}
|
||||
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.EmuHawk.CustomControls;
|
||||
using BizHawk.Emulation.Common;
|
||||
using Cores = BizHawk.Emulation.Cores;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public static class EmuHawkUtil
|
||||
{
|
||||
public static bool EnsureCoreIsAccurate(IEmulator emulator)
|
||||
{
|
||||
static bool PromptToSwitchCore(string currentCore, string recommendedCore, Action disableCurrentCore)
|
||||
{
|
||||
using var box = new MsgBox(
|
||||
$"While the {currentCore} core is faster, it is not nearly as accurate as {recommendedCore}.{Environment.NewLine}It is recommended that you switch to the {recommendedCore} core for movie recording.{Environment.NewLine}Switch to {recommendedCore}?",
|
||||
"Accuracy Warning",
|
||||
MessageBoxIcon.Warning);
|
||||
|
||||
box.SetButtons(
|
||||
new[] { "Switch", "Continue" },
|
||||
new[] { DialogResult.Yes, DialogResult.Cancel });
|
||||
|
||||
box.MaximumSize = UIHelper.Scale(new Size(575, 175));
|
||||
box.SetMessageToAutoSize();
|
||||
|
||||
var result = box.ShowDialog();
|
||||
|
||||
if (result != DialogResult.Yes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
disableCurrentCore();
|
||||
GlobalWin.MainForm.RebootCore();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (emulator is Cores.Nintendo.SNES9X.Snes9x)
|
||||
{
|
||||
return PromptToSwitchCore("Snes9x", "bsnes", () => Global.Config.SNES_InSnes9x = false);
|
||||
}
|
||||
if (emulator is Cores.Consoles.Nintendo.QuickNES.QuickNES)
|
||||
{
|
||||
return PromptToSwitchCore("QuickNes", "NesHawk", () => Global.Config.NES_InQuickNES = false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,10 +7,7 @@ using System.Runtime.InteropServices;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
|
||||
namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
||||
{
|
||||
|
@ -43,44 +40,7 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
|||
return control.BeginInvoke(action);
|
||||
}
|
||||
|
||||
public static void AddColumn(this ListView listView, string columnName, bool enabled, int columnWidth)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
if (listView.Columns[columnName] == null)
|
||||
{
|
||||
var column = new ColumnHeader
|
||||
{
|
||||
Name = columnName,
|
||||
Text = columnName.Replace("Column", ""),
|
||||
Width = columnWidth,
|
||||
};
|
||||
|
||||
listView.Columns.Add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddColumn(this ListView listView, ToolDialogSettings.Column column)
|
||||
{
|
||||
if (column.Visible)
|
||||
{
|
||||
if (listView.Columns[column.Name] == null)
|
||||
{
|
||||
var lsstViewColumn = new ColumnHeader
|
||||
{
|
||||
Name = column.Name,
|
||||
Text = column.Name.Replace("Column", ""),
|
||||
Width = column.Width,
|
||||
DisplayIndex = column.Index
|
||||
};
|
||||
|
||||
listView.Columns.Add(lsstViewColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ToolStripMenuItem GenerateColumnsMenu(this ToolDialogSettings.ColumnList list, Action changeCallback)
|
||||
public static ToolStripMenuItem ToColumnsMenu(this InputRoll inputRoll, Action changeCallback)
|
||||
{
|
||||
var menu = new ToolStripMenuItem
|
||||
{
|
||||
|
@ -88,33 +48,31 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
|||
Text = "Columns"
|
||||
};
|
||||
|
||||
var dummyList = list;
|
||||
var columns = inputRoll.AllColumns;
|
||||
|
||||
foreach (var column in dummyList)
|
||||
foreach (var column in columns)
|
||||
{
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = column.Name,
|
||||
Text = column.Name.Replace("Column", "")
|
||||
Text = $"{column.Text} ({column.Name})",
|
||||
Checked = column.Visible,
|
||||
CheckOnClick = true,
|
||||
Tag = column.Name
|
||||
};
|
||||
|
||||
menuItem.Click += (o, ev) =>
|
||||
menuItem.CheckedChanged += (o, ev) =>
|
||||
{
|
||||
dummyList[menuItem.Name].Visible ^= true;
|
||||
var sender = (ToolStripMenuItem)o;
|
||||
columns.Find(c => c.Name == (string)sender.Tag).Visible = sender.Checked;
|
||||
columns.ColumnsChanged();
|
||||
changeCallback();
|
||||
inputRoll.Refresh();
|
||||
};
|
||||
|
||||
menu.DropDownItems.Add(menuItem);
|
||||
}
|
||||
|
||||
menu.DropDownOpened += (o, e) =>
|
||||
{
|
||||
foreach (var column in dummyList)
|
||||
{
|
||||
(menu.DropDownItems[column.Name] as ToolStripMenuItem).Checked = column.Visible;
|
||||
}
|
||||
};
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
@ -123,6 +81,13 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
|||
return control.PointToScreen(new Point(child.Location.X, child.Location.Y));
|
||||
}
|
||||
|
||||
public static Color Add(this Color color, int val)
|
||||
{
|
||||
var col = color.ToArgb();
|
||||
col += val;
|
||||
return Color.FromArgb(col);
|
||||
}
|
||||
|
||||
#region Enumerable to Enumerable<T>
|
||||
|
||||
/// <summary>
|
||||
|
@ -139,16 +104,6 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
|||
return tabControl.TabPages.Cast<TabPage>();
|
||||
}
|
||||
|
||||
public static IEnumerable<int> SelectedIndices(this ListView listView)
|
||||
{
|
||||
return listView.SelectedIndices.Cast<int>();
|
||||
}
|
||||
|
||||
public static IEnumerable<ColumnHeader> ColumnHeaders(this ListView listView)
|
||||
{
|
||||
return listView.Columns.OfType<ColumnHeader>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -251,7 +206,7 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
|||
{
|
||||
foreach (ListViewItem.ListViewSubItem item in listViewControl.Items[index].SubItems)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(item.Text))
|
||||
if (!string.IsNullOrWhiteSpace(item.Text))
|
||||
{
|
||||
sb.Append(item.Text).Append('\t');
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using BizHawk.Emulation.Cores.Nintendo.SNES9X;
|
|||
using BizHawk.Emulation.Cores.Sega.Saturn;
|
||||
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
|
||||
using BizHawk.Emulation.Cores.Sony.PSP;
|
||||
using BizHawk.Emulation.Cores.Arcades.MAME;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
|
@ -51,6 +52,10 @@ namespace BizHawk.Client.EmuHawk.CoreExtensions
|
|||
{
|
||||
return Properties.Resources.snes9x;
|
||||
}
|
||||
else if (core is MAME)
|
||||
{
|
||||
return Properties.Resources.mame;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace BizHawk.Client.EmuHawk.ToolExtensions
|
|||
}
|
||||
|
||||
//TODO - do TSMI and TSDD need disposing? yuck
|
||||
var item = new ToolStripMenuItem { Text = caption };
|
||||
var item = new ToolStripMenuItem { Text = caption.Replace("&", "&&") };
|
||||
items.Add(item);
|
||||
|
||||
item.Click += (o, ev) =>
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public class FileFilterEntry
|
||||
{
|
||||
public string Description { get; }
|
||||
public string[] Filters { get; }
|
||||
public string[] DeveloperFilters { get; }
|
||||
|
||||
public FileFilterEntry(string description, string filters, string developerFilters = null)
|
||||
{
|
||||
Description = description;
|
||||
Filters = filters?.Split(';') ?? Array.Empty<string>();
|
||||
DeveloperFilters = developerFilters?.Split(';') ?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
public IEnumerable<string> EffectiveFilters
|
||||
{
|
||||
get
|
||||
{
|
||||
IEnumerable<string> effectiveFilters = Filters;
|
||||
if (VersionInfo.DeveloperBuild)
|
||||
{
|
||||
effectiveFilters = effectiveFilters.Concat(DeveloperFilters);
|
||||
}
|
||||
return effectiveFilters;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
@ -40,31 +39,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
// This is the list from MainForm->RomFilter()'s non-developer build. It needs to be kept up-to-date when new cores are added.
|
||||
// adelikat: This is annoying and bad. Maybe we could generate RomFilter from this property?
|
||||
private string[] KnownRomExtensions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (VersionInfo.DeveloperBuild)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC",
|
||||
".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML",
|
||||
".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF", ".EXE", ".PRG", ".D64", ".G64", ".CRT", ".TAP", ".32X", ".MDS", ".TZX",
|
||||
".PZX", ".CSW", ".WAV", ".CDT"
|
||||
};
|
||||
}
|
||||
|
||||
return new[]
|
||||
{
|
||||
".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC",
|
||||
".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML",
|
||||
".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF", ".PRG", ".D64", ".G64", ".CRT", ".TAP", ".32X", ".MDS", ".TZX", ".PZX", ".CSW", ".WAV"
|
||||
};
|
||||
}
|
||||
}
|
||||
private IEnumerable<string> KnownRomExtensions =>
|
||||
RomFilterEntries.SelectMany(f => f.EffectiveFilters.Where(s => s.StartsWith("*.", StringComparison.Ordinal)).Select(s => s.Substring(1).ToUpperInvariant()));
|
||||
|
||||
private readonly string[] _nonArchive = { ".ISO", ".CUE", ".CCD" };
|
||||
|
||||
|
@ -173,7 +149,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
foreach (string file in fileList)
|
||||
{
|
||||
var ext = Path.GetExtension(file).ToUpper() ?? "";
|
||||
var ext = Path.GetExtension(file).ToUpperInvariant() ?? "";
|
||||
FileInformation fileInformation = new FileInformation(Path.GetDirectoryName(file), Path.GetFileName(file), archive);
|
||||
|
||||
switch (ext)
|
||||
|
|
|
@ -3,8 +3,6 @@ using System.Linq;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
using SlimDX.DirectInput;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
|
@ -70,6 +68,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
Pad = 4
|
||||
}
|
||||
|
||||
public enum AllowInput
|
||||
{
|
||||
None = 0,
|
||||
All = 1,
|
||||
OnlyController = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If your form needs this kind of input focus, be sure to say so.
|
||||
/// Really, this only makes sense for mouse, but I've started building it out for other things
|
||||
|
@ -196,71 +201,53 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public LogicalButton LogicalButton;
|
||||
public InputEventType EventType;
|
||||
public InputFocus Source;
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{EventType.ToString()}:{LogicalButton.ToString()}";
|
||||
}
|
||||
}
|
||||
|
||||
private readonly WorkingDictionary<string, object> ModifierState = new WorkingDictionary<string, object>();
|
||||
private readonly Dictionary<string, LogicalButton> ModifierState = new Dictionary<string, LogicalButton>();
|
||||
private readonly WorkingDictionary<string, bool> LastState = new WorkingDictionary<string, bool>();
|
||||
private readonly WorkingDictionary<string, bool> UnpressState = new WorkingDictionary<string, bool>();
|
||||
private readonly HashSet<string> IgnoreKeys = new HashSet<string>(new[] { "LeftShift", "RightShift", "LeftControl", "RightControl", "LeftAlt", "RightAlt" });
|
||||
private readonly WorkingDictionary<string, float> FloatValues = new WorkingDictionary<string, float>();
|
||||
private readonly WorkingDictionary<string, float> FloatDeltas = new WorkingDictionary<string, float>();
|
||||
private bool trackdeltas = false;
|
||||
private bool IgnoreEventsNextPoll = false;
|
||||
|
||||
void HandleButton(string button, bool newState)
|
||||
void HandleButton(string button, bool newState, InputFocus source)
|
||||
{
|
||||
bool isModifier = IgnoreKeys.Contains(button);
|
||||
if (EnableIgnoreModifiers && isModifier) return;
|
||||
if (LastState[button] && newState) return;
|
||||
if (!LastState[button] && !newState) return;
|
||||
ModifierKey currentModifier = ButtonToModifierKey(button);
|
||||
if (EnableIgnoreModifiers && currentModifier != ModifierKey.None) return;
|
||||
if (LastState[button] == newState) return;
|
||||
|
||||
//apply
|
||||
//NOTE: this is not quite right. if someone held leftshift+rightshift it would be broken. seems unlikely, though.
|
||||
if (button == "LeftShift")
|
||||
if (currentModifier != ModifierKey.None)
|
||||
{
|
||||
_Modifiers &= ~ModifierKey.Shift;
|
||||
if (newState)
|
||||
_Modifiers |= ModifierKey.Shift;
|
||||
_Modifiers |= currentModifier;
|
||||
else
|
||||
_Modifiers &= ~currentModifier;
|
||||
}
|
||||
if (button == "RightShift") { _Modifiers &= ~ModifierKey.Shift; if (newState) _Modifiers |= ModifierKey.Shift; }
|
||||
if (button == "LeftControl") { _Modifiers &= ~ModifierKey.Control; if (newState) _Modifiers |= ModifierKey.Control; }
|
||||
if (button == "RightControl") { _Modifiers &= ~ModifierKey.Control; if (newState) _Modifiers |= ModifierKey.Control; }
|
||||
if (button == "LeftAlt") { _Modifiers &= ~ModifierKey.Alt; if (newState) _Modifiers |= ModifierKey.Alt; }
|
||||
if (button == "RightAlt") { _Modifiers &= ~ModifierKey.Alt; if (newState) _Modifiers |= ModifierKey.Alt; }
|
||||
|
||||
if (UnpressState.ContainsKey(button))
|
||||
{
|
||||
if (newState) return;
|
||||
Console.WriteLine($"Removing Unpress {button} with {nameof(newState)} {newState}");
|
||||
UnpressState.Remove(button);
|
||||
LastState[button] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//dont generate events for things like Ctrl+LeftControl
|
||||
ModifierKey mods = _Modifiers;
|
||||
if (button == "LeftShift") mods &= ~ModifierKey.Shift;
|
||||
if (button == "RightShift") mods &= ~ModifierKey.Shift;
|
||||
if (button == "LeftControl") mods &= ~ModifierKey.Control;
|
||||
if (button == "RightControl") mods &= ~ModifierKey.Control;
|
||||
if (button == "LeftAlt") mods &= ~ModifierKey.Alt;
|
||||
if (button == "RightAlt") mods &= ~ModifierKey.Alt;
|
||||
if (currentModifier != ModifierKey.None)
|
||||
mods &= ~currentModifier;
|
||||
|
||||
var ie = new InputEvent
|
||||
{
|
||||
EventType = newState ? InputEventType.Press : InputEventType.Release,
|
||||
LogicalButton = new LogicalButton(button, mods)
|
||||
LogicalButton = new LogicalButton(button, mods),
|
||||
Source = source
|
||||
};
|
||||
LastState[button] = newState;
|
||||
|
||||
//track the pressed events with modifiers that we send so that we can send corresponding unpresses with modifiers
|
||||
//this is an interesting idea, which we may need later, but not yet.
|
||||
//for example, you may see this series of events: press:ctrl+c, release:ctrl, release:c
|
||||
//but you might would rather have press:ctr+c, release:ctrl+c
|
||||
//but you might would rather have press:ctrl+c, release:ctrl+c
|
||||
//this code relates the releases to the original presses.
|
||||
//UPDATE - this is necessary for the frame advance key, which has a special meaning when it gets stuck down
|
||||
//so, i am adding it as of 11-sep-2011
|
||||
|
@ -270,32 +257,53 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ModifierState[button] != null)
|
||||
LogicalButton buttonModifierState;
|
||||
if (ModifierState.TryGetValue(button, out buttonModifierState))
|
||||
{
|
||||
LogicalButton alreadyReleased = ie.LogicalButton;
|
||||
var ieModified = new InputEvent
|
||||
{
|
||||
LogicalButton = (LogicalButton)ModifierState[button],
|
||||
EventType = InputEventType.Release
|
||||
};
|
||||
if (ieModified.LogicalButton != alreadyReleased)
|
||||
_NewEvents.Add(ieModified);
|
||||
if (buttonModifierState != ie.LogicalButton && !IgnoreEventsNextPoll)
|
||||
{
|
||||
_NewEvents.Add(
|
||||
new InputEvent
|
||||
{
|
||||
LogicalButton = buttonModifierState,
|
||||
EventType = InputEventType.Release,
|
||||
Source = source
|
||||
});
|
||||
}
|
||||
ModifierState.Remove(button);
|
||||
}
|
||||
ModifierState[button] = null;
|
||||
}
|
||||
|
||||
_NewEvents.Add(ie);
|
||||
if (!IgnoreEventsNextPoll)
|
||||
{
|
||||
_NewEvents.Add(ie);
|
||||
}
|
||||
}
|
||||
|
||||
ModifierKey _Modifiers;
|
||||
private static ModifierKey ButtonToModifierKey(string button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case "LeftShift": return ModifierKey.Shift;
|
||||
case "RightShift": return ModifierKey.Shift;
|
||||
case "LeftControl": return ModifierKey.Control;
|
||||
case "RightControl": return ModifierKey.Control;
|
||||
case "LeftAlt": return ModifierKey.Alt;
|
||||
case "RightAlt": return ModifierKey.Alt;
|
||||
}
|
||||
return ModifierKey.None;
|
||||
}
|
||||
|
||||
private ModifierKey _Modifiers;
|
||||
private readonly List<InputEvent> _NewEvents = new List<InputEvent>();
|
||||
|
||||
//do we need this?
|
||||
public void ClearEvents()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
InputEvents.Clear();
|
||||
// To "clear" anything currently in the input device buffers
|
||||
IgnoreEventsNextPoll = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,7 +359,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
//analyze keys
|
||||
foreach (var ke in keyEvents)
|
||||
HandleButton(ke.Key.ToString(), ke.Pressed);
|
||||
HandleButton(ke.Key.ToString(), ke.Pressed, InputFocus.Keyboard);
|
||||
|
||||
lock (FloatValues)
|
||||
{
|
||||
|
@ -378,7 +386,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
string xname = $"X{pad.PlayerNumber} ";
|
||||
for (int b = 0; b < pad.NumButtons; b++)
|
||||
HandleButton(xname + pad.ButtonName(b), pad.Pressed(b));
|
||||
HandleButton(xname + pad.ButtonName(b), pad.Pressed(b), InputFocus.Pad);
|
||||
foreach (var sv in pad.GetFloats())
|
||||
{
|
||||
string n = xname + sv.Item1;
|
||||
|
@ -394,7 +402,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
string jname = $"J{pad.PlayerNumber} ";
|
||||
for (int b = 0; b < pad.NumButtons; b++)
|
||||
HandleButton(jname + pad.ButtonName(b), pad.Pressed(b));
|
||||
HandleButton(jname + pad.ButtonName(b), pad.Pressed(b), InputFocus.Pad);
|
||||
foreach (var sv in pad.GetFloats())
|
||||
{
|
||||
string n = jname + sv.Item1;
|
||||
|
@ -423,11 +431,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
FloatValues["WMouse Y"] = P.Y;
|
||||
|
||||
var B = System.Windows.Forms.Control.MouseButtons;
|
||||
HandleButton("WMouse L", (B & System.Windows.Forms.MouseButtons.Left) != 0);
|
||||
HandleButton("WMouse C", (B & System.Windows.Forms.MouseButtons.Middle) != 0);
|
||||
HandleButton("WMouse R", (B & System.Windows.Forms.MouseButtons.Right) != 0);
|
||||
HandleButton("WMouse 1", (B & System.Windows.Forms.MouseButtons.XButton1) != 0);
|
||||
HandleButton("WMouse 2", (B & System.Windows.Forms.MouseButtons.XButton2) != 0);
|
||||
HandleButton("WMouse L", (B & System.Windows.Forms.MouseButtons.Left) != 0, InputFocus.Mouse);
|
||||
HandleButton("WMouse C", (B & System.Windows.Forms.MouseButtons.Middle) != 0, InputFocus.Mouse);
|
||||
HandleButton("WMouse R", (B & System.Windows.Forms.MouseButtons.Right) != 0, InputFocus.Mouse);
|
||||
HandleButton("WMouse 1", (B & System.Windows.Forms.MouseButtons.XButton1) != 0, InputFocus.Mouse);
|
||||
HandleButton("WMouse 2", (B & System.Windows.Forms.MouseButtons.XButton2) != 0, InputFocus.Mouse);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -439,22 +447,26 @@ namespace BizHawk.Client.EmuHawk
|
|||
//HandleButton("WMouse 1", false);
|
||||
//HandleButton("WMouse 2", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//WHAT!? WE SHOULD NOT BE SO NAIVELY TOUCHING MAINFORM FROM THE INPUTTHREAD. ITS BUSY RUNNING.
|
||||
bool swallow = !GlobalWin.MainForm.AllowInput(false);
|
||||
|
||||
foreach (var ie in _NewEvents)
|
||||
if (_NewEvents.Count != 0)
|
||||
{
|
||||
//events are swallowed in some cases:
|
||||
if (ie.LogicalButton.Alt && !GlobalWin.MainForm.AllowInput(true))
|
||||
{ }
|
||||
else if (ie.EventType == InputEventType.Press && swallow)
|
||||
{ }
|
||||
else
|
||||
//WHAT!? WE SHOULD NOT BE SO NAIVELY TOUCHING MAINFORM FROM THE INPUTTHREAD. ITS BUSY RUNNING.
|
||||
AllowInput allowInput = GlobalWin.MainForm.AllowInput(false);
|
||||
|
||||
foreach (var ie in _NewEvents)
|
||||
{
|
||||
//events are swallowed in some cases:
|
||||
if (ie.LogicalButton.Alt && ShouldSwallow(GlobalWin.MainForm.AllowInput(true), ie))
|
||||
continue;
|
||||
if (ie.EventType == InputEventType.Press && ShouldSwallow(allowInput, ie))
|
||||
continue;
|
||||
|
||||
EnqueueEvent(ie);
|
||||
}
|
||||
}
|
||||
|
||||
IgnoreEventsNextPoll = false;
|
||||
} //lock(this)
|
||||
|
||||
//arbitrary selection of polling frequency:
|
||||
|
@ -462,6 +474,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private static bool ShouldSwallow(AllowInput allowInput, InputEvent inputEvent)
|
||||
{
|
||||
return allowInput == AllowInput.None || (allowInput == AllowInput.OnlyController && inputEvent.Source != InputFocus.Pad);
|
||||
}
|
||||
|
||||
public void StartListeningForFloatEvents()
|
||||
{
|
||||
lock (FloatValues)
|
||||
|
@ -500,42 +517,39 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
//returns the next Press event, if available. should be useful
|
||||
public string GetNextBindEvent()
|
||||
public string GetNextBindEvent(ref InputEvent lastPress)
|
||||
{
|
||||
//this whole process is intimately involved with the data structures, which can conflict with the input thread.
|
||||
lock (this)
|
||||
{
|
||||
if (InputEvents.Count == 0) return null;
|
||||
if (!GlobalWin.MainForm.AllowInput(false)) return null;
|
||||
AllowInput allowInput = GlobalWin.MainForm.AllowInput(false);
|
||||
|
||||
//we only listen to releases for input binding, because we need to distinguish releases of pure modifierkeys from modified keys
|
||||
//wait for the first release after a press to complete input binding, because we need to distinguish pure modifierkeys from modified keys
|
||||
//if you just pressed ctrl, wanting to bind ctrl, we'd see: pressed:ctrl, unpressed:ctrl
|
||||
//if you just pressed ctrl+c, wanting to bind ctrl+c, we'd see: pressed:ctrl, pressed:ctrl+c, unpressed:ctrl+c, unpressed:ctrl
|
||||
//so its the first unpress we need to listen for
|
||||
//but in the 2nd example the unpresses will be swapped if ctrl is released first, so we'll take the last press before the release
|
||||
|
||||
while (InputEvents.Count != 0)
|
||||
{
|
||||
var ie = DequeueEvent();
|
||||
InputEvent ie = DequeueEvent();
|
||||
|
||||
//as a special perk, we'll accept escape immediately
|
||||
if (ie.EventType == InputEventType.Press && ie.LogicalButton.Button == "Escape")
|
||||
goto ACCEPT;
|
||||
if (ShouldSwallow(allowInput, ie)) continue;
|
||||
|
||||
if (ie.EventType == InputEventType.Press) continue;
|
||||
if (ie.EventType == InputEventType.Press)
|
||||
{
|
||||
lastPress = ie;
|
||||
//don't allow presses to directly complete binding except escape which we'll accept as a special perk
|
||||
if (ie.LogicalButton.Button != "Escape")
|
||||
continue;
|
||||
}
|
||||
else if (lastPress == null) continue;
|
||||
|
||||
ACCEPT:
|
||||
Console.WriteLine("Bind Event: {0} ", ie);
|
||||
|
||||
foreach (var kvp in LastState)
|
||||
if (kvp.Value)
|
||||
{
|
||||
Console.WriteLine($"Unpressing {kvp.Key}");
|
||||
UnpressState[kvp.Key] = true;
|
||||
}
|
||||
Console.WriteLine("Bind Event: {0} ", lastPress);
|
||||
|
||||
InputEvents.Clear();
|
||||
|
||||
return ie.LogicalButton.ToString();
|
||||
return lastPress.LogicalButton.ToString();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -545,16 +559,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
//controls whether modifier keys will be ignored as key press events
|
||||
//this should be used by hotkey binders, but we may want modifier key events
|
||||
//to get triggered in the main form
|
||||
public bool EnableIgnoreModifiers = false;
|
||||
|
||||
//sets a key as unpressed for the binding system
|
||||
public void BindUnpress(System.Windows.Forms.Keys key)
|
||||
{
|
||||
//only validated for Return
|
||||
string keystr = key.ToString();
|
||||
UnpressState[keystr] = true;
|
||||
LastState[keystr] = true;
|
||||
}
|
||||
|
||||
public volatile bool EnableIgnoreModifiers = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,9 +60,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
foreach (var e in events)
|
||||
{
|
||||
foreach (var k in e.PressedKeys)
|
||||
_eventList.Add(new KeyEvent { Key = k, Pressed = true });
|
||||
_eventList.Add(new KeyEvent { Key = KeyboardMapping.Handle(k), Pressed = true });
|
||||
foreach (var k in e.ReleasedKeys)
|
||||
_eventList.Add(new KeyEvent { Key = k, Pressed = false });
|
||||
_eventList.Add(new KeyEvent { Key = KeyboardMapping.Handle(k), Pressed = false });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,416 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using BizHawk.Client.Common;
|
||||
using SlimDX.DirectInput;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
internal static class KeyboardMapping
|
||||
{
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
private const uint MAPVK_VSC_TO_VK_EX = 0x03;
|
||||
|
||||
public static Key Handle(Key key)
|
||||
{
|
||||
if (!Global.Config.HandleAlternateKeyboardLayouts) return key;
|
||||
ScanCode inputScanCode = SlimDXScanCodeMap[(int)key];
|
||||
Keys virtualKey = (Keys)MapVirtualKey((uint)inputScanCode, MAPVK_VSC_TO_VK_EX);
|
||||
ScanCode standardScanCode = GetStandardScanCode(virtualKey);
|
||||
if (standardScanCode == 0)
|
||||
standardScanCode = inputScanCode;
|
||||
return ScanCodeToSlimDXKey[standardScanCode];
|
||||
}
|
||||
|
||||
private static ScanCode GetStandardScanCode(Keys virtualKey)
|
||||
{
|
||||
switch (virtualKey)
|
||||
{
|
||||
case Keys.Escape: return ScanCode.Escape;
|
||||
case Keys.D1: return ScanCode.D1;
|
||||
case Keys.D2: return ScanCode.D2;
|
||||
case Keys.D3: return ScanCode.D3;
|
||||
case Keys.D4: return ScanCode.D4;
|
||||
case Keys.D5: return ScanCode.D5;
|
||||
case Keys.D6: return ScanCode.D6;
|
||||
case Keys.D7: return ScanCode.D7;
|
||||
case Keys.D8: return ScanCode.D8;
|
||||
case Keys.D9: return ScanCode.D9;
|
||||
case Keys.D0: return ScanCode.D0;
|
||||
case Keys.OemMinus: return ScanCode.Minus;
|
||||
case Keys.Oemplus: return ScanCode.Equals;
|
||||
case Keys.Back: return ScanCode.Back;
|
||||
case Keys.Tab: return ScanCode.Tab;
|
||||
case Keys.Q: return ScanCode.Q;
|
||||
case Keys.W: return ScanCode.W;
|
||||
case Keys.E: return ScanCode.E;
|
||||
case Keys.R: return ScanCode.R;
|
||||
case Keys.T: return ScanCode.T;
|
||||
case Keys.Y: return ScanCode.Y;
|
||||
case Keys.U: return ScanCode.U;
|
||||
case Keys.I: return ScanCode.I;
|
||||
case Keys.O: return ScanCode.O;
|
||||
case Keys.P: return ScanCode.P;
|
||||
case Keys.OemOpenBrackets: return ScanCode.LBracket;
|
||||
case Keys.OemCloseBrackets: return ScanCode.RBracket;
|
||||
case Keys.Return: return ScanCode.Return;
|
||||
case Keys.LControlKey: return ScanCode.LControl;
|
||||
case Keys.A: return ScanCode.A;
|
||||
case Keys.S: return ScanCode.S;
|
||||
case Keys.D: return ScanCode.D;
|
||||
case Keys.F: return ScanCode.F;
|
||||
case Keys.G: return ScanCode.G;
|
||||
case Keys.H: return ScanCode.H;
|
||||
case Keys.J: return ScanCode.J;
|
||||
case Keys.K: return ScanCode.K;
|
||||
case Keys.L: return ScanCode.L;
|
||||
case Keys.OemSemicolon: return ScanCode.Semicolon;
|
||||
case Keys.OemQuotes: return ScanCode.Apostrophe;
|
||||
case Keys.Oemtilde: return ScanCode.Grave;
|
||||
case Keys.LShiftKey: return ScanCode.LShift;
|
||||
case Keys.OemPipe: return ScanCode.Backslash;
|
||||
case Keys.Z: return ScanCode.Z;
|
||||
case Keys.X: return ScanCode.X;
|
||||
case Keys.C: return ScanCode.C;
|
||||
case Keys.V: return ScanCode.V;
|
||||
case Keys.B: return ScanCode.B;
|
||||
case Keys.N: return ScanCode.N;
|
||||
case Keys.M: return ScanCode.M;
|
||||
case Keys.Oemcomma: return ScanCode.Comma;
|
||||
case Keys.OemPeriod: return ScanCode.Period;
|
||||
case Keys.OemQuestion: return ScanCode.Slash;
|
||||
case Keys.RShiftKey: return ScanCode.RShift;
|
||||
case Keys.Multiply: return ScanCode.Multiply;
|
||||
case Keys.LMenu: return ScanCode.LMenu;
|
||||
case Keys.Space: return ScanCode.Space;
|
||||
case Keys.Capital: return ScanCode.Capital;
|
||||
case Keys.F1: return ScanCode.F1;
|
||||
case Keys.F2: return ScanCode.F2;
|
||||
case Keys.F3: return ScanCode.F3;
|
||||
case Keys.F4: return ScanCode.F4;
|
||||
case Keys.F5: return ScanCode.F5;
|
||||
case Keys.F6: return ScanCode.F6;
|
||||
case Keys.F7: return ScanCode.F7;
|
||||
case Keys.F8: return ScanCode.F8;
|
||||
case Keys.F9: return ScanCode.F9;
|
||||
case Keys.F10: return ScanCode.F10;
|
||||
case Keys.NumLock: return ScanCode.NumLock;
|
||||
case Keys.Scroll: return ScanCode.Scroll;
|
||||
case Keys.Subtract: return ScanCode.Subtract;
|
||||
case Keys.Add: return ScanCode.Add;
|
||||
case Keys.OemBackslash: return ScanCode.Oem_102;
|
||||
case Keys.F11: return ScanCode.F11;
|
||||
case Keys.F12: return ScanCode.F12;
|
||||
case Keys.F13: return ScanCode.F13;
|
||||
case Keys.F14: return ScanCode.F14;
|
||||
case Keys.F15: return ScanCode.F15;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private enum ScanCode
|
||||
{
|
||||
Escape = 0x01,
|
||||
D1 = 0x02,
|
||||
D2 = 0x03,
|
||||
D3 = 0x04,
|
||||
D4 = 0x05,
|
||||
D5 = 0x06,
|
||||
D6 = 0x07,
|
||||
D7 = 0x08,
|
||||
D8 = 0x09,
|
||||
D9 = 0x0A,
|
||||
D0 = 0x0B,
|
||||
Minus = 0x0C,
|
||||
Equals = 0x0D,
|
||||
Back = 0x0E,
|
||||
Tab = 0x0F,
|
||||
Q = 0x10,
|
||||
W = 0x11,
|
||||
E = 0x12,
|
||||
R = 0x13,
|
||||
T = 0x14,
|
||||
Y = 0x15,
|
||||
U = 0x16,
|
||||
I = 0x17,
|
||||
O = 0x18,
|
||||
P = 0x19,
|
||||
LBracket = 0x1A,
|
||||
RBracket = 0x1B,
|
||||
Return = 0x1C,
|
||||
LControl = 0x1D,
|
||||
A = 0x1E,
|
||||
S = 0x1F,
|
||||
D = 0x20,
|
||||
F = 0x21,
|
||||
G = 0x22,
|
||||
H = 0x23,
|
||||
J = 0x24,
|
||||
K = 0x25,
|
||||
L = 0x26,
|
||||
Semicolon = 0x27,
|
||||
Apostrophe = 0x28,
|
||||
Grave = 0x29,
|
||||
LShift = 0x2A,
|
||||
Backslash = 0x2B,
|
||||
Z = 0x2C,
|
||||
X = 0x2D,
|
||||
C = 0x2E,
|
||||
V = 0x2F,
|
||||
B = 0x30,
|
||||
N = 0x31,
|
||||
M = 0x32,
|
||||
Comma = 0x33,
|
||||
Period = 0x34,
|
||||
Slash = 0x35,
|
||||
RShift = 0x36,
|
||||
Multiply = 0x37,
|
||||
LMenu = 0x38,
|
||||
Space = 0x39,
|
||||
Capital = 0x3A,
|
||||
F1 = 0x3B,
|
||||
F2 = 0x3C,
|
||||
F3 = 0x3D,
|
||||
F4 = 0x3E,
|
||||
F5 = 0x3F,
|
||||
F6 = 0x40,
|
||||
F7 = 0x41,
|
||||
F8 = 0x42,
|
||||
F9 = 0x43,
|
||||
F10 = 0x44,
|
||||
NumLock = 0x45,
|
||||
Scroll = 0x46,
|
||||
NumPad7 = 0x47,
|
||||
NumPad8 = 0x48,
|
||||
NumPad9 = 0x49,
|
||||
Subtract = 0x4A,
|
||||
NumPad4 = 0x4B,
|
||||
NumPad5 = 0x4C,
|
||||
NumPad6 = 0x4D,
|
||||
Add = 0x4E,
|
||||
NumPad1 = 0x4F,
|
||||
NumPad2 = 0x50,
|
||||
NumPad3 = 0x51,
|
||||
NumPad0 = 0x52,
|
||||
Decimal = 0x53,
|
||||
Oem_102 = 0x56,
|
||||
F11 = 0x57,
|
||||
F12 = 0x58,
|
||||
F13 = 0x64,
|
||||
F14 = 0x65,
|
||||
F15 = 0x66,
|
||||
Kana = 0x70,
|
||||
Abnt_C1 = 0x73,
|
||||
Convert = 0x79,
|
||||
NoConvert = 0x7B,
|
||||
Yen = 0x7D,
|
||||
Abnt_C2 = 0x7E,
|
||||
NumPadEquals = 0x8D,
|
||||
PrevTrack = 0x90,
|
||||
AT = 0x91,
|
||||
Colon = 0x92,
|
||||
Underline = 0x93,
|
||||
Kanji = 0x94,
|
||||
Stop = 0x95,
|
||||
AX = 0x96,
|
||||
Unlabeled = 0x97,
|
||||
NextTrack = 0x99,
|
||||
NumPadEnter = 0x9C,
|
||||
RControl = 0x9D,
|
||||
Mute = 0xA0,
|
||||
Calculator = 0xA1,
|
||||
PlayPause = 0xA2,
|
||||
MediaStop = 0xA4,
|
||||
VolumeDown = 0xAE,
|
||||
VolumeUp = 0xB0,
|
||||
WebHome = 0xB2,
|
||||
NumPadComma = 0xB3,
|
||||
Divide = 0xB5,
|
||||
SysRq = 0xB7,
|
||||
RMenu = 0xB8,
|
||||
Pause = 0xC5,
|
||||
Home = 0xC7,
|
||||
Up = 0xC8,
|
||||
Prior = 0xC9,
|
||||
Left = 0xCB,
|
||||
Right = 0xCD,
|
||||
End = 0xCF,
|
||||
Down = 0xD0,
|
||||
Next = 0xD1,
|
||||
Insert = 0xD2,
|
||||
Delete = 0xD3,
|
||||
LWin = 0xDB,
|
||||
RWin = 0xDC,
|
||||
Apps = 0xDD,
|
||||
Power = 0xDE,
|
||||
Sleep = 0xDF,
|
||||
Wake = 0xE3,
|
||||
WebSearch = 0xE5,
|
||||
WebFavorites = 0xE6,
|
||||
WebRefresh = 0xE7,
|
||||
WebStop = 0xE8,
|
||||
WebForward = 0xE9,
|
||||
WebBack = 0xEA,
|
||||
MyComputer = 0xEB,
|
||||
Mail = 0xEC,
|
||||
MediaSelect = 0xED
|
||||
}
|
||||
|
||||
private static readonly ScanCode[] SlimDXScanCodeMap = new ScanCode[]
|
||||
{
|
||||
ScanCode.D0, // 0
|
||||
ScanCode.D1, // 1
|
||||
ScanCode.D2, // 2
|
||||
ScanCode.D3, // 3
|
||||
ScanCode.D4, // 4
|
||||
ScanCode.D5, // 5
|
||||
ScanCode.D6, // 6
|
||||
ScanCode.D7, // 7
|
||||
ScanCode.D8, // 8
|
||||
ScanCode.D9, // 9
|
||||
ScanCode.A, // 10
|
||||
ScanCode.B, // 11
|
||||
ScanCode.C, // 12
|
||||
ScanCode.D, // 13
|
||||
ScanCode.E, // 14
|
||||
ScanCode.F, // 15
|
||||
ScanCode.G, // 16
|
||||
ScanCode.H, // 17
|
||||
ScanCode.I, // 18
|
||||
ScanCode.J, // 19
|
||||
ScanCode.K, // 20
|
||||
ScanCode.L, // 21
|
||||
ScanCode.M, // 22
|
||||
ScanCode.N, // 23
|
||||
ScanCode.O, // 24
|
||||
ScanCode.P, // 25
|
||||
ScanCode.Q, // 26
|
||||
ScanCode.R, // 27
|
||||
ScanCode.S, // 28
|
||||
ScanCode.T, // 29
|
||||
ScanCode.U, // 30
|
||||
ScanCode.V, // 31
|
||||
ScanCode.W, // 32
|
||||
ScanCode.X, // 33
|
||||
ScanCode.Y, // 34
|
||||
ScanCode.Z, // 35
|
||||
ScanCode.Abnt_C1, // 36
|
||||
ScanCode.Abnt_C2, // 37
|
||||
ScanCode.Apostrophe, // 38
|
||||
ScanCode.Apps, // 39
|
||||
ScanCode.AT, // 40
|
||||
ScanCode.AX, // 41
|
||||
ScanCode.Back, // 42
|
||||
ScanCode.Backslash, // 43
|
||||
ScanCode.Calculator, // 44
|
||||
ScanCode.Capital, // 45
|
||||
ScanCode.Colon, // 46
|
||||
ScanCode.Comma, // 47
|
||||
ScanCode.Convert, // 48
|
||||
ScanCode.Delete, // 49
|
||||
ScanCode.Down, // 50
|
||||
ScanCode.End, // 51
|
||||
ScanCode.Equals, // 52
|
||||
ScanCode.Escape, // 53
|
||||
ScanCode.F1, // 54
|
||||
ScanCode.F2, // 55
|
||||
ScanCode.F3, // 56
|
||||
ScanCode.F4, // 57
|
||||
ScanCode.F5, // 58
|
||||
ScanCode.F6, // 59
|
||||
ScanCode.F7, // 60
|
||||
ScanCode.F8, // 61
|
||||
ScanCode.F9, // 62
|
||||
ScanCode.F10, // 63
|
||||
ScanCode.F11, // 64
|
||||
ScanCode.F12, // 65
|
||||
ScanCode.F13, // 66
|
||||
ScanCode.F14, // 67
|
||||
ScanCode.F15, // 68
|
||||
ScanCode.Grave, // 69
|
||||
ScanCode.Home, // 70
|
||||
ScanCode.Insert, // 71
|
||||
ScanCode.Kana, // 72
|
||||
ScanCode.Kanji, // 73
|
||||
ScanCode.LBracket, // 74
|
||||
ScanCode.LControl, // 75
|
||||
ScanCode.Left, // 76
|
||||
ScanCode.LMenu, // 77
|
||||
ScanCode.LShift, // 78
|
||||
ScanCode.LWin, // 79
|
||||
ScanCode.Mail, // 80
|
||||
ScanCode.MediaSelect, // 81
|
||||
ScanCode.MediaStop, // 82
|
||||
ScanCode.Minus, // 83
|
||||
ScanCode.Mute, // 84
|
||||
ScanCode.MyComputer, // 85
|
||||
ScanCode.NextTrack, // 86
|
||||
ScanCode.NoConvert, // 87
|
||||
ScanCode.NumLock, // 88
|
||||
ScanCode.NumPad0, // 89
|
||||
ScanCode.NumPad1, // 90
|
||||
ScanCode.NumPad2, // 91
|
||||
ScanCode.NumPad3, // 92
|
||||
ScanCode.NumPad4, // 93
|
||||
ScanCode.NumPad5, // 94
|
||||
ScanCode.NumPad6, // 95
|
||||
ScanCode.NumPad7, // 96
|
||||
ScanCode.NumPad8, // 97
|
||||
ScanCode.NumPad9, // 98
|
||||
ScanCode.NumPadComma, // 99
|
||||
ScanCode.NumPadEnter, // 100
|
||||
ScanCode.NumPadEquals, // 101
|
||||
ScanCode.Subtract, // 102
|
||||
ScanCode.Decimal, // 103
|
||||
ScanCode.Add, // 104
|
||||
ScanCode.Divide, // 105
|
||||
ScanCode.Multiply, // 106
|
||||
ScanCode.Oem_102, // 107
|
||||
ScanCode.Next, // 108
|
||||
ScanCode.Prior, // 109
|
||||
ScanCode.Pause, // 110
|
||||
ScanCode.Period, // 111
|
||||
ScanCode.PlayPause, // 112
|
||||
ScanCode.Power, // 113
|
||||
ScanCode.PrevTrack, // 114
|
||||
ScanCode.RBracket, // 115
|
||||
ScanCode.RControl, // 116
|
||||
ScanCode.Return, // 117
|
||||
ScanCode.Right, // 118
|
||||
ScanCode.RMenu, // 119
|
||||
ScanCode.RShift, // 120
|
||||
ScanCode.RWin, // 121
|
||||
ScanCode.Scroll, // 122
|
||||
ScanCode.Semicolon, // 123
|
||||
ScanCode.Slash, // 124
|
||||
ScanCode.Sleep, // 125
|
||||
ScanCode.Space, // 126
|
||||
ScanCode.Stop, // 127
|
||||
ScanCode.SysRq, // 128
|
||||
ScanCode.Tab, // 129
|
||||
ScanCode.Underline, // 130
|
||||
ScanCode.Unlabeled, // 131
|
||||
ScanCode.Up, // 132
|
||||
ScanCode.VolumeDown, // 133
|
||||
ScanCode.VolumeUp, // 134
|
||||
ScanCode.Wake, // 135
|
||||
ScanCode.WebBack, // 136
|
||||
ScanCode.WebFavorites, // 137
|
||||
ScanCode.WebForward, // 138
|
||||
ScanCode.WebHome, // 139
|
||||
ScanCode.WebRefresh, // 140
|
||||
ScanCode.WebSearch, // 141
|
||||
ScanCode.WebStop, // 142
|
||||
ScanCode.Yen, // 143
|
||||
0 // 144
|
||||
};
|
||||
|
||||
private static readonly Dictionary<ScanCode, Key> ScanCodeToSlimDXKey =
|
||||
SlimDXScanCodeMap
|
||||
.Select((n, i) => new { Value = n, Index = i })
|
||||
.ToDictionary(n => n.Value, n => (Key)n.Index);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
namespace BizHawk.Client.EmuHawk
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
partial class LogWindow
|
||||
{
|
||||
|
@ -34,7 +36,7 @@
|
|||
this.buttonCopy = new System.Windows.Forms.Button();
|
||||
this.buttonCopyAll = new System.Windows.Forms.Button();
|
||||
this.AddToGameDbBtn = new System.Windows.Forms.Button();
|
||||
this.virtualListView1 = new BizHawk.Client.EmuHawk.VirtualListView();
|
||||
this.virtualListView1 = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -118,23 +120,20 @@
|
|||
//
|
||||
// virtualListView1
|
||||
//
|
||||
this.virtualListView1.BlazingFast = false;
|
||||
this.virtualListView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1});
|
||||
this.virtualListView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.virtualListView1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.virtualListView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
||||
this.virtualListView1.ItemCount = 0;
|
||||
this.virtualListView1.VirtualListSize = 0;
|
||||
this.virtualListView1.Location = new System.Drawing.Point(0, 0);
|
||||
this.virtualListView1.Name = "virtualListView1";
|
||||
this.virtualListView1.SelectAllInProgress = false;
|
||||
this.virtualListView1.selectedItem = -1;
|
||||
this.virtualListView1.Size = new System.Drawing.Size(675, 367);
|
||||
this.virtualListView1.TabIndex = 8;
|
||||
this.virtualListView1.UseCompatibleStateImageBehavior = false;
|
||||
this.virtualListView1.View = System.Windows.Forms.View.Details;
|
||||
this.virtualListView1.VirtualMode = true;
|
||||
this.virtualListView1.QueryItemText += new BizHawk.Client.EmuHawk.QueryItemTextHandler(this.virtualListView1_QueryItemText);
|
||||
this.virtualListView1.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(this.virtualListView1_QueryItemText);
|
||||
this.virtualListView1.ClientSizeChanged += new System.EventHandler(this.virtualListView1_ClientSizeChanged);
|
||||
this.virtualListView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.virtualListView1_KeyDown);
|
||||
//
|
||||
|
@ -163,7 +162,7 @@
|
|||
private System.Windows.Forms.Button btnClose;
|
||||
private System.Windows.Forms.Button btnClear;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private VirtualListView virtualListView1;
|
||||
private System.Windows.Forms.ListView virtualListView1;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||
private System.Windows.Forms.Button buttonCopy;
|
||||
private System.Windows.Forms.Button buttonCopyAll;
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Client.Common;
|
||||
|
@ -40,7 +39,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
var ss = report.Split('\n');
|
||||
foreach (var s in ss)
|
||||
dlg.Lines.Add(s.TrimEnd('\r'));
|
||||
dlg.virtualListView1.ItemCount = ss.Length;
|
||||
dlg.virtualListView1.VirtualListSize = ss.Length;
|
||||
dlg.Text = title;
|
||||
dlg.btnClear.Visible = false;
|
||||
dlg.ShowDialog(parent);
|
||||
|
@ -55,7 +54,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (!string.IsNullOrWhiteSpace(s))
|
||||
{
|
||||
Lines.Add(s.TrimEnd('\r'));
|
||||
virtualListView1.ItemCount++;
|
||||
virtualListView1.VirtualListSize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +62,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void btnClear_Click(object sender, EventArgs e)
|
||||
{
|
||||
Lines.Clear();
|
||||
virtualListView1.ItemCount = 0;
|
||||
virtualListView1.VirtualListSize = 0;
|
||||
virtualListView1.SelectedIndices.Clear();
|
||||
}
|
||||
|
||||
|
@ -99,9 +98,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private void virtualListView1_QueryItemText(int item, int subItem, out string text)
|
||||
private void virtualListView1_QueryItemText(object sender, RetrieveVirtualItemEventArgs e)
|
||||
{
|
||||
text = Lines[item];
|
||||
e.Item = new ListViewItem(Lines[e.ItemIndex]);
|
||||
}
|
||||
|
||||
private void virtualListView1_ClientSizeChanged(object sender, EventArgs e)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,21 +6,18 @@ using System.Collections.Generic;
|
|||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.Atari.A7800Hawk;
|
||||
using BizHawk.Emulation.Cores.Calculators;
|
||||
using BizHawk.Emulation.Cores.ColecoVision;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SubNESHawk;
|
||||
using BizHawk.Emulation.Cores.Nintendo.N64;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES9X;
|
||||
using BizHawk.Emulation.Cores.PCEngine;
|
||||
using BizHawk.Emulation.Cores.Sega.MasterSystem;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
using BizHawk.Client.EmuHawk.CustomControls;
|
||||
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||
using BizHawk.Client.EmuHawk.ToolExtensions;
|
||||
using BizHawk.Emulation.Cores.Computers.AppleII;
|
||||
|
@ -309,6 +306,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void OpenRomMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
AdvancedLoader = AdvancedRomLoaderType.None;
|
||||
OpenRom();
|
||||
}
|
||||
|
||||
|
@ -320,7 +318,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
if (oac.Result == OpenAdvancedChooser.Command.RetroLaunchNoGame)
|
||||
AdvancedLoader = oac.Result;
|
||||
|
||||
if (AdvancedLoader == AdvancedRomLoaderType.LibretroLaunchNoGame)
|
||||
{
|
||||
var argsNoGame = new LoadRomArgs
|
||||
{
|
||||
|
@ -334,15 +334,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
var filter = RomFilter;
|
||||
|
||||
if (oac.Result == OpenAdvancedChooser.Command.RetroLaunchGame)
|
||||
if (AdvancedLoader == AdvancedRomLoaderType.LibretroLaunchGame)
|
||||
{
|
||||
args.OpenAdvanced = new OpenAdvanced_Libretro();
|
||||
filter = oac.SuggestedExtensionFilter;
|
||||
}
|
||||
else if (oac.Result == OpenAdvancedChooser.Command.ClassicLaunchGame)
|
||||
else if (AdvancedLoader == AdvancedRomLoaderType.ClassicLaunchGame)
|
||||
{
|
||||
args.OpenAdvanced = new OpenAdvanced_OpenRom();
|
||||
}
|
||||
else if (AdvancedLoader == AdvancedRomLoaderType.MAMELaunchGame)
|
||||
{
|
||||
args.OpenAdvanced = new OpenAdvanced_MAME();
|
||||
filter = "MAME Arcade ROMs (*.zip)|*.zip";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Automatic Alpha Sanitizer");
|
||||
|
@ -468,8 +473,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
var result = MessageBox.Show(
|
||||
this,
|
||||
"Thanks for using Bizhawk! The emulation core you have selected " +
|
||||
"is currently BETA-status. We appreciate your help in testing Bizhawk. " +
|
||||
"Thanks for using BizHawk! The emulation core you have selected " +
|
||||
"is currently BETA-status. We appreciate your help in testing BizHawk. " +
|
||||
"You can record a movie on this core if you'd like to, but expect to " +
|
||||
"encounter bugs and sync problems. Continue?", "BizHawk", MessageBoxButtons.YesNo);
|
||||
|
||||
|
@ -478,55 +483,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (Emulator is Snes9x)
|
||||
|
||||
if (!EmuHawkUtil.EnsureCoreIsAccurate(Emulator))
|
||||
{
|
||||
var box = new MsgBox(
|
||||
"While the Snes9x core is faster, it is not nearly as accurate as bsnes. \nIt is recommended that you switch to the bsnes core for movie recording\nSwitch to bsnes?",
|
||||
"Accuracy Warning",
|
||||
MessageBoxIcon.Warning);
|
||||
|
||||
box.SetButtons(
|
||||
new[] { "Switch", "Continue" },
|
||||
new[] { DialogResult.Yes, DialogResult.Cancel });
|
||||
|
||||
box.MaximumSize = new Size(475, 350);
|
||||
box.SetMessageToAutoSize();
|
||||
var result = box.ShowDialog();
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
Global.Config.SNES_InSnes9x = false;
|
||||
RebootCore();
|
||||
}
|
||||
else if (result == DialogResult.Cancel)
|
||||
{
|
||||
// Do nothing and allow the user to continue to record the movie
|
||||
}
|
||||
}
|
||||
else if (Emulator is QuickNES) // This is unsustainable :( But mixing the logic together is even worse, this needs to be rethought
|
||||
{
|
||||
var box = new MsgBox(
|
||||
"While the QuickNes core is faster, it is not nearly as accurate as NesHawk. \nIt is recommended that you switch to the NesHawk core for movie recording\nSwitch to NesHawk?",
|
||||
"Accuracy Warning",
|
||||
MessageBoxIcon.Warning);
|
||||
|
||||
box.SetButtons(
|
||||
new[] { "Switch", "Continue" },
|
||||
new[] { DialogResult.Yes, DialogResult.Cancel });
|
||||
|
||||
box.MaximumSize = new Size(475, 350);
|
||||
box.SetMessageToAutoSize();
|
||||
var result = box.ShowDialog();
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
Global.Config.NES_InQuickNES = false;
|
||||
RebootCore();
|
||||
}
|
||||
else if (result == DialogResult.Cancel)
|
||||
{
|
||||
// Do nothing and allow the user to continue to record the movie
|
||||
}
|
||||
// Inaccurate core but allow the user to continue anyway
|
||||
}
|
||||
|
||||
new RecordMovie(Emulator).ShowDialog();
|
||||
|
@ -659,7 +619,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void RecordAVMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
RecordAv(null, null); // force unattended, but allow tradtional setup
|
||||
RecordAv(null, null); // force unattended, but allow traditional setup
|
||||
}
|
||||
|
||||
private void StopAVMenuItem_Click(object sender, EventArgs e)
|
||||
|
@ -1024,9 +984,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void FirmwaresMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (e is RomLoader.RomErrorArgs)
|
||||
if (e is RomLoader.RomErrorArgs args)
|
||||
{
|
||||
var args = (RomLoader.RomErrorArgs)e;
|
||||
var result = new FirmwaresConfig(true, args.RomPath).ShowDialog();
|
||||
args.Retry = result == DialogResult.Retry;
|
||||
}
|
||||
|
@ -1446,7 +1405,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
externalToolToolStripMenuItem.DropDownItems.Add(item);
|
||||
}
|
||||
|
||||
|
||||
if (externalToolToolStripMenuItem.DropDownItems.Count == 0)
|
||||
{
|
||||
externalToolToolStripMenuItem.DropDownItems.Add("None");
|
||||
|
@ -1455,7 +1414,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void ExperimentalToolsSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
AutoHawkMenuItem.Enabled = GlobalWin.Tools.IsAvailable<AutoHawk>();
|
||||
NewHexEditorMenuItem.Enabled = GlobalWin.Tools.IsAvailable<NewHexEditor>();
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1433,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (OSTailoredCode.CurrentOS != OSTailoredCode.DistinctOS.Windows)
|
||||
{
|
||||
// this is apparently needed for weird mono-forms-on-different-thread issues
|
||||
// dont do .Show() within Load<T>() for RamSearch - instead put an instance of it here on MainForm, then show here
|
||||
// don't do .Show() within Load<T>() for RamSearch - instead put an instance of it here on MainForm, then show here
|
||||
// the mono winforms implementation is.... weird and buggy
|
||||
ramSearch.Show();
|
||||
}
|
||||
|
@ -1552,11 +1510,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
new BatchRun().ShowDialog();
|
||||
}
|
||||
|
||||
private void AutoHawkMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GlobalWin.Tools.Load<AutoHawk>();
|
||||
}
|
||||
|
||||
private void NewHexEditorMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GlobalWin.Tools.Load<NewHexEditor>();
|
||||
|
@ -1585,7 +1538,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
VSControlsMenuItem.Enabled =
|
||||
VSSettingsMenuItem.Enabled =
|
||||
Emulator is NES && ((NES)Emulator).IsVS;
|
||||
Emulator is NES nes && nes.IsVS;
|
||||
|
||||
NESSoundChannelsMenuItem.Enabled = GlobalWin.Tools.IsAvailable<NESSoundConfig>();
|
||||
MovieSettingsMenuItem.Enabled = Emulator is NES && !Global.MovieSession.Movie.IsActive;
|
||||
|
@ -1661,7 +1614,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VsSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is NES && ((NES)Emulator).IsVS)
|
||||
if (Emulator is NES nes && nes.IsVS)
|
||||
{
|
||||
new NesVsSettings().ShowHawkDialog();
|
||||
}
|
||||
|
@ -1678,7 +1631,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VsInsertCoinP1MenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is NES && ((NES)Emulator).IsVS)
|
||||
if (Emulator is NES nes && nes.IsVS)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
|
@ -1690,7 +1643,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VsInsertCoinP2MenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is NES && ((NES)Emulator).IsVS)
|
||||
if (Emulator is NES nes && nes.IsVS)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
|
@ -1702,7 +1655,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VsServiceSwitchMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is NES && ((NES)Emulator).IsVS)
|
||||
if (Emulator is NES nes && nes.IsVS)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
|
@ -1842,7 +1795,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
SMSDisplayOverscanMenuItem.Visible =
|
||||
Global.Game.System == "SMS" || Global.Game.System == "SG";
|
||||
|
||||
|
||||
SMSOverclockMenuItem.Visible =
|
||||
SMSForceStereoMenuItem.Visible =
|
||||
SMSdisplayToolStripMenuItem.Visible =
|
||||
|
@ -2013,7 +1966,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
s.ControllerType = "Sports Pad";
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
|
||||
private void SMSControllerKeyboardToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
|
@ -2119,7 +2072,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
GBPrefs.DoGBPrefsDialog(this);
|
||||
}
|
||||
else // sameboy
|
||||
else // SameBoy
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "Gameboy Settings");
|
||||
}
|
||||
|
@ -2149,6 +2102,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
#region GBA
|
||||
|
||||
private void GBACoreSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "Gameboy Advance Settings");
|
||||
}
|
||||
|
||||
private void GbaGpuViewerMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GlobalWin.Tools.Load<GBAGPUView>();
|
||||
|
@ -2168,14 +2126,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void GBACoreSelectionSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
GBAmGBAMenuItem.Checked = Global.Config.GBA_UsemGBA == true;
|
||||
GBAVBANextMenuItem.Checked = Global.Config.GBA_UsemGBA == false;
|
||||
}
|
||||
|
||||
private void GbaWithmGBAMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Global.Config.GBA_UsemGBA ^= true;
|
||||
FlagNeedsReboot();
|
||||
GBAmGBAMenuItem.Checked = Global.Config.GBA_UsemGBA;
|
||||
GBAVBANextMenuItem.Checked = !Global.Config.GBA_UsemGBA;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -2256,6 +2208,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
SNESOptions.DoSettingsDialog(this);
|
||||
}
|
||||
|
||||
private void Snes9xSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "Snes9x Settings");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Coleco
|
||||
|
@ -2317,7 +2274,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
// Do nothing, Reboot is being flagged already if they chaned anything
|
||||
// Do nothing, Reboot is being flagged already if they changed anything
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2443,7 +2400,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
#region Wondersawn
|
||||
|
||||
private void WondersawnSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
private void WonderSwanSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "WonderSwan Settings");
|
||||
}
|
||||
|
@ -2469,9 +2426,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
AppleDisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
if (Emulator is AppleII)
|
||||
if (Emulator is AppleII appleII)
|
||||
{
|
||||
var appleII = (AppleII)Emulator;
|
||||
for (int i = 0; i < appleII.DiskCount; i++)
|
||||
{
|
||||
var menuItem = new ToolStripMenuItem
|
||||
|
@ -2508,9 +2464,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
C64DisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
if (Emulator is C64)
|
||||
if (Emulator is C64 c64)
|
||||
{
|
||||
var c64 = (C64)Emulator;
|
||||
for (int i = 0; i < c64.DiskCount; i++)
|
||||
{
|
||||
var menuItem = new ToolStripMenuItem
|
||||
|
@ -2540,7 +2495,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
#region Intv
|
||||
|
||||
private void IntvSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
private void IntVSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
IntVControllerSettingsMenuItem.Enabled = !Global.MovieSession.Movie.IsActive;
|
||||
}
|
||||
|
@ -2550,260 +2505,271 @@ namespace BizHawk.Client.EmuHawk
|
|||
new IntvControllerSettings().ShowDialog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region ZXSpectrum
|
||||
#region VirtualBoy
|
||||
private void VirtualBoySettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "VirtualBoy Settings");
|
||||
}
|
||||
|
||||
private void zXSpectrumToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region NeoGeoPocket
|
||||
|
||||
|
||||
private void preferencesToolStripMenuItem4_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "ZXSpectrum Settings");
|
||||
}
|
||||
|
||||
private void NeoGeoSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "NeoPop Settings");
|
||||
}
|
||||
|
||||
private void ZXSpectrumControllerConfigurationMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumJoystickSettings().ShowDialog();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void ZXSpectrumCoreEmulationSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumCoreEmulationSettings().ShowDialog();
|
||||
}
|
||||
#region PC-FX
|
||||
|
||||
private void ZXSpectrumNonSyncSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumNonSyncSettings().ShowDialog();
|
||||
}
|
||||
private void PCFXSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
GenericCoreConfig.DoDialog(this, "PC-FX Settings");
|
||||
}
|
||||
|
||||
private void ZXSpectrumAudioSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumAudioSettings().ShowDialog();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void ZXSpectrumPokeMemoryMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumPokeMemory().ShowDialog();
|
||||
}
|
||||
#region ZXSpectrum
|
||||
|
||||
private void ZXSpectrumMediaMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
ZXSpectrumTapesSubMenu.Enabled = ((ZXSpectrum)Emulator)._tapeInfo.Count > 0;
|
||||
ZXSpectrumDisksSubMenu.Enabled = ((ZXSpectrum)Emulator)._diskInfo.Count > 0;
|
||||
}
|
||||
}
|
||||
private void ZXSpectrumControllerConfigurationMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumJoystickSettings().ShowDialog();
|
||||
}
|
||||
|
||||
private void ZXSpectrumTapesSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ZXSpectrumTapesSubMenu.DropDownItems.Clear();
|
||||
private void ZXSpectrumCoreEmulationSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumCoreEmulationSettings().ShowDialog();
|
||||
}
|
||||
|
||||
List<ToolStripMenuItem> items = new List<ToolStripMenuItem>();
|
||||
private void ZXSpectrumNonSyncSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumNonSyncSettings().ShowDialog();
|
||||
}
|
||||
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Emulator;
|
||||
var currSel = speccy._machine.TapeMediaIndex;
|
||||
private void ZXSpectrumAudioSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumAudioSettings().ShowDialog();
|
||||
}
|
||||
|
||||
for (int i = 0; i < speccy._tapeInfo.Count; i++)
|
||||
{
|
||||
string name = speccy._tapeInfo[i].Name;
|
||||
private void ZXSpectrumPokeMemoryMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ZXSpectrumPokeMemory().ShowDialog();
|
||||
}
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = currSel == i
|
||||
};
|
||||
private void ZXSpectrumMediaMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
ZXSpectrumTapesSubMenu.Enabled = ((ZXSpectrum)Emulator)._tapeInfo.Count > 0;
|
||||
ZXSpectrumDisksSubMenu.Enabled = ((ZXSpectrum)Emulator)._diskInfo.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
speccy._machine.TapeMediaIndex = dummy;
|
||||
};
|
||||
|
||||
items.Add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
ZXSpectrumTapesSubMenu.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void ZXSpectrumDisksSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ZXSpectrumDisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
List<ToolStripMenuItem> items = new List<ToolStripMenuItem>();
|
||||
|
||||
if (Emulator is ZXSpectrum)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Emulator;
|
||||
var currSel = speccy._machine.DiskMediaIndex;
|
||||
|
||||
for (int i = 0; i < speccy._diskInfo.Count; i++)
|
||||
{
|
||||
string name = speccy._diskInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = currSel == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
speccy._machine.DiskMediaIndex = dummy;
|
||||
};
|
||||
|
||||
items.Add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
ZXSpectrumDisksSubMenu.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void ZXSpectrumExportSnapshotMenuItemMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
SaveFileDialog zxSnapExpDialog = new SaveFileDialog();
|
||||
zxSnapExpDialog.RestoreDirectory = true;
|
||||
zxSnapExpDialog.Title = "EXPERIMENTAL - Export 3rd party snapshot formats";
|
||||
zxSnapExpDialog.DefaultExt = "szx";
|
||||
zxSnapExpDialog.Filter = "ZX-State files (*.szx)|*.szx";
|
||||
zxSnapExpDialog.SupportMultiDottedExtensions = true;
|
||||
|
||||
try
|
||||
{
|
||||
var res = zxSnapExpDialog.ShowDialog();
|
||||
if (res == DialogResult.OK)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Emulator;
|
||||
var snap = speccy.GetSZXSnapshot();
|
||||
File.WriteAllBytes(zxSnapExpDialog.FileName, snap);
|
||||
//File.WriteAllText(zxSnapExpDialog.FileName, snap);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var ee = ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AmstradCPC
|
||||
|
||||
private void amstradCPCCoreEmulationSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCCoreEmulationSettings().ShowDialog();
|
||||
}
|
||||
|
||||
private void AmstradCPCAudioSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCAudioSettings().ShowDialog();
|
||||
}
|
||||
|
||||
private void AmstradCPCPokeMemoryToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCPokeMemory().ShowDialog();
|
||||
}
|
||||
|
||||
private void AmstradCPCMediaToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is AmstradCPC)
|
||||
{
|
||||
AmstradCPCTapesSubMenu.Enabled = ((AmstradCPC)Emulator)._tapeInfo.Count > 0;
|
||||
AmstradCPCDisksSubMenu.Enabled = ((AmstradCPC)Emulator)._diskInfo.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void AmstradCPCTapesSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
AmstradCPCTapesSubMenu.DropDownItems.Clear();
|
||||
private void ZXSpectrumTapesSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ZXSpectrumTapesSubMenu.DropDownItems.Clear();
|
||||
|
||||
List<ToolStripMenuItem> items = new List<ToolStripMenuItem>();
|
||||
|
||||
if (Emulator is AmstradCPC)
|
||||
{
|
||||
var ams = (AmstradCPC)Emulator;
|
||||
var currSel = ams._machine.TapeMediaIndex;
|
||||
if (Emulator is ZXSpectrum speccy)
|
||||
{
|
||||
var tapeMediaIndex = speccy._machine.TapeMediaIndex;
|
||||
|
||||
for (int i = 0; i < ams._tapeInfo.Count; i++)
|
||||
{
|
||||
string name = ams._tapeInfo[i].Name;
|
||||
for (int i = 0; i < speccy._tapeInfo.Count; i++)
|
||||
{
|
||||
string name = speccy._tapeInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = currSel == i
|
||||
};
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = tapeMediaIndex == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
ams._machine.TapeMediaIndex = dummy;
|
||||
};
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
speccy._machine.TapeMediaIndex = dummy;
|
||||
};
|
||||
|
||||
items.Add(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ZXSpectrumTapesSubMenu.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void ZXSpectrumDisksSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ZXSpectrumDisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
var items = new List<ToolStripMenuItem>();
|
||||
|
||||
if (Emulator is ZXSpectrum speccy)
|
||||
{
|
||||
var diskMediaIndex = speccy._machine.DiskMediaIndex;
|
||||
|
||||
for (int i = 0; i < speccy._diskInfo.Count; i++)
|
||||
{
|
||||
string name = speccy._diskInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = diskMediaIndex == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
speccy._machine.DiskMediaIndex = dummy;
|
||||
};
|
||||
|
||||
items.Add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
ZXSpectrumDisksSubMenu.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void ZXSpectrumExportSnapshotMenuItemMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var zxSnapExpDialog = new SaveFileDialog
|
||||
{
|
||||
RestoreDirectory = true
|
||||
, Title = "EXPERIMENTAL - Export 3rd party snapshot formats"
|
||||
, DefaultExt = "szx"
|
||||
, Filter = "ZX-State files (*.szx)|*.szx"
|
||||
, SupportMultiDottedExtensions = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var res = zxSnapExpDialog.ShowDialog();
|
||||
if (res == DialogResult.OK)
|
||||
{
|
||||
var speccy = (ZXSpectrum)Emulator;
|
||||
var snap = speccy.GetSZXSnapshot();
|
||||
File.WriteAllBytes(zxSnapExpDialog.FileName, snap);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var ee = ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AmstradCPC
|
||||
|
||||
private void amstradCPCCoreEmulationSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCCoreEmulationSettings().ShowDialog();
|
||||
}
|
||||
|
||||
private void AmstradCPCAudioSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCAudioSettings().ShowDialog();
|
||||
}
|
||||
|
||||
private void AmstradCPCPokeMemoryToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCPokeMemory().ShowDialog();
|
||||
}
|
||||
|
||||
private void AmstradCPCMediaToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (Emulator is AmstradCPC)
|
||||
{
|
||||
AmstradCPCTapesSubMenu.Enabled = ((AmstradCPC)Emulator)._tapeInfo.Count > 0;
|
||||
AmstradCPCDisksSubMenu.Enabled = ((AmstradCPC)Emulator)._diskInfo.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void AmstradCPCTapesSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
AmstradCPCTapesSubMenu.DropDownItems.Clear();
|
||||
|
||||
var items = new List<ToolStripMenuItem>();
|
||||
|
||||
if (Emulator is AmstradCPC ams)
|
||||
{
|
||||
var tapeMediaIndex = ams._machine.TapeMediaIndex;
|
||||
|
||||
for (int i = 0; i < ams._tapeInfo.Count; i++)
|
||||
{
|
||||
string name = ams._tapeInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = tapeMediaIndex == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
ams._machine.TapeMediaIndex = dummy;
|
||||
};
|
||||
|
||||
items.Add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
AmstradCPCTapesSubMenu.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void AmstradCPCDisksSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
private void AmstradCPCDisksSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
AmstradCPCDisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
List<ToolStripMenuItem> items = new List<ToolStripMenuItem>();
|
||||
var items = new List<ToolStripMenuItem>();
|
||||
|
||||
if (Emulator is AmstradCPC)
|
||||
{
|
||||
var ams = (AmstradCPC)Emulator;
|
||||
var currSel = ams._machine.DiskMediaIndex;
|
||||
if (Emulator is AmstradCPC ams)
|
||||
{
|
||||
var diskMediaIndex = ams._machine.DiskMediaIndex;
|
||||
|
||||
for (int i = 0; i < ams._diskInfo.Count; i++)
|
||||
{
|
||||
string name = ams._diskInfo[i].Name;
|
||||
for (int i = 0; i < ams._diskInfo.Count; i++)
|
||||
{
|
||||
string name = ams._diskInfo[i].Name;
|
||||
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = currSel == i
|
||||
};
|
||||
var menuItem = new ToolStripMenuItem
|
||||
{
|
||||
Name = $"{i}_{name}",
|
||||
Text = $"{i}: {name}",
|
||||
Checked = diskMediaIndex == i
|
||||
};
|
||||
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
ams._machine.DiskMediaIndex = dummy;
|
||||
};
|
||||
int dummy = i;
|
||||
menuItem.Click += (o, ev) =>
|
||||
{
|
||||
ams._machine.DiskMediaIndex = dummy;
|
||||
};
|
||||
|
||||
items.Add(menuItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AmstradCPCDisksSubMenu.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void AmstradCPCNonSyncSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCNonSyncSettings().ShowDialog();
|
||||
}
|
||||
private void AmstradCPCNonSyncSettingsToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AmstradCPCNonSyncSettings().ShowDialog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Help
|
||||
#region Help
|
||||
|
||||
private void HelpSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
private void HelpSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
FeaturesMenuItem.Visible = VersionInfo.DeveloperBuild;
|
||||
}
|
||||
|
@ -2853,9 +2819,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
showMenuVisible = true; // need to always be able to restore this as an emergency measure
|
||||
}
|
||||
|
||||
if (argParser._chromeless)
|
||||
if (_argParser._chromeless)
|
||||
{
|
||||
showMenuVisible = true; // I decided this was always possible in chromeless mode, we'll see what they think
|
||||
showMenuVisible = true; // I decided this was always possible in chrome-less mode, we'll see what they think
|
||||
}
|
||||
|
||||
ShowMenuContextMenuItem.Visible =
|
||||
|
@ -3297,7 +3263,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
try
|
||||
{
|
||||
FormDragDrop_Internal(sender, e);
|
||||
_FormDragDrop_internal(sender, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -3305,113 +3271,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private void FormDragDrop_Internal(object sender, DragEventArgs e)
|
||||
{
|
||||
_FormDragDrop_internal(sender, e);
|
||||
/*
|
||||
var filePaths = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
var isLua = false;
|
||||
foreach (var path in filePaths)
|
||||
{
|
||||
var extension = Path.GetExtension(path);
|
||||
if (extension != null && extension.ToUpper() == ".LUA")
|
||||
{
|
||||
OpenLuaConsole();
|
||||
if (GlobalWin.Tools.Has<LuaConsole>())
|
||||
{
|
||||
GlobalWin.Tools.LuaConsole.LoadLuaFile(path);
|
||||
}
|
||||
isLua = true;
|
||||
}
|
||||
}
|
||||
if (isLua)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(filePaths[0]) ?? "";
|
||||
if (ext.ToUpper() == ".LUASES")
|
||||
{
|
||||
OpenLuaConsole();
|
||||
if (GlobalWin.Tools.Has<LuaConsole>())
|
||||
{
|
||||
GlobalWin.Tools.LuaConsole.LoadLuaSession(filePaths[0]);
|
||||
}
|
||||
}
|
||||
else if (MovieService.IsValidMovieExtension(ext))
|
||||
{
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
OpenRom();
|
||||
}
|
||||
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartNewMovie(MovieService.Get(filePaths[0]), false);
|
||||
}
|
||||
else if (ext.ToUpper() == ".STATE")
|
||||
{
|
||||
LoadState(filePaths[0], Path.GetFileName(filePaths[0]));
|
||||
}
|
||||
else if (ext.ToUpper() == ".CHT")
|
||||
{
|
||||
Global.CheatList.Load(filePaths[0], false);
|
||||
GlobalWin.Tools.Load<Cheats>();
|
||||
}
|
||||
else if (ext.ToUpper() == ".WCH")
|
||||
{
|
||||
GlobalWin.Tools.LoadRamWatch(true);
|
||||
(GlobalWin.Tools.Get<RamWatch>() as RamWatch).LoadWatchFile(new FileInfo(filePaths[0]), false);
|
||||
}
|
||||
|
||||
else if (ext.ToUpper() == ".CDL" && Emulator is PCEngine)
|
||||
{
|
||||
GlobalWin.Tools.Load<CDL>();
|
||||
(GlobalWin.Tools.Get<CDL>() as CDL).LoadFile(filePaths[0]);
|
||||
}
|
||||
|
||||
else if (MovieImport.IsValidMovieExtension(Path.GetExtension(filePaths[0])))
|
||||
{
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
OpenRom();
|
||||
}
|
||||
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// tries to open a legacy movie format by importing it
|
||||
string errorMsg;
|
||||
string warningMsg;
|
||||
var movie = MovieImport.ImportFile(filePaths[0], out errorMsg, out warningMsg);
|
||||
if (!string.IsNullOrEmpty(errorMsg))
|
||||
{
|
||||
MessageBox.Show(errorMsg, "Conversion error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fix movie extension to something palatable for these purposes.
|
||||
// for instance, something which doesnt clobber movies you already may have had.
|
||||
// i'm evenly torn between this, and a file in %TEMP%, but since we dont really have a way to clean up this tempfile, i choose this:
|
||||
StartNewMovie(movie, false);
|
||||
}
|
||||
|
||||
GlobalWin.OSD.AddMessage(warningMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
var args = new LoadRomArgs();
|
||||
args.OpenAdvanced = new OpenAdvanced_OpenRom { Path = filePaths[0] };
|
||||
LoadRom(filePaths[0], args);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -347,7 +347,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
type = " (on)";
|
||||
}
|
||||
|
||||
Global.CheatList.ToList().ForEach(x => x.Toggle());
|
||||
foreach (var x in Global.CheatList)
|
||||
{
|
||||
x.Toggle();
|
||||
}
|
||||
GlobalWin.OSD.AddMessage($"Cheats toggled{type}");
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,147 +28,184 @@
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.btnLibretroLaunchNoGame = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.txtLibretroCore = new System.Windows.Forms.TextBox();
|
||||
this.btnLibretroLaunchGame = new System.Windows.Forms.Button();
|
||||
this.btnSetLibretroCore = new System.Windows.Forms.Button();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.btnClassicLaunchGame = new System.Windows.Forms.Button();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Location = new System.Drawing.Point(6, 25);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(250, 29);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Load a rom with the classic BizHawk autodetection method. But why not just use Op" +
|
||||
"en Rom?";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(6, 26);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "Current Core:";
|
||||
//
|
||||
// btnLibretroLaunchNoGame
|
||||
//
|
||||
this.btnLibretroLaunchNoGame.Location = new System.Drawing.Point(217, 50);
|
||||
this.btnLibretroLaunchNoGame.Name = "btnLibretroLaunchNoGame";
|
||||
this.btnLibretroLaunchNoGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchNoGame.TabIndex = 1;
|
||||
this.btnLibretroLaunchNoGame.Text = "Launch No Game";
|
||||
this.btnLibretroLaunchNoGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchNoGame.Click += new System.EventHandler(this.btnLibretroLaunchNoGame_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(370, 176);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.txtLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchGame);
|
||||
this.groupBox2.Controls.Add(this.btnSetLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchNoGame);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(433, 81);
|
||||
this.groupBox2.TabIndex = 3;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Libretro";
|
||||
//
|
||||
// txtLibretroCore
|
||||
//
|
||||
this.txtLibretroCore.AllowDrop = true;
|
||||
this.txtLibretroCore.Location = new System.Drawing.Point(81, 23);
|
||||
this.txtLibretroCore.Name = "txtLibretroCore";
|
||||
this.txtLibretroCore.ReadOnly = true;
|
||||
this.txtLibretroCore.Size = new System.Drawing.Size(314, 20);
|
||||
this.txtLibretroCore.TabIndex = 6;
|
||||
this.txtLibretroCore.DragDrop += new System.Windows.Forms.DragEventHandler(this.txtLibretroCore_DragDrop);
|
||||
this.txtLibretroCore.DragEnter += new System.Windows.Forms.DragEventHandler(this.txtLibretroCore_DragEnter);
|
||||
//
|
||||
// btnLibretroLaunchGame
|
||||
//
|
||||
this.btnLibretroLaunchGame.Location = new System.Drawing.Point(325, 50);
|
||||
this.btnLibretroLaunchGame.Name = "btnLibretroLaunchGame";
|
||||
this.btnLibretroLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchGame.TabIndex = 5;
|
||||
this.btnLibretroLaunchGame.Text = "Launch Game";
|
||||
this.btnLibretroLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchGame.Click += new System.EventHandler(this.btnLibretroLaunchGame_Click);
|
||||
//
|
||||
// btnSetLibretroCore
|
||||
//
|
||||
this.btnSetLibretroCore.AutoSize = true;
|
||||
this.btnSetLibretroCore.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnSetLibretroCore.Location = new System.Drawing.Point(401, 21);
|
||||
this.btnSetLibretroCore.Name = "btnSetLibretroCore";
|
||||
this.btnSetLibretroCore.Size = new System.Drawing.Size(26, 23);
|
||||
this.btnSetLibretroCore.TabIndex = 4;
|
||||
this.btnSetLibretroCore.Text = "...";
|
||||
this.btnSetLibretroCore.UseVisualStyleBackColor = true;
|
||||
this.btnSetLibretroCore.Click += new System.EventHandler(this.btnSetLibretroCore_Click);
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.btnClassicLaunchGame);
|
||||
this.groupBox3.Controls.Add(this.label3);
|
||||
this.groupBox3.Location = new System.Drawing.Point(12, 99);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(277, 100);
|
||||
this.groupBox3.TabIndex = 6;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "BizHawk Classic";
|
||||
//
|
||||
// btnClassicLaunchGame
|
||||
//
|
||||
this.btnClassicLaunchGame.Location = new System.Drawing.Point(169, 71);
|
||||
this.btnClassicLaunchGame.Name = "btnClassicLaunchGame";
|
||||
this.btnClassicLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnClassicLaunchGame.TabIndex = 6;
|
||||
this.btnClassicLaunchGame.Text = "Launch Game";
|
||||
this.btnClassicLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnClassicLaunchGame.Click += new System.EventHandler(this.btnClassicLaunchGame_Click);
|
||||
//
|
||||
// OpenAdvancedChooser
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(457, 208);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "OpenAdvancedChooser";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Open Advanced";
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.btnLibretroLaunchNoGame = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.txtLibretroCore = new System.Windows.Forms.TextBox();
|
||||
this.btnLibretroLaunchGame = new System.Windows.Forms.Button();
|
||||
this.btnSetLibretroCore = new System.Windows.Forms.Button();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.btnClassicLaunchGame = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.btnMAMELaunchGame = new System.Windows.Forms.Button();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Location = new System.Drawing.Point(6, 25);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(198, 45);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Load a ROM with the classic BizHawk autodetection method. But why not just use Op" +
|
||||
"en Rom?";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(6, 26);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "Current Core:";
|
||||
//
|
||||
// btnLibretroLaunchNoGame
|
||||
//
|
||||
this.btnLibretroLaunchNoGame.Location = new System.Drawing.Point(217, 50);
|
||||
this.btnLibretroLaunchNoGame.Name = "btnLibretroLaunchNoGame";
|
||||
this.btnLibretroLaunchNoGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchNoGame.TabIndex = 1;
|
||||
this.btnLibretroLaunchNoGame.Text = "Launch No Game";
|
||||
this.btnLibretroLaunchNoGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchNoGame.Click += new System.EventHandler(this.btnLibretroLaunchNoGame_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(370, 221);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.txtLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchGame);
|
||||
this.groupBox2.Controls.Add(this.btnSetLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchNoGame);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(433, 81);
|
||||
this.groupBox2.TabIndex = 3;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Libretro";
|
||||
//
|
||||
// txtLibretroCore
|
||||
//
|
||||
this.txtLibretroCore.AllowDrop = true;
|
||||
this.txtLibretroCore.Location = new System.Drawing.Point(81, 23);
|
||||
this.txtLibretroCore.Name = "txtLibretroCore";
|
||||
this.txtLibretroCore.ReadOnly = true;
|
||||
this.txtLibretroCore.Size = new System.Drawing.Size(314, 20);
|
||||
this.txtLibretroCore.TabIndex = 6;
|
||||
this.txtLibretroCore.DragDrop += new System.Windows.Forms.DragEventHandler(this.txtLibretroCore_DragDrop);
|
||||
this.txtLibretroCore.DragEnter += new System.Windows.Forms.DragEventHandler(this.txtLibretroCore_DragEnter);
|
||||
//
|
||||
// btnLibretroLaunchGame
|
||||
//
|
||||
this.btnLibretroLaunchGame.Location = new System.Drawing.Point(325, 50);
|
||||
this.btnLibretroLaunchGame.Name = "btnLibretroLaunchGame";
|
||||
this.btnLibretroLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchGame.TabIndex = 5;
|
||||
this.btnLibretroLaunchGame.Text = "Launch Game";
|
||||
this.btnLibretroLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchGame.Click += new System.EventHandler(this.btnLibretroLaunchGame_Click);
|
||||
//
|
||||
// btnSetLibretroCore
|
||||
//
|
||||
this.btnSetLibretroCore.AutoSize = true;
|
||||
this.btnSetLibretroCore.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnSetLibretroCore.Location = new System.Drawing.Point(401, 21);
|
||||
this.btnSetLibretroCore.Name = "btnSetLibretroCore";
|
||||
this.btnSetLibretroCore.Size = new System.Drawing.Size(26, 23);
|
||||
this.btnSetLibretroCore.TabIndex = 4;
|
||||
this.btnSetLibretroCore.Text = "...";
|
||||
this.btnSetLibretroCore.UseVisualStyleBackColor = true;
|
||||
this.btnSetLibretroCore.Click += new System.EventHandler(this.btnSetLibretroCore_Click);
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.btnClassicLaunchGame);
|
||||
this.groupBox3.Controls.Add(this.label3);
|
||||
this.groupBox3.Location = new System.Drawing.Point(235, 99);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(210, 100);
|
||||
this.groupBox3.TabIndex = 6;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "BizHawk Classic";
|
||||
//
|
||||
// btnClassicLaunchGame
|
||||
//
|
||||
this.btnClassicLaunchGame.Location = new System.Drawing.Point(102, 71);
|
||||
this.btnClassicLaunchGame.Name = "btnClassicLaunchGame";
|
||||
this.btnClassicLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnClassicLaunchGame.TabIndex = 6;
|
||||
this.btnClassicLaunchGame.Text = "Launch Game";
|
||||
this.btnClassicLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnClassicLaunchGame.Click += new System.EventHandler(this.btnClassicLaunchGame_Click);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.label1);
|
||||
this.groupBox1.Controls.Add(this.btnMAMELaunchGame);
|
||||
this.groupBox1.Location = new System.Drawing.Point(13, 99);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(216, 100);
|
||||
this.groupBox1.TabIndex = 7;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "MAME Arcade";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(6, 25);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(204, 42);
|
||||
this.label1.TabIndex = 1;
|
||||
this.label1.Text = "Load .zip archive as MAME Arcade ROM (do not unzip)";
|
||||
this.label1.Click += new System.EventHandler(this.btnMAMELaunchGame_Click);
|
||||
//
|
||||
// btnMAMELaunchGame
|
||||
//
|
||||
this.btnMAMELaunchGame.Location = new System.Drawing.Point(108, 71);
|
||||
this.btnMAMELaunchGame.Name = "btnMAMELaunchGame";
|
||||
this.btnMAMELaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnMAMELaunchGame.TabIndex = 0;
|
||||
this.btnMAMELaunchGame.Text = "Launch Game";
|
||||
this.btnMAMELaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnMAMELaunchGame.Click += new System.EventHandler(this.btnMAMELaunchGame_Click);
|
||||
//
|
||||
// OpenAdvancedChooser
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(457, 256);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "OpenAdvancedChooser";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Open Advanced";
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -182,6 +219,9 @@
|
|||
private System.Windows.Forms.TextBox txtLibretroCore;
|
||||
private System.Windows.Forms.Button btnLibretroLaunchGame;
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.Button btnClassicLaunchGame;
|
||||
private System.Windows.Forms.Button btnClassicLaunchGame;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button btnMAMELaunchGame;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,8 @@ using System.Drawing;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores;
|
||||
using BizHawk.Emulation.Cores.Libretro;
|
||||
using BizHawk.Client.Common;
|
||||
|
@ -20,13 +21,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
MainForm mainForm;
|
||||
|
||||
public enum Command
|
||||
{
|
||||
RetroLaunchNoGame, RetroLaunchGame,
|
||||
ClassicLaunchGame
|
||||
}
|
||||
|
||||
public Command Result;
|
||||
public AdvancedRomLoaderType Result;
|
||||
public string SuggestedExtensionFilter;
|
||||
|
||||
public OpenAdvancedChooser(MainForm mainForm)
|
||||
|
@ -131,21 +126,28 @@ namespace BizHawk.Client.EmuHawk
|
|||
filter = MainForm.FormatFilter(args.ToArray());
|
||||
SuggestedExtensionFilter = filter;
|
||||
|
||||
Result = Command.RetroLaunchGame;
|
||||
Result = AdvancedRomLoaderType.LibretroLaunchGame;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnMAMELaunchGame_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = AdvancedRomLoaderType.MAMELaunchGame;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnClassicLaunchGame_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = Command.ClassicLaunchGame;
|
||||
Result = AdvancedRomLoaderType.ClassicLaunchGame;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnLibretroLaunchNoGame_Click(object sender, EventArgs e)
|
||||
{
|
||||
Result = Command.RetroLaunchNoGame;
|
||||
Result = AdvancedRomLoaderType.LibretroLaunchNoGame;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
@ -170,6 +172,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
var filePaths = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
Global.Config.LibretroCore = filePaths[0];
|
||||
RefreshLibretroCore(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,36 +30,33 @@ namespace BizHawk.Client.EmuHawk
|
|||
//try loading libraries we know we'll need
|
||||
//something in the winforms, etc. code below will cause .net to popup a missing msvcr100.dll in case that one's missing
|
||||
//but oddly it lets us proceed and we'll then catch it here
|
||||
var d3dx9 = libLoader.LoadPlatformSpecific("d3dx9_43.dll");
|
||||
var vc2015 = libLoader.LoadPlatformSpecific("vcruntime140.dll");
|
||||
var vc2012 = libLoader.LoadPlatformSpecific("msvcr120.dll"); //TODO - check version?
|
||||
var vc2010 = libLoader.LoadPlatformSpecific("msvcr100.dll"); //TODO - check version?
|
||||
var vc2010p = libLoader.LoadPlatformSpecific("msvcp100.dll");
|
||||
var fail = vc2015 == IntPtr.Zero || vc2010 == IntPtr.Zero || vc2012 == IntPtr.Zero || vc2010p == IntPtr.Zero;
|
||||
var warn = d3dx9 == IntPtr.Zero;
|
||||
if (fail || warn)
|
||||
var d3dx9 = libLoader.LoadOrNull("d3dx9_43.dll");
|
||||
var vc2015 = libLoader.LoadOrNull("vcruntime140.dll");
|
||||
var vc2012 = libLoader.LoadOrNull("msvcr120.dll"); //TODO - check version?
|
||||
var vc2010 = libLoader.LoadOrNull("msvcr100.dll"); //TODO - check version?
|
||||
var vc2010p = libLoader.LoadOrNull("msvcp100.dll");
|
||||
var reqPresent = vc2015.HasValue && vc2010.HasValue && vc2012.HasValue && vc2010p.HasValue;
|
||||
var optPresent = d3dx9.HasValue;
|
||||
if (!reqPresent || !optPresent)
|
||||
{
|
||||
var alertLines = new[]
|
||||
{
|
||||
"[ OK ] .NET CLR (You wouldn't even get here without it)",
|
||||
$"[{(d3dx9 == IntPtr.Zero ? "WARN" : " OK ")}] Direct3d 9",
|
||||
$"[{(vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2010 SP1 Runtime",
|
||||
$"[{(vc2012 == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2012 Runtime",
|
||||
$"[{(vc2015 == IntPtr.Zero ? "FAIL" : " OK ")}] Visual C++ 2015 Runtime"
|
||||
$"[{(d3dx9.HasValue ? " OK " : "WARN")}] Direct3d 9",
|
||||
$"[{(vc2010.HasValue && vc2010p.HasValue ? " OK " : "FAIL")}] Visual C++ 2010 SP1 Runtime",
|
||||
$"[{(vc2012.HasValue ? " OK " : "FAIL")}] Visual C++ 2012 Runtime",
|
||||
$"[{(vc2015.HasValue ? " OK " : "FAIL")}] Visual C++ 2015 Runtime"
|
||||
};
|
||||
var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert(!fail)
|
||||
var box = new CustomControls.PrereqsAlert(reqPresent)
|
||||
{
|
||||
textBox1 = { Text = string.Concat("\n", alertLines) }
|
||||
textBox1 = { Text = string.Join(Environment.NewLine, alertLines) }
|
||||
};
|
||||
box.ShowDialog();
|
||||
if (fail) System.Diagnostics.Process.GetCurrentProcess().Kill();
|
||||
if (!reqPresent) Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
libLoader.FreePlatformSpecific(d3dx9);
|
||||
libLoader.FreePlatformSpecific(vc2015);
|
||||
libLoader.FreePlatformSpecific(vc2012);
|
||||
libLoader.FreePlatformSpecific(vc2010);
|
||||
libLoader.FreePlatformSpecific(vc2010p);
|
||||
foreach (var p in new[] { d3dx9, vc2015, vc2012, vc2010, vc2010p })
|
||||
if (p.HasValue) libLoader.FreeByPtr(p.Value);
|
||||
|
||||
// this will look in subdirectory "dll" to load pinvoked stuff
|
||||
var dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
|
||||
|
@ -115,7 +112,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
BizHawk.Common.TempFileManager.Start();
|
||||
TempFileManager.Start();
|
||||
|
||||
#if true // switch to if false for system-agnostic glory!
|
||||
switch (EXE_PROJECT.OSTailoredCode.CurrentOS)
|
||||
|
@ -147,8 +144,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
Global.Config.ResolveDefaults();
|
||||
|
||||
BizHawk.Client.Common.StringLogUtil.DefaultToDisk = Global.Config.MoviesOnDisk;
|
||||
BizHawk.Client.Common.StringLogUtil.DefaultToAWE = Global.Config.MoviesInAWE;
|
||||
StringLogUtil.DefaultToDisk = Global.Config.MoviesOnDisk;
|
||||
StringLogUtil.DefaultToAWE = Global.Config.MoviesInAWE;
|
||||
|
||||
// super hacky! this needs to be done first. still not worth the trouble to make this system fully proper
|
||||
if (Array.Exists(args, arg => arg.StartsWith("--gdi", StringComparison.InvariantCultureIgnoreCase)))
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Client.EmuHawk.Properties {
|
|||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
@ -120,6 +120,16 @@ namespace BizHawk.Client.EmuHawk.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap ArcadeController {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("ArcadeController", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -870,6 +880,16 @@ namespace BizHawk.Client.EmuHawk.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap mame {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("mame", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -1479,6 +1499,16 @@ namespace BizHawk.Client.EmuHawk.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap StopButton {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("StopButton", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
|
|
@ -1563,4 +1563,13 @@
|
|||
<data name="MoveTop" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\MoveTop.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="StopButton" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\StopButton.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="ArcadeController" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\ControllerImages\ArcadeController.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="mame" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\mame.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
|
@ -9,6 +9,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
void ApplyVolumeSettings(double volume);
|
||||
int MaxSamplesDeficit { get; }
|
||||
int CalculateSamplesNeeded();
|
||||
void WriteSamples(short[] samples, int sampleCount);
|
||||
void WriteSamples(short[] samples, int sampleOffset, int sampleCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public static IEnumerable<string> GetDeviceNames()
|
||||
{
|
||||
return DirectSound.GetDevices().Select(d => d.Description).ToList();
|
||||
return DirectSound.GetDevices().Select(d => d.Description);
|
||||
}
|
||||
|
||||
private int BufferSizeSamples { get; set; }
|
||||
|
@ -152,12 +152,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
return (end - start + size) % size;
|
||||
}
|
||||
|
||||
public void WriteSamples(short[] samples, int sampleCount)
|
||||
public void WriteSamples(short[] samples, int sampleOffset, int sampleCount)
|
||||
{
|
||||
if (sampleCount == 0) return;
|
||||
int total = sampleCount * Sound.ChannelCount;
|
||||
if (total > samples.Length) { total = samples.Length; }
|
||||
_deviceBuffer.Write(samples, 0, total, _actualWriteOffsetBytes, LockFlags.None);
|
||||
_deviceBuffer.Write(samples, sampleOffset * Sound.ChannelCount, sampleCount * Sound.ChannelCount, _actualWriteOffsetBytes, LockFlags.None);
|
||||
_actualWriteOffsetBytes = (_actualWriteOffsetBytes + (sampleCount * Sound.BlockAlign)) % BufferSizeBytes;
|
||||
_filledBufferSizeBytes += sampleCount * Sound.BlockAlign;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
return samplesNeeded;
|
||||
}
|
||||
|
||||
public void WriteSamples(short[] samples, int sampleCount)
|
||||
public void WriteSamples(short[] samples, int sampleOffset, int sampleCount)
|
||||
{
|
||||
if (sampleCount == 0) return;
|
||||
_remainingSamples += sampleCount;
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private int _sourceID;
|
||||
private BufferPool _bufferPool;
|
||||
private int _currentSamplesQueued;
|
||||
private short[] _tempSampleBuffer;
|
||||
|
||||
public OpenALSoundOutput(Sound sound)
|
||||
{
|
||||
|
@ -94,11 +95,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
return samplesNeeded;
|
||||
}
|
||||
|
||||
public void WriteSamples(short[] samples, int sampleCount)
|
||||
public void WriteSamples(short[] samples, int sampleOffset, int sampleCount)
|
||||
{
|
||||
if (sampleCount == 0) return;
|
||||
UnqueueProcessedBuffers();
|
||||
int byteCount = sampleCount * Sound.BlockAlign;
|
||||
if (sampleOffset != 0)
|
||||
{
|
||||
AllocateTempSampleBuffer(sampleCount);
|
||||
Buffer.BlockCopy(samples, sampleOffset * Sound.BlockAlign, _tempSampleBuffer, 0, byteCount);
|
||||
samples = _tempSampleBuffer;
|
||||
}
|
||||
var buffer = _bufferPool.Obtain(byteCount);
|
||||
AL.BufferData(buffer.BufferID, ALFormat.Stereo16, samples, byteCount, Sound.SampleRate);
|
||||
AL.SourceQueueBuffer(_sourceID, buffer.BufferID);
|
||||
|
@ -127,6 +134,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
return value;
|
||||
}
|
||||
|
||||
private void AllocateTempSampleBuffer(int sampleCount)
|
||||
{
|
||||
int length = sampleCount * Sound.ChannelCount;
|
||||
if (_tempSampleBuffer == null || _tempSampleBuffer.Length < length)
|
||||
{
|
||||
_tempSampleBuffer = new short[length];
|
||||
}
|
||||
}
|
||||
|
||||
private class BufferPool : IDisposable
|
||||
{
|
||||
private Stack<BufferPoolItem> _availableItems = new Stack<BufferPoolItem>();
|
||||
|
|
|
@ -49,7 +49,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
using (XAudio2 device = new XAudio2())
|
||||
{
|
||||
return Enumerable.Range(0, device.DeviceCount).Select(n => device.GetDeviceDetails(n).DisplayName).ToList();
|
||||
return Enumerable.Range(0, device.DeviceCount)
|
||||
.Select(n => device.GetDeviceDetails(n).DisplayName)
|
||||
.ToList(); // enumerate before local var device is disposed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,14 +112,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
return samplesNeeded;
|
||||
}
|
||||
|
||||
public void WriteSamples(short[] samples, int sampleCount)
|
||||
public void WriteSamples(short[] samples, int sampleOffset, int sampleCount)
|
||||
{
|
||||
if (sampleCount == 0) return;
|
||||
_bufferPool.Release(_sourceVoice.State.BuffersQueued);
|
||||
int byteCount = sampleCount * Sound.BlockAlign;
|
||||
var buffer = _bufferPool.Obtain(byteCount);
|
||||
if (byteCount > (samples.Length * 2)) { byteCount = samples.Length * 2; }
|
||||
Buffer.BlockCopy(samples, 0, buffer.Bytes, 0, byteCount);
|
||||
Buffer.BlockCopy(samples, sampleOffset * Sound.BlockAlign, buffer.Bytes, 0, byteCount);
|
||||
_sourceVoice.SubmitSourceBuffer(new AudioBuffer
|
||||
{
|
||||
AudioBytes = byteCount,
|
||||
|
|
|
@ -16,8 +16,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
public const int BlockAlign = BytesPerSample * ChannelCount;
|
||||
|
||||
private bool _disposed;
|
||||
private bool _unjamSoundThrottle;
|
||||
|
||||
private readonly ISoundOutput _outputDevice;
|
||||
private readonly SoundOutputProvider _outputProvider = new SoundOutputProvider(); // Buffer for Sync sources
|
||||
private readonly BufferedAsync _bufferedAsync = new BufferedAsync(); // Buffer for Async sources
|
||||
|
@ -118,9 +116,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
// Fill device buffer with silence but leave enough room for one frame
|
||||
int samplesPerFrame = (int)Math.Round(SampleRate / (double)Global.Emulator.VsyncRate());
|
||||
int silenceSamples = Math.Max(samplesNeeded - samplesPerFrame, 0);
|
||||
_outputDevice.WriteSamples(new short[silenceSamples * 2], silenceSamples);
|
||||
_outputDevice.WriteSamples(new short[silenceSamples * 2], 0, silenceSamples);
|
||||
samplesNeeded -= silenceSamples;
|
||||
_unjamSoundThrottle = isUnderrun;
|
||||
|
||||
if (isUnderrun)
|
||||
{
|
||||
|
@ -141,14 +138,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (atten > 1) atten = 1;
|
||||
_outputDevice.ApplyVolumeSettings(atten);
|
||||
|
||||
short[] samples;
|
||||
int samplesNeeded = _outputDevice.CalculateSamplesNeeded();
|
||||
int samplesProvided;
|
||||
short[] samples;
|
||||
int sampleOffset;
|
||||
int sampleCount;
|
||||
|
||||
if (atten == 0)
|
||||
{
|
||||
samples = new short[samplesNeeded * ChannelCount];
|
||||
samplesProvided = samplesNeeded;
|
||||
sampleOffset = 0;
|
||||
sampleCount = samplesNeeded;
|
||||
|
||||
_bufferedProvider.DiscardSamples();
|
||||
}
|
||||
|
@ -156,25 +155,34 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Global.Config.SoundThrottle)
|
||||
{
|
||||
_outputProvider.BaseSoundProvider.GetSamplesSync(out samples, out samplesProvided);
|
||||
_outputProvider.BaseSoundProvider.GetSamplesSync(out samples, out sampleCount);
|
||||
sampleOffset = 0;
|
||||
|
||||
if (Global.DisableSecondaryThrottling && samplesProvided > samplesNeeded)
|
||||
if (Global.DisableSecondaryThrottling && sampleCount > samplesNeeded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (samplesProvided > samplesNeeded)
|
||||
int samplesPerMs = SampleRate / 1000;
|
||||
int outputThresholdMs = 20;
|
||||
while (sampleCount > samplesNeeded)
|
||||
{
|
||||
Thread.Sleep((samplesProvided - samplesNeeded) / (SampleRate / 1000)); // Let the audio clock control sleep time
|
||||
samplesNeeded = _outputDevice.CalculateSamplesNeeded();
|
||||
if (_unjamSoundThrottle)
|
||||
if (samplesNeeded >= outputThresholdMs * samplesPerMs)
|
||||
{
|
||||
//may be garbage, but what can we do?
|
||||
samplesProvided = samplesNeeded;
|
||||
break;
|
||||
// If we were given a large enough number of samples (e.g. larger than the device's
|
||||
// buffer), the device will never need that many samples no matter how long we
|
||||
// wait, so we have to start splitting up the output
|
||||
_outputDevice.WriteSamples(samples, sampleOffset, samplesNeeded);
|
||||
sampleOffset += samplesNeeded;
|
||||
sampleCount -= samplesNeeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the audio clock control sleep time
|
||||
Thread.Sleep(Math.Min((sampleCount - samplesNeeded) / samplesPerMs, outputThresholdMs));
|
||||
}
|
||||
samplesNeeded = _outputDevice.CalculateSamplesNeeded();
|
||||
}
|
||||
_unjamSoundThrottle = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -182,7 +190,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
_outputProvider.OnVolatility();
|
||||
}
|
||||
_outputProvider.GetSamples(samplesNeeded, out samples, out samplesProvided);
|
||||
_outputProvider.GetSamples(samplesNeeded, out samples, out sampleCount);
|
||||
sampleOffset = 0;
|
||||
}
|
||||
}
|
||||
else if (_bufferedProvider == _bufferedAsync)
|
||||
|
@ -191,14 +200,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
_bufferedAsync.GetSamplesAsync(samples);
|
||||
|
||||
samplesProvided = samplesNeeded;
|
||||
sampleOffset = 0;
|
||||
sampleCount = samplesNeeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_outputDevice.WriteSamples(samples, samplesProvided);
|
||||
_outputDevice.WriteSamples(samples, sampleOffset, sampleCount);
|
||||
}
|
||||
|
||||
public static int MillisecondsToSamples(int milliseconds)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
|
@ -9,14 +10,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
public ToolAttribute(bool released, string[] supportedSystems, string[] unsupportedCores = null)
|
||||
{
|
||||
Released = released;
|
||||
SupportedSystems = supportedSystems;
|
||||
UnsupportedCores = unsupportedCores;
|
||||
SupportedSystems = supportedSystems ?? Enumerable.Empty<string>();
|
||||
UnsupportedCores = unsupportedCores ?? Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
public bool Released { get; private set; }
|
||||
public bool Released { get; }
|
||||
|
||||
public IEnumerable<string> SupportedSystems { get; private set; }
|
||||
public IEnumerable<string> SupportedSystems { get; }
|
||||
|
||||
public IEnumerable<string> UnsupportedCores { get; private set; }
|
||||
public IEnumerable<string> UnsupportedCores { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,42 +2,21 @@
|
|||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public static class UIHelper
|
||||
{
|
||||
private static readonly AutoScaleMode _autoScaleMode = AutoScaleMode.Font;
|
||||
private static readonly SizeF _autoScaleBaseSize = new SizeF(6F, 13F);
|
||||
private static readonly SizeF _autoScaleCurrentSize = GetCurrentAutoScaleSize(_autoScaleMode);
|
||||
public static AutoScaleMode AutoScaleMode { get; } = AutoScaleMode.Font;
|
||||
|
||||
private static SizeF GetCurrentAutoScaleSize(AutoScaleMode autoScaleMode)
|
||||
{
|
||||
using (Form form = new Form())
|
||||
{
|
||||
form.AutoScaleMode = autoScaleMode;
|
||||
return form.CurrentAutoScaleDimensions;
|
||||
}
|
||||
}
|
||||
public static SizeF AutoScaleBaseSize { get; } = new SizeF(6F, 13F);
|
||||
|
||||
public static AutoScaleMode AutoScaleMode
|
||||
{
|
||||
get { return _autoScaleMode; }
|
||||
}
|
||||
public static SizeF AutoScaleCurrentSize { get; } = GetCurrentAutoScaleSize(AutoScaleMode);
|
||||
|
||||
public static SizeF AutoScaleBaseSize
|
||||
{
|
||||
get { return _autoScaleBaseSize; }
|
||||
}
|
||||
public static float AutoScaleFactorX { get; } = AutoScaleCurrentSize.Width / AutoScaleBaseSize.Width;
|
||||
|
||||
public static float AutoScaleFactorX
|
||||
{
|
||||
get { return _autoScaleCurrentSize.Width / _autoScaleBaseSize.Width; }
|
||||
}
|
||||
public static float AutoScaleFactorY { get; } = AutoScaleCurrentSize.Height / AutoScaleBaseSize.Height;
|
||||
|
||||
public static float AutoScaleFactorY
|
||||
{
|
||||
get { return _autoScaleCurrentSize.Height / _autoScaleBaseSize.Height; }
|
||||
}
|
||||
public static SizeF AutoScaleFactor { get; } = new SizeF(AutoScaleFactorX, AutoScaleFactorY);
|
||||
|
||||
public static int ScaleX(int size)
|
||||
{
|
||||
|
@ -58,5 +37,13 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return new Size(ScaleX(s.Width), ScaleY(s.Height));
|
||||
}
|
||||
|
||||
private static SizeF GetCurrentAutoScaleSize(AutoScaleMode autoScaleMode)
|
||||
{
|
||||
using (var form = new Form { AutoScaleMode = autoScaleMode })
|
||||
{
|
||||
return form.CurrentAutoScaleDimensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true"/>
|
||||
</runtime>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true"/>
|
||||
</runtime>
|
||||
<appSettings>
|
||||
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
|
||||
</appSettings>
|
||||
</configuration>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="BizHawk.Client.EmuHawk.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel element will disable file and registry virtualization.
|
||||
Remove this element if your application requires this virtualization for backwards
|
||||
compatibility.
|
||||
-->
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
|
@ -302,7 +302,8 @@
|
|||
this.Name = "ControllerConfig";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Controller Config";
|
||||
this.Load += new System.EventHandler(this.NewControllerConfig_Load);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ControllerConfig_FormClosed);
|
||||
this.Load += new System.EventHandler(this.ControllerConfig_Load);
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
|
|
|
@ -49,7 +49,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
ControllerImages.Add("Apple IIe Keyboard", Properties.Resources.AppleIIKeyboard);
|
||||
ControllerImages.Add("VirtualBoy Controller", Properties.Resources.VBoyController);
|
||||
ControllerImages.Add("NeoGeo Portable Controller", Properties.Resources.NGPController);
|
||||
|
||||
ControllerImages.Add("MAME Controller", Properties.Resources.ArcadeController);
|
||||
}
|
||||
|
||||
private ControllerConfig()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnActivated(EventArgs e)
|
||||
|
@ -64,13 +69,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
Input.Instance.ControlInputFocus(this, Input.InputFocus.Mouse, false);
|
||||
}
|
||||
|
||||
private ControllerConfig()
|
||||
private void ControllerConfig_Load(object sender, EventArgs e)
|
||||
{
|
||||
InitializeComponent();
|
||||
Closing += (o, e) =>
|
||||
{
|
||||
buttonOK.Focus(); // A very dirty hack to avoid https://code.google.com/p/bizhawk/issues/detail?id=161
|
||||
};
|
||||
Text = $"{_theDefinition.Name} Configuration";
|
||||
}
|
||||
|
||||
private void ControllerConfig_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Input.Instance.ClearEvents();
|
||||
}
|
||||
|
||||
private delegate Control PanelCreator<T>(Dictionary<string, T> settings, List<string> buttons, Size size);
|
||||
|
@ -187,7 +193,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (Global.Emulator.SystemId == "ZXSpectrum" || Global.Emulator.SystemId == "AmstradCPC" || Global.Emulator.SystemId == "ChannelF")
|
||||
return;
|
||||
|
||||
string tabname = (Global.Emulator.SystemId == "C64") ? "Keyboard" : "Console"; // hack
|
||||
string tabname =
|
||||
(Global.Emulator.SystemId == "C64") ? "Keyboard" :
|
||||
(Global.Emulator.SystemId == "MAME") ? "Misc" :
|
||||
"Console"; // hack
|
||||
tt.TabPages.Add(tabname);
|
||||
tt.TabPages[pageidx].Controls.Add(createpanel(settings, buckets[0], tt.Size));
|
||||
}
|
||||
|
@ -365,11 +374,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
Close();
|
||||
}
|
||||
|
||||
private void NewControllerConfig_Load(object sender, EventArgs e)
|
||||
{
|
||||
Text = $"{_theDefinition.Name} Configuration";
|
||||
}
|
||||
|
||||
private static TabControl GetTabControl(IEnumerable controls)
|
||||
{
|
||||
if (controls != null)
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
this.NeverAskSaveCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.AcceptBackgroundInputCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.RunInBackgroundCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.SaveWindowPositionCheckbox = new System.Windows.Forms.CheckBox();
|
||||
|
@ -73,6 +74,7 @@
|
|||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
|
@ -120,10 +122,12 @@
|
|||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.Controls.Add(this.HandleAlternateKeyboardLayoutsCheckBox);
|
||||
this.tabPage1.Controls.Add(this.groupBox1);
|
||||
this.tabPage1.Controls.Add(this.NeverAskSaveCheckbox);
|
||||
this.tabPage1.Controls.Add(this.label2);
|
||||
this.tabPage1.Controls.Add(this.AcceptBackgroundInputCheckbox);
|
||||
this.tabPage1.Controls.Add(this.AcceptBackgroundInputControllerOnlyCheckBox);
|
||||
this.tabPage1.Controls.Add(this.label1);
|
||||
this.tabPage1.Controls.Add(this.RunInBackgroundCheckbox);
|
||||
this.tabPage1.Controls.Add(this.SaveWindowPositionCheckbox);
|
||||
|
@ -144,7 +148,7 @@
|
|||
this.groupBox1.Controls.Add(this.StartFullScreenCheckbox);
|
||||
this.groupBox1.Controls.Add(this.label3);
|
||||
this.groupBox1.Controls.Add(this.SingleInstanceModeCheckbox);
|
||||
this.groupBox1.Location = new System.Drawing.Point(6, 182);
|
||||
this.groupBox1.Location = new System.Drawing.Point(6, 205);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(369, 140);
|
||||
this.groupBox1.TabIndex = 13;
|
||||
|
@ -215,7 +219,7 @@
|
|||
this.label2.Location = new System.Drawing.Point(26, 155);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(349, 13);
|
||||
this.label2.TabIndex = 9;
|
||||
this.label2.TabIndex = 10;
|
||||
this.label2.Text = "When this is set, the client will receive user input even when focus is lost";
|
||||
//
|
||||
// AcceptBackgroundInputCheckbox
|
||||
|
@ -227,6 +231,18 @@
|
|||
this.AcceptBackgroundInputCheckbox.TabIndex = 8;
|
||||
this.AcceptBackgroundInputCheckbox.Text = "Accept background input";
|
||||
this.AcceptBackgroundInputCheckbox.UseVisualStyleBackColor = true;
|
||||
this.AcceptBackgroundInputCheckbox.CheckedChanged += new System.EventHandler(this.AcceptBackgroundInputCheckbox_CheckedChanged);
|
||||
//
|
||||
// AcceptBackgroundInputControllerOnlyCheckBox
|
||||
//
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.AutoSize = true;
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.Enabled = false;
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.Location = new System.Drawing.Point(156, 135);
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.Name = "AcceptBackgroundInputControllerOnlyCheckBox";
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.Size = new System.Drawing.Size(117, 17);
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.TabIndex = 9;
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.Text = "From controller only";
|
||||
this.AcceptBackgroundInputControllerOnlyCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
|
@ -313,7 +329,7 @@
|
|||
this.groupBox2.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(265, 60);
|
||||
this.groupBox2.TabIndex = 27;
|
||||
this.groupBox2.TabIndex = 5;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "AutoSaveRAM";
|
||||
//
|
||||
|
@ -327,7 +343,7 @@
|
|||
0});
|
||||
this.AutosaveSRAMtextBox.Name = "AutosaveSRAMtextBox";
|
||||
this.AutosaveSRAMtextBox.Size = new System.Drawing.Size(50, 20);
|
||||
this.AutosaveSRAMtextBox.TabIndex = 27;
|
||||
this.AutosaveSRAMtextBox.TabIndex = 5;
|
||||
//
|
||||
// AutosaveSRAMradioButton1
|
||||
//
|
||||
|
@ -335,7 +351,7 @@
|
|||
this.AutosaveSRAMradioButton1.Location = new System.Drawing.Point(48, 33);
|
||||
this.AutosaveSRAMradioButton1.Name = "AutosaveSRAMradioButton1";
|
||||
this.AutosaveSRAMradioButton1.Size = new System.Drawing.Size(36, 17);
|
||||
this.AutosaveSRAMradioButton1.TabIndex = 22;
|
||||
this.AutosaveSRAMradioButton1.TabIndex = 2;
|
||||
this.AutosaveSRAMradioButton1.TabStop = true;
|
||||
this.AutosaveSRAMradioButton1.Text = "5s";
|
||||
this.AutosaveSRAMradioButton1.UseVisualStyleBackColor = true;
|
||||
|
@ -346,7 +362,7 @@
|
|||
this.label8.Location = new System.Drawing.Point(202, 35);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(12, 13);
|
||||
this.label8.TabIndex = 26;
|
||||
this.label8.TabIndex = 6;
|
||||
this.label8.Text = "s";
|
||||
//
|
||||
// AutosaveSRAMradioButton2
|
||||
|
@ -355,7 +371,7 @@
|
|||
this.AutosaveSRAMradioButton2.Location = new System.Drawing.Point(90, 34);
|
||||
this.AutosaveSRAMradioButton2.Name = "AutosaveSRAMradioButton2";
|
||||
this.AutosaveSRAMradioButton2.Size = new System.Drawing.Size(39, 17);
|
||||
this.AutosaveSRAMradioButton2.TabIndex = 23;
|
||||
this.AutosaveSRAMradioButton2.TabIndex = 3;
|
||||
this.AutosaveSRAMradioButton2.TabStop = true;
|
||||
this.AutosaveSRAMradioButton2.Text = "5m";
|
||||
this.AutosaveSRAMradioButton2.UseVisualStyleBackColor = true;
|
||||
|
@ -366,7 +382,7 @@
|
|||
this.AutosaveSRAMradioButton3.Location = new System.Drawing.Point(131, 35);
|
||||
this.AutosaveSRAMradioButton3.Name = "AutosaveSRAMradioButton3";
|
||||
this.AutosaveSRAMradioButton3.Size = new System.Drawing.Size(14, 13);
|
||||
this.AutosaveSRAMradioButton3.TabIndex = 24;
|
||||
this.AutosaveSRAMradioButton3.TabIndex = 4;
|
||||
this.AutosaveSRAMradioButton3.TabStop = true;
|
||||
this.AutosaveSRAMradioButton3.UseVisualStyleBackColor = true;
|
||||
this.AutosaveSRAMradioButton3.CheckedChanged += new System.EventHandler(this.AutosaveSRAMradioButton3_CheckedChanged);
|
||||
|
@ -377,7 +393,7 @@
|
|||
this.AutosaveSRAMCheckbox.Location = new System.Drawing.Point(6, 62);
|
||||
this.AutosaveSRAMCheckbox.Name = "AutosaveSRAMCheckbox";
|
||||
this.AutosaveSRAMCheckbox.Size = new System.Drawing.Size(15, 14);
|
||||
this.AutosaveSRAMCheckbox.TabIndex = 21;
|
||||
this.AutosaveSRAMCheckbox.TabIndex = 4;
|
||||
this.AutosaveSRAMCheckbox.UseVisualStyleBackColor = true;
|
||||
this.AutosaveSRAMCheckbox.CheckedChanged += new System.EventHandler(this.AutosaveSRAMCheckbox_CheckedChanged);
|
||||
//
|
||||
|
@ -397,7 +413,7 @@
|
|||
this.label7.Location = new System.Drawing.Point(3, 1);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(50, 13);
|
||||
this.label7.TabIndex = 2;
|
||||
this.label7.TabIndex = 0;
|
||||
this.label7.Text = "Lua Core";
|
||||
//
|
||||
// LuaInterfaceRadio
|
||||
|
@ -406,7 +422,7 @@
|
|||
this.LuaInterfaceRadio.Location = new System.Drawing.Point(4, 36);
|
||||
this.LuaInterfaceRadio.Name = "LuaInterfaceRadio";
|
||||
this.LuaInterfaceRadio.Size = new System.Drawing.Size(338, 17);
|
||||
this.LuaInterfaceRadio.TabIndex = 1;
|
||||
this.LuaInterfaceRadio.TabIndex = 2;
|
||||
this.LuaInterfaceRadio.TabStop = true;
|
||||
this.LuaInterfaceRadio.Text = "Lua+LuaInterface - Faster but memory leaks, use at your own risk!";
|
||||
this.LuaInterfaceRadio.UseVisualStyleBackColor = true;
|
||||
|
@ -417,7 +433,7 @@
|
|||
this.NLuaRadio.Location = new System.Drawing.Point(4, 17);
|
||||
this.NLuaRadio.Name = "NLuaRadio";
|
||||
this.NLuaRadio.Size = new System.Drawing.Size(194, 17);
|
||||
this.NLuaRadio.TabIndex = 0;
|
||||
this.NLuaRadio.TabIndex = 1;
|
||||
this.NLuaRadio.TabStop = true;
|
||||
this.NLuaRadio.Text = "NLua+KopiLua - Reliable but slower";
|
||||
this.NLuaRadio.UseVisualStyleBackColor = true;
|
||||
|
@ -507,7 +523,7 @@
|
|||
this.BackupSRamCheckbox.Location = new System.Drawing.Point(6, 39);
|
||||
this.BackupSRamCheckbox.Name = "BackupSRamCheckbox";
|
||||
this.BackupSRamCheckbox.Size = new System.Drawing.Size(203, 17);
|
||||
this.BackupSRamCheckbox.TabIndex = 9;
|
||||
this.BackupSRamCheckbox.TabIndex = 3;
|
||||
this.BackupSRamCheckbox.Text = "Backup SaveRAM to .SaveRAM.bak";
|
||||
this.BackupSRamCheckbox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
|
@ -536,7 +552,7 @@
|
|||
this.label9.Location = new System.Drawing.Point(6, 16);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(225, 13);
|
||||
this.label9.TabIndex = 28;
|
||||
this.label9.TabIndex = 0;
|
||||
this.label9.Text = "Save SaveRAM to .AutoSaveRAM.SaveRAM";
|
||||
//
|
||||
// label10
|
||||
|
@ -545,9 +561,19 @@
|
|||
this.label10.Location = new System.Drawing.Point(9, 34);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(33, 13);
|
||||
this.label10.TabIndex = 29;
|
||||
this.label10.TabIndex = 1;
|
||||
this.label10.Text = "every";
|
||||
//
|
||||
// HandleAlternateKeyboardLayoutsCheckBox
|
||||
//
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.AutoSize = true;
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.Location = new System.Drawing.Point(6, 175);
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.Name = "HandleAlternateKeyboardLayoutsCheckBox";
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.Size = new System.Drawing.Size(255, 17);
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.TabIndex = 11;
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.Text = "Handle alternate keyboard layouts (e.g. Dvorak) [experimental]";
|
||||
this.HandleAlternateKeyboardLayoutsCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// EmuHawkOptions
|
||||
//
|
||||
this.AcceptButton = this.OkBtn;
|
||||
|
@ -593,6 +619,7 @@
|
|||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.CheckBox AcceptBackgroundInputCheckbox;
|
||||
private System.Windows.Forms.CheckBox AcceptBackgroundInputControllerOnlyCheckBox;
|
||||
private System.Windows.Forms.CheckBox NeverAskSaveCheckbox;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.CheckBox SingleInstanceModeCheckbox;
|
||||
|
@ -625,5 +652,6 @@
|
|||
private System.Windows.Forms.NumericUpDown AutosaveSRAMtextBox;
|
||||
private System.Windows.Forms.Label label10;
|
||||
private System.Windows.Forms.Label label9;
|
||||
private System.Windows.Forms.CheckBox HandleAlternateKeyboardLayoutsCheckBox;
|
||||
}
|
||||
}
|
|
@ -49,6 +49,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
SaveWindowPositionCheckbox.Checked = Global.Config.SaveWindowPosition;
|
||||
RunInBackgroundCheckbox.Checked = Global.Config.RunInBackground;
|
||||
AcceptBackgroundInputCheckbox.Checked = Global.Config.AcceptBackgroundInput;
|
||||
AcceptBackgroundInputControllerOnlyCheckBox.Checked = Global.Config.AcceptBackgroundInputControllerOnly;
|
||||
HandleAlternateKeyboardLayoutsCheckBox.Checked = Global.Config.HandleAlternateKeyboardLayouts;
|
||||
NeverAskSaveCheckbox.Checked = Global.Config.SupressAskSave;
|
||||
SingleInstanceModeCheckbox.Checked = Global.Config.SingleInstanceMode;
|
||||
|
||||
|
@ -83,6 +85,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
Global.Config.SaveWindowPosition = SaveWindowPositionCheckbox.Checked;
|
||||
Global.Config.RunInBackground = RunInBackgroundCheckbox.Checked;
|
||||
Global.Config.AcceptBackgroundInput = AcceptBackgroundInputCheckbox.Checked;
|
||||
Global.Config.AcceptBackgroundInputControllerOnly = AcceptBackgroundInputControllerOnlyCheckBox.Checked;
|
||||
Global.Config.HandleAlternateKeyboardLayouts = HandleAlternateKeyboardLayoutsCheckBox.Checked;
|
||||
Global.Config.SupressAskSave = NeverAskSaveCheckbox.Checked;
|
||||
Global.Config.SingleInstanceMode = SingleInstanceModeCheckbox.Checked;
|
||||
|
||||
|
@ -113,6 +117,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
GlobalWin.OSD.AddMessage("Customizing aborted.");
|
||||
}
|
||||
|
||||
private void AcceptBackgroundInputCheckbox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
AcceptBackgroundInputControllerOnlyCheckBox.Enabled = AcceptBackgroundInputCheckbox.Checked;
|
||||
}
|
||||
|
||||
private void AutosaveSRAMCheckbox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
groupBox2.Enabled = AutosaveSRAMCheckbox.Checked;
|
||||
|
|
|
@ -228,7 +228,8 @@
|
|||
this.Name = "HotkeyConfig";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Configure Hotkeys";
|
||||
this.Load += new System.EventHandler(this.NewHotkeyWindow_Load);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.HotkeyConfig_FormClosed);
|
||||
this.Load += new System.EventHandler(this.HotkeyConfig_Load);
|
||||
this.HotkeyTabControl.ResumeLayout(false);
|
||||
this.clearBtnContextMenu.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
|
|
@ -14,11 +14,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
Closing += (o, e) =>
|
||||
{
|
||||
IDB_SAVE.Focus(); // A very dirty hack to avoid https://code.google.com/p/bizhawk/issues/detail?id=161
|
||||
};
|
||||
|
||||
tabPage1.Focus();
|
||||
}
|
||||
|
||||
|
@ -34,7 +29,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
Input.Instance.ControlInputFocus(this, Input.InputFocus.Mouse, false);
|
||||
}
|
||||
|
||||
private void NewHotkeyWindow_Load(object sender, EventArgs e)
|
||||
private void HotkeyConfig_Load(object sender, EventArgs e)
|
||||
{
|
||||
var source = new AutoCompleteStringCollection();
|
||||
source.AddRange(Global.Config.HotkeyBindings.Select(x => x.DisplayName).ToArray());
|
||||
|
@ -47,6 +42,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
DoFocus();
|
||||
}
|
||||
|
||||
private void HotkeyConfig_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Input.Instance.ClearEvents();
|
||||
}
|
||||
|
||||
private void IDB_CANCEL_Click(object sender, EventArgs e)
|
||||
{
|
||||
GlobalWin.OSD.AddMessage("Hotkey config aborted");
|
||||
|
@ -72,64 +72,49 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
foreach (var w in InputWidgets)
|
||||
{
|
||||
var b = Global.Config.HotkeyBindings.FirstOrDefault(x => x.DisplayName == w.WidgetName);
|
||||
var b = Global.Config.HotkeyBindings.First(x => x.DisplayName == w.WidgetName);
|
||||
b.Bindings = w.Bindings;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<InputCompositeWidget> InputWidgets
|
||||
{
|
||||
get
|
||||
{
|
||||
var widgets = new List<InputCompositeWidget>();
|
||||
for (var x = 0; x < HotkeyTabControl.TabPages.Count; x++)
|
||||
{
|
||||
for (var y = 0; y < HotkeyTabControl.TabPages[x].Controls.Count; y++)
|
||||
{
|
||||
if (HotkeyTabControl.TabPages[x].Controls[y] is InputCompositeWidget)
|
||||
{
|
||||
widgets.Add(HotkeyTabControl.TabPages[x].Controls[y] as InputCompositeWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
return widgets;
|
||||
}
|
||||
}
|
||||
private IEnumerable<InputCompositeWidget> InputWidgets =>
|
||||
HotkeyTabControl.TabPages.Cast<TabPage>().SelectMany(tp => tp.Controls.OfType<InputCompositeWidget>());
|
||||
|
||||
private void DoTabs()
|
||||
{
|
||||
HotkeyTabControl.SuspendLayout();
|
||||
HotkeyTabControl.TabPages.Clear();
|
||||
|
||||
// Buckets
|
||||
var tabs = Global.Config.HotkeyBindings.Select(x => x.TabGroup).Distinct().ToList();
|
||||
var tabs = Global.Config.HotkeyBindings.Select(x => x.TabGroup).Distinct();
|
||||
|
||||
foreach (var tab in tabs)
|
||||
{
|
||||
var _y = UIHelper.ScaleY(14);
|
||||
var _x = UIHelper.ScaleX(6);
|
||||
|
||||
var tb = new TabPage {Name = tab, Text = tab};
|
||||
|
||||
var bindings = Global.Config.HotkeyBindings.Where(x => x.TabGroup == tab).OrderBy(x => x.Ordinal).ThenBy(x => x.DisplayName).ToList();
|
||||
|
||||
var tb = new TabPage { Name = tab, Text = tab };
|
||||
var bindings = Global.Config.HotkeyBindings.Where(n => n.TabGroup == tab).OrderBy(n => n.Ordinal).ThenBy(n => n.DisplayName);
|
||||
int x = UIHelper.ScaleX(6);
|
||||
int y = UIHelper.ScaleY(14);
|
||||
int iwOffsetX = UIHelper.ScaleX(110);
|
||||
int iwOffsetY = UIHelper.ScaleY(-4);
|
||||
int iwWidth = UIHelper.ScaleX(120);
|
||||
|
||||
tb.SuspendLayout();
|
||||
|
||||
foreach (var b in bindings)
|
||||
{
|
||||
var l = new Label
|
||||
{
|
||||
Text = b.DisplayName,
|
||||
Location = new Point(_x, _y),
|
||||
Size = new Size(iwOffsetX - UIHelper.ScaleX(2), UIHelper.ScaleY(15)),
|
||||
Location = new Point(x, y),
|
||||
Size = new Size(iwOffsetX - UIHelper.ScaleX(2), UIHelper.ScaleY(15))
|
||||
};
|
||||
|
||||
var w = new InputCompositeWidget
|
||||
{
|
||||
Location = new Point(_x + iwOffsetX, _y + iwOffsetY),
|
||||
Location = new Point(x + iwOffsetX, y + iwOffsetY),
|
||||
AutoTab = AutoTabCheckBox.Checked,
|
||||
Width = iwWidth,
|
||||
WidgetName = b.DisplayName,
|
||||
WidgetName = b.DisplayName
|
||||
};
|
||||
|
||||
w.SetupTooltip(toolTip1, b.ToolTip);
|
||||
|
@ -140,11 +125,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
tb.Controls.Add(l);
|
||||
tb.Controls.Add(w);
|
||||
|
||||
_y += UIHelper.ScaleY(24);
|
||||
if (_y > HotkeyTabControl.Height - UIHelper.ScaleY(35))
|
||||
y += UIHelper.ScaleY(24);
|
||||
if (y > HotkeyTabControl.Height - UIHelper.ScaleY(35))
|
||||
{
|
||||
_x += iwOffsetX + iwWidth + UIHelper.ScaleX(10);
|
||||
_y = UIHelper.ScaleY(14);
|
||||
x += iwOffsetX + iwWidth + UIHelper.ScaleX(10);
|
||||
y = UIHelper.ScaleY(14);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,13 +138,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
tb.Controls.Add(new Label
|
||||
{
|
||||
Text = "Save States hotkeys operate with branches when TAStudio is engaged.",
|
||||
Location = new Point(_x, _y),
|
||||
Size = new Size(iwWidth + iwOffsetX, HotkeyTabControl.Height - _y),
|
||||
Location = new Point(x, y),
|
||||
Size = new Size(iwWidth + iwOffsetX, HotkeyTabControl.Height - y)
|
||||
});
|
||||
}
|
||||
|
||||
HotkeyTabControl.TabPages.Add(tb);
|
||||
tb.ResumeLayout();
|
||||
}
|
||||
|
||||
HotkeyTabControl.ResumeLayout();
|
||||
}
|
||||
|
||||
private void Defaults()
|
||||
|
@ -232,7 +220,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (w != null)
|
||||
{
|
||||
HotkeyTabControl.SelectTab((TabPage)w.Parent);
|
||||
Input.Instance.BindUnpress(e.KeyCode);
|
||||
w.Focus();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
// TODO: when binding, make sure that the new key combo is not in one of the other bindings
|
||||
private readonly Timer _timer = new Timer();
|
||||
private readonly List<string> _bindings = new List<string>();
|
||||
|
||||
private string _wasPressed = "";
|
||||
|
||||
private Input.InputEvent _lastPress;
|
||||
|
||||
public InputCompositeWidget CompositeWidget { get; set; }
|
||||
|
||||
|
@ -88,9 +88,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
protected override void OnEnter(EventArgs e)
|
||||
{
|
||||
Input.Instance.ClearEvents();
|
||||
_lastPress = null;
|
||||
_timer.Start();
|
||||
|
||||
_wasPressed = Input.Instance.GetNextBindEvent();
|
||||
BackColor = Color.FromArgb(unchecked((int)0xFFC0FFFF)); // Color.LightCyan is too light on Windows 8, this is a bit darker
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
base.OnLeave(e);
|
||||
}
|
||||
|
||||
protected override void OnHandleDestroyed(EventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
base.OnHandleDestroyed(e);
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
ReadKeys();
|
||||
|
@ -129,11 +135,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void ReadKeys()
|
||||
{
|
||||
Input.Instance.Update();
|
||||
var bindingStr = Input.Instance.GetNextBindEvent();
|
||||
if (!string.IsNullOrEmpty(_wasPressed) && bindingStr == _wasPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var bindingStr = Input.Instance.GetNextBindEvent(ref _lastPress);
|
||||
|
||||
if (bindingStr != null)
|
||||
{
|
||||
|
@ -171,7 +173,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
_bindings.Add(bindingStr);
|
||||
}
|
||||
|
||||
_wasPressed = bindingStr;
|
||||
UpdateLabel();
|
||||
Increment();
|
||||
}
|
||||
|
@ -188,8 +189,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
base.OnKeyUp(e);
|
||||
}
|
||||
|
||||
_wasPressed = "";
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
typeof(NES.NESSyncSettings.Region),
|
||||
(string)RegionComboBox.SelectedItem);
|
||||
|
||||
List<byte> oldRam = _syncSettings.InitialWRamStatePattern?.ToList() ?? new List<byte>();
|
||||
var oldRam = _syncSettings.InitialWRamStatePattern ?? new List<byte>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(RamPatternOverrideBox.Text))
|
||||
{
|
||||
|
|
|
@ -115,8 +115,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
var paths = pathCollection
|
||||
.Where(p => p.System == systemId)
|
||||
.OrderBy(p => p.Ordinal)
|
||||
.ThenBy(p => p.Type)
|
||||
.ToList();
|
||||
.ThenBy(p => p.Type);
|
||||
|
||||
var y = UIHelper.ScaleY(14);
|
||||
foreach (var path in paths)
|
||||
|
@ -261,10 +260,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void DoRomToggle()
|
||||
{
|
||||
AllPathControls
|
||||
.Where(c => c.Name == "ROM")
|
||||
.ToList()
|
||||
.ForEach(control => control.Enabled = !RecentForROMs.Checked);
|
||||
foreach (var control in AllPathControls.Where(c => c.Name == "ROM"))
|
||||
{
|
||||
control.Enabled = !RecentForROMs.Checked;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<TextBox> AllPathBoxes
|
||||
|
|
|
@ -186,7 +186,7 @@
|
|||
this.label10.Location = new System.Drawing.Point(6, 20);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(40, 13);
|
||||
this.label10.TabIndex = 17;
|
||||
this.label10.TabIndex = 0;
|
||||
this.label10.Text = "Enable";
|
||||
//
|
||||
// LargeStateEnabledBox
|
||||
|
@ -195,7 +195,7 @@
|
|||
this.LargeStateEnabledBox.Location = new System.Drawing.Point(9, 87);
|
||||
this.LargeStateEnabledBox.Name = "LargeStateEnabledBox";
|
||||
this.LargeStateEnabledBox.Size = new System.Drawing.Size(15, 14);
|
||||
this.LargeStateEnabledBox.TabIndex = 16;
|
||||
this.LargeStateEnabledBox.TabIndex = 11;
|
||||
this.LargeStateEnabledBox.UseVisualStyleBackColor = true;
|
||||
this.LargeStateEnabledBox.CheckStateChanged += new System.EventHandler(this.LargeStateEnabledBox_CheckStateChanged);
|
||||
//
|
||||
|
@ -205,7 +205,7 @@
|
|||
this.MediumStateEnabledBox.Location = new System.Drawing.Point(9, 63);
|
||||
this.MediumStateEnabledBox.Name = "MediumStateEnabledBox";
|
||||
this.MediumStateEnabledBox.Size = new System.Drawing.Size(15, 14);
|
||||
this.MediumStateEnabledBox.TabIndex = 15;
|
||||
this.MediumStateEnabledBox.TabIndex = 6;
|
||||
this.MediumStateEnabledBox.UseVisualStyleBackColor = true;
|
||||
this.MediumStateEnabledBox.CheckStateChanged += new System.EventHandler(this.MediumStateEnabledBox_CheckStateChanged);
|
||||
//
|
||||
|
@ -215,7 +215,7 @@
|
|||
this.SmallStateEnabledBox.Location = new System.Drawing.Point(9, 39);
|
||||
this.SmallStateEnabledBox.Name = "SmallStateEnabledBox";
|
||||
this.SmallStateEnabledBox.Size = new System.Drawing.Size(15, 14);
|
||||
this.SmallStateEnabledBox.TabIndex = 14;
|
||||
this.SmallStateEnabledBox.TabIndex = 1;
|
||||
this.SmallStateEnabledBox.UseVisualStyleBackColor = true;
|
||||
this.SmallStateEnabledBox.CheckStateChanged += new System.EventHandler(this.SmallStateEnabledBox_CheckStateChanged);
|
||||
//
|
||||
|
@ -234,7 +234,7 @@
|
|||
this.LargeLabel3.Location = new System.Drawing.Point(307, 88);
|
||||
this.LargeLabel3.Name = "LargeLabel3";
|
||||
this.LargeLabel3.Size = new System.Drawing.Size(38, 13);
|
||||
this.LargeLabel3.TabIndex = 12;
|
||||
this.LargeLabel3.TabIndex = 15;
|
||||
this.LargeLabel3.Text = "frames";
|
||||
//
|
||||
// LargeSavestateNumeric
|
||||
|
@ -252,7 +252,7 @@
|
|||
0});
|
||||
this.LargeSavestateNumeric.Name = "LargeSavestateNumeric";
|
||||
this.LargeSavestateNumeric.Size = new System.Drawing.Size(38, 20);
|
||||
this.LargeSavestateNumeric.TabIndex = 11;
|
||||
this.LargeSavestateNumeric.TabIndex = 14;
|
||||
this.LargeSavestateNumeric.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
|
@ -266,7 +266,7 @@
|
|||
this.LargeLabel1.Location = new System.Drawing.Point(40, 88);
|
||||
this.LargeLabel1.Name = "LargeLabel1";
|
||||
this.LargeLabel1.Size = new System.Drawing.Size(179, 13);
|
||||
this.LargeLabel1.TabIndex = 10;
|
||||
this.LargeLabel1.TabIndex = 12;
|
||||
this.LargeLabel1.Text = "Large savestates (more than 100KB)";
|
||||
this.LargeLabel1.Click += new System.EventHandler(this.LargeLabel1_Click);
|
||||
//
|
||||
|
@ -276,7 +276,7 @@
|
|||
this.MediumLabel2.Location = new System.Drawing.Point(227, 64);
|
||||
this.MediumLabel2.Name = "MediumLabel2";
|
||||
this.MediumLabel2.Size = new System.Drawing.Size(33, 13);
|
||||
this.MediumLabel2.TabIndex = 9;
|
||||
this.MediumLabel2.TabIndex = 8;
|
||||
this.MediumLabel2.Text = "every";
|
||||
//
|
||||
// MediumLabel3
|
||||
|
@ -285,7 +285,7 @@
|
|||
this.MediumLabel3.Location = new System.Drawing.Point(307, 64);
|
||||
this.MediumLabel3.Name = "MediumLabel3";
|
||||
this.MediumLabel3.Size = new System.Drawing.Size(38, 13);
|
||||
this.MediumLabel3.TabIndex = 8;
|
||||
this.MediumLabel3.TabIndex = 10;
|
||||
this.MediumLabel3.Text = "frames";
|
||||
//
|
||||
// MediumSavestateNumeric
|
||||
|
@ -303,7 +303,7 @@
|
|||
0});
|
||||
this.MediumSavestateNumeric.Name = "MediumSavestateNumeric";
|
||||
this.MediumSavestateNumeric.Size = new System.Drawing.Size(38, 20);
|
||||
this.MediumSavestateNumeric.TabIndex = 7;
|
||||
this.MediumSavestateNumeric.TabIndex = 9;
|
||||
this.MediumSavestateNumeric.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
|
@ -317,7 +317,7 @@
|
|||
this.MediumLabel1.Location = new System.Drawing.Point(40, 64);
|
||||
this.MediumLabel1.Name = "MediumLabel1";
|
||||
this.MediumLabel1.Size = new System.Drawing.Size(160, 13);
|
||||
this.MediumLabel1.TabIndex = 6;
|
||||
this.MediumLabel1.TabIndex = 7;
|
||||
this.MediumLabel1.Text = "Medium savestates (32 - 100KB)";
|
||||
this.MediumLabel1.Click += new System.EventHandler(this.MediumLabel1_Click);
|
||||
//
|
||||
|
@ -327,7 +327,7 @@
|
|||
this.SmallLabel2.Location = new System.Drawing.Point(227, 40);
|
||||
this.SmallLabel2.Name = "SmallLabel2";
|
||||
this.SmallLabel2.Size = new System.Drawing.Size(33, 13);
|
||||
this.SmallLabel2.TabIndex = 5;
|
||||
this.SmallLabel2.TabIndex = 3;
|
||||
this.SmallLabel2.Text = "every";
|
||||
//
|
||||
// SmallLabel3
|
||||
|
@ -336,7 +336,7 @@
|
|||
this.SmallLabel3.Location = new System.Drawing.Point(307, 40);
|
||||
this.SmallLabel3.Name = "SmallLabel3";
|
||||
this.SmallLabel3.Size = new System.Drawing.Size(38, 13);
|
||||
this.SmallLabel3.TabIndex = 4;
|
||||
this.SmallLabel3.TabIndex = 5;
|
||||
this.SmallLabel3.Text = "frames";
|
||||
//
|
||||
// SmallSavestateNumeric
|
||||
|
@ -354,7 +354,7 @@
|
|||
0});
|
||||
this.SmallSavestateNumeric.Name = "SmallSavestateNumeric";
|
||||
this.SmallSavestateNumeric.Size = new System.Drawing.Size(38, 20);
|
||||
this.SmallSavestateNumeric.TabIndex = 3;
|
||||
this.SmallSavestateNumeric.TabIndex = 4;
|
||||
this.SmallSavestateNumeric.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
|
@ -399,7 +399,7 @@
|
|||
this.MediumStateTrackbar.Minimum = 1;
|
||||
this.MediumStateTrackbar.Name = "MediumStateTrackbar";
|
||||
this.MediumStateTrackbar.Size = new System.Drawing.Size(186, 45);
|
||||
this.MediumStateTrackbar.TabIndex = 7;
|
||||
this.MediumStateTrackbar.TabIndex = 1;
|
||||
this.MediumStateTrackbar.TickFrequency = 256;
|
||||
this.MediumStateTrackbar.Value = 1;
|
||||
this.MediumStateTrackbar.ValueChanged += new System.EventHandler(this.MediumStateTrackbar_ValueChanged);
|
||||
|
@ -417,7 +417,7 @@
|
|||
this.groupBox2.Location = new System.Drawing.Point(12, 387);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(371, 105);
|
||||
this.groupBox2.TabIndex = 8;
|
||||
this.groupBox2.TabIndex = 5;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "State Size Definition";
|
||||
//
|
||||
|
@ -436,7 +436,7 @@
|
|||
0});
|
||||
this.LargeStateUpDown.Name = "LargeStateUpDown";
|
||||
this.LargeStateUpDown.Size = new System.Drawing.Size(52, 20);
|
||||
this.LargeStateUpDown.TabIndex = 14;
|
||||
this.LargeStateUpDown.TabIndex = 6;
|
||||
this.LargeStateUpDown.Value = new decimal(new int[] {
|
||||
256,
|
||||
0,
|
||||
|
@ -459,7 +459,7 @@
|
|||
0});
|
||||
this.MediumStateUpDown.Name = "MediumStateUpDown";
|
||||
this.MediumStateUpDown.Size = new System.Drawing.Size(52, 20);
|
||||
this.MediumStateUpDown.TabIndex = 13;
|
||||
this.MediumStateUpDown.TabIndex = 2;
|
||||
this.MediumStateUpDown.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
|
@ -473,7 +473,7 @@
|
|||
this.LargeStateSizeLabel.Location = new System.Drawing.Point(312, 71);
|
||||
this.LargeStateSizeLabel.Name = "LargeStateSizeLabel";
|
||||
this.LargeStateSizeLabel.Size = new System.Drawing.Size(21, 13);
|
||||
this.LargeStateSizeLabel.TabIndex = 12;
|
||||
this.LargeStateSizeLabel.TabIndex = 7;
|
||||
this.LargeStateSizeLabel.Text = "KB";
|
||||
//
|
||||
// label5
|
||||
|
@ -482,7 +482,7 @@
|
|||
this.label5.Location = new System.Drawing.Point(27, 63);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(34, 13);
|
||||
this.label5.TabIndex = 11;
|
||||
this.label5.TabIndex = 4;
|
||||
this.label5.Text = "Large";
|
||||
//
|
||||
// LargeStateTrackbar
|
||||
|
@ -493,7 +493,7 @@
|
|||
this.LargeStateTrackbar.Minimum = 256;
|
||||
this.LargeStateTrackbar.Name = "LargeStateTrackbar";
|
||||
this.LargeStateTrackbar.Size = new System.Drawing.Size(186, 45);
|
||||
this.LargeStateTrackbar.TabIndex = 10;
|
||||
this.LargeStateTrackbar.TabIndex = 5;
|
||||
this.LargeStateTrackbar.TickFrequency = 1024;
|
||||
this.LargeStateTrackbar.Value = 256;
|
||||
this.LargeStateTrackbar.ValueChanged += new System.EventHandler(this.LargeStateTrackbar_ValueChanged);
|
||||
|
@ -504,7 +504,7 @@
|
|||
this.MediumStateSizeLabel.Location = new System.Drawing.Point(313, 35);
|
||||
this.MediumStateSizeLabel.Name = "MediumStateSizeLabel";
|
||||
this.MediumStateSizeLabel.Size = new System.Drawing.Size(21, 13);
|
||||
this.MediumStateSizeLabel.TabIndex = 9;
|
||||
this.MediumStateSizeLabel.TabIndex = 3;
|
||||
this.MediumStateSizeLabel.Text = "KB";
|
||||
//
|
||||
// label2
|
||||
|
@ -513,7 +513,7 @@
|
|||
this.label2.Location = new System.Drawing.Point(18, 31);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(44, 13);
|
||||
this.label2.TabIndex = 8;
|
||||
this.label2.TabIndex = 0;
|
||||
this.label2.Text = "Medium";
|
||||
//
|
||||
// groupBox3
|
||||
|
@ -531,7 +531,7 @@
|
|||
this.groupBox3.Location = new System.Drawing.Point(12, 214);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(371, 167);
|
||||
this.groupBox3.TabIndex = 9;
|
||||
this.groupBox3.TabIndex = 4;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "Rewind Options";
|
||||
//
|
||||
|
@ -683,7 +683,7 @@
|
|||
this.groupBox4.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox4.Name = "groupBox4";
|
||||
this.groupBox4.Size = new System.Drawing.Size(371, 72);
|
||||
this.groupBox4.TabIndex = 12;
|
||||
this.groupBox4.TabIndex = 2;
|
||||
this.groupBox4.TabStop = false;
|
||||
this.groupBox4.Text = "Current Statistics";
|
||||
//
|
||||
|
@ -767,7 +767,7 @@
|
|||
this.groupBox6.Location = new System.Drawing.Point(22, 78);
|
||||
this.groupBox6.Name = "groupBox6";
|
||||
this.groupBox6.Size = new System.Drawing.Size(215, 48);
|
||||
this.groupBox6.TabIndex = 0;
|
||||
this.groupBox6.TabIndex = 4;
|
||||
this.groupBox6.TabStop = false;
|
||||
this.groupBox6.Text = "Type";
|
||||
//
|
||||
|
@ -811,7 +811,7 @@
|
|||
this.btnResetCompression.Location = new System.Drawing.Point(243, 34);
|
||||
this.btnResetCompression.Name = "btnResetCompression";
|
||||
this.btnResetCompression.Size = new System.Drawing.Size(27, 27);
|
||||
this.btnResetCompression.TabIndex = 23;
|
||||
this.btnResetCompression.TabIndex = 3;
|
||||
this.toolTip1.SetToolTip(this.btnResetCompression, "Reset to default");
|
||||
this.btnResetCompression.UseVisualStyleBackColor = true;
|
||||
this.btnResetCompression.Click += new System.EventHandler(this.BtnResetCompression_Click);
|
||||
|
@ -823,7 +823,7 @@
|
|||
this.trackBarCompression.Maximum = 9;
|
||||
this.trackBarCompression.Name = "trackBarCompression";
|
||||
this.trackBarCompression.Size = new System.Drawing.Size(157, 45);
|
||||
this.trackBarCompression.TabIndex = 20;
|
||||
this.trackBarCompression.TabIndex = 1;
|
||||
this.toolTip1.SetToolTip(this.trackBarCompression, "0 = None; 9 = Maximum");
|
||||
this.trackBarCompression.Value = 1;
|
||||
this.trackBarCompression.ValueChanged += new System.EventHandler(this.TrackBarCompression_ValueChanged);
|
||||
|
@ -838,7 +838,7 @@
|
|||
0});
|
||||
this.nudCompression.Name = "nudCompression";
|
||||
this.nudCompression.Size = new System.Drawing.Size(52, 20);
|
||||
this.nudCompression.TabIndex = 22;
|
||||
this.nudCompression.TabIndex = 2;
|
||||
this.nudCompression.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
|
@ -866,7 +866,7 @@
|
|||
this.groupBox7.Location = new System.Drawing.Point(389, 12);
|
||||
this.groupBox7.Name = "groupBox7";
|
||||
this.groupBox7.Size = new System.Drawing.Size(342, 408);
|
||||
this.groupBox7.TabIndex = 2;
|
||||
this.groupBox7.TabIndex = 6;
|
||||
this.groupBox7.TabStop = false;
|
||||
this.groupBox7.Text = "Savestate Options";
|
||||
//
|
||||
|
@ -983,7 +983,7 @@
|
|||
this.label12.Location = new System.Drawing.Point(19, 21);
|
||||
this.label12.Name = "label12";
|
||||
this.label12.Size = new System.Drawing.Size(96, 13);
|
||||
this.label12.TabIndex = 24;
|
||||
this.label12.TabIndex = 0;
|
||||
this.label12.Text = "Compression Level";
|
||||
//
|
||||
// RewindConfig
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
this.cbEnableNormal.Location = new System.Drawing.Point(6, 20);
|
||||
this.cbEnableNormal.Name = "cbEnableNormal";
|
||||
this.cbEnableNormal.Size = new System.Drawing.Size(48, 17);
|
||||
this.cbEnableNormal.TabIndex = 3;
|
||||
this.cbEnableNormal.TabIndex = 0;
|
||||
this.cbEnableNormal.Text = "Ena.";
|
||||
this.cbEnableNormal.UseVisualStyleBackColor = true;
|
||||
this.cbEnableNormal.CheckedChanged += new System.EventHandler(this.UpdateSoundDialog);
|
||||
|
@ -116,7 +116,7 @@
|
|||
this.nudRWFF.Location = new System.Drawing.Point(58, 223);
|
||||
this.nudRWFF.Name = "nudRWFF";
|
||||
this.nudRWFF.Size = new System.Drawing.Size(45, 20);
|
||||
this.nudRWFF.TabIndex = 15;
|
||||
this.nudRWFF.TabIndex = 7;
|
||||
this.nudRWFF.Value = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
|
@ -129,7 +129,7 @@
|
|||
this.cbEnableRWFF.Location = new System.Drawing.Point(58, 20);
|
||||
this.cbEnableRWFF.Name = "cbEnableRWFF";
|
||||
this.cbEnableRWFF.Size = new System.Drawing.Size(48, 17);
|
||||
this.cbEnableRWFF.TabIndex = 14;
|
||||
this.cbEnableRWFF.TabIndex = 4;
|
||||
this.cbEnableRWFF.Text = "Ena.";
|
||||
this.cbEnableRWFF.UseVisualStyleBackColor = true;
|
||||
//
|
||||
|
@ -141,7 +141,7 @@
|
|||
this.tbRWFF.Name = "tbRWFF";
|
||||
this.tbRWFF.Orientation = System.Windows.Forms.Orientation.Vertical;
|
||||
this.tbRWFF.Size = new System.Drawing.Size(42, 164);
|
||||
this.tbRWFF.TabIndex = 13;
|
||||
this.tbRWFF.TabIndex = 6;
|
||||
this.tbRWFF.TickFrequency = 10;
|
||||
this.tbRWFF.Scroll += new System.EventHandler(this.TbRwff_Scroll);
|
||||
//
|
||||
|
@ -152,7 +152,7 @@
|
|||
this.label2.Location = new System.Drawing.Point(56, 42);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(50, 13);
|
||||
this.label2.TabIndex = 12;
|
||||
this.label2.TabIndex = 5;
|
||||
this.label2.Text = "RW && FF";
|
||||
//
|
||||
// label1
|
||||
|
@ -162,7 +162,7 @@
|
|||
this.label1.Location = new System.Drawing.Point(6, 42);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(40, 13);
|
||||
this.label1.TabIndex = 11;
|
||||
this.label1.TabIndex = 1;
|
||||
this.label1.Text = "Normal";
|
||||
//
|
||||
// tbNormal
|
||||
|
@ -173,7 +173,7 @@
|
|||
this.tbNormal.Name = "tbNormal";
|
||||
this.tbNormal.Orientation = System.Windows.Forms.Orientation.Vertical;
|
||||
this.tbNormal.Size = new System.Drawing.Size(42, 164);
|
||||
this.tbNormal.TabIndex = 0;
|
||||
this.tbNormal.TabIndex = 2;
|
||||
this.tbNormal.TickFrequency = 10;
|
||||
this.tbNormal.Scroll += new System.EventHandler(this.TrackBar1_Scroll);
|
||||
//
|
||||
|
@ -182,7 +182,7 @@
|
|||
this.nudNormal.Location = new System.Drawing.Point(5, 223);
|
||||
this.nudNormal.Name = "nudNormal";
|
||||
this.nudNormal.Size = new System.Drawing.Size(45, 20);
|
||||
this.nudNormal.TabIndex = 1;
|
||||
this.nudNormal.TabIndex = 3;
|
||||
this.nudNormal.Value = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
|
@ -199,7 +199,7 @@
|
|||
this.listBoxSoundDevices.Location = new System.Drawing.Point(138, 110);
|
||||
this.listBoxSoundDevices.Name = "listBoxSoundDevices";
|
||||
this.listBoxSoundDevices.Size = new System.Drawing.Size(254, 95);
|
||||
this.listBoxSoundDevices.TabIndex = 7;
|
||||
this.listBoxSoundDevices.TabIndex = 8;
|
||||
//
|
||||
// SoundDeviceLabel
|
||||
//
|
||||
|
@ -207,7 +207,7 @@
|
|||
this.SoundDeviceLabel.Location = new System.Drawing.Point(135, 89);
|
||||
this.SoundDeviceLabel.Name = "SoundDeviceLabel";
|
||||
this.SoundDeviceLabel.Size = new System.Drawing.Size(78, 13);
|
||||
this.SoundDeviceLabel.TabIndex = 6;
|
||||
this.SoundDeviceLabel.TabIndex = 7;
|
||||
this.SoundDeviceLabel.Text = "Sound Device:";
|
||||
//
|
||||
// BufferSizeLabel
|
||||
|
@ -217,7 +217,7 @@
|
|||
this.BufferSizeLabel.Location = new System.Drawing.Point(135, 210);
|
||||
this.BufferSizeLabel.Name = "BufferSizeLabel";
|
||||
this.BufferSizeLabel.Size = new System.Drawing.Size(61, 13);
|
||||
this.BufferSizeLabel.TabIndex = 8;
|
||||
this.BufferSizeLabel.TabIndex = 9;
|
||||
this.BufferSizeLabel.Text = "Buffer Size:";
|
||||
//
|
||||
// BufferSizeNumeric
|
||||
|
@ -236,7 +236,7 @@
|
|||
0});
|
||||
this.BufferSizeNumeric.Name = "BufferSizeNumeric";
|
||||
this.BufferSizeNumeric.Size = new System.Drawing.Size(59, 20);
|
||||
this.BufferSizeNumeric.TabIndex = 9;
|
||||
this.BufferSizeNumeric.TabIndex = 10;
|
||||
this.BufferSizeNumeric.Value = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
|
@ -250,7 +250,7 @@
|
|||
this.BufferSizeUnitsLabel.Location = new System.Drawing.Point(267, 210);
|
||||
this.BufferSizeUnitsLabel.Name = "BufferSizeUnitsLabel";
|
||||
this.BufferSizeUnitsLabel.Size = new System.Drawing.Size(63, 13);
|
||||
this.BufferSizeUnitsLabel.TabIndex = 10;
|
||||
this.BufferSizeUnitsLabel.TabIndex = 11;
|
||||
this.BufferSizeUnitsLabel.Text = "milliseconds";
|
||||
//
|
||||
// grpOutputMethod
|
||||
|
@ -261,7 +261,7 @@
|
|||
this.grpOutputMethod.Location = new System.Drawing.Point(292, 12);
|
||||
this.grpOutputMethod.Name = "grpOutputMethod";
|
||||
this.grpOutputMethod.Size = new System.Drawing.Size(100, 90);
|
||||
this.grpOutputMethod.TabIndex = 5;
|
||||
this.grpOutputMethod.TabIndex = 12;
|
||||
this.grpOutputMethod.TabStop = false;
|
||||
this.grpOutputMethod.Text = "Output Method";
|
||||
//
|
||||
|
@ -307,7 +307,7 @@
|
|||
this.cbMuteFrameAdvance.Location = new System.Drawing.Point(139, 68);
|
||||
this.cbMuteFrameAdvance.Name = "cbMuteFrameAdvance";
|
||||
this.cbMuteFrameAdvance.Size = new System.Drawing.Size(128, 17);
|
||||
this.cbMuteFrameAdvance.TabIndex = 17;
|
||||
this.cbMuteFrameAdvance.TabIndex = 6;
|
||||
this.cbMuteFrameAdvance.Text = "Mute Frame Advance";
|
||||
this.cbMuteFrameAdvance.UseVisualStyleBackColor = true;
|
||||
//
|
||||
|
@ -317,7 +317,7 @@
|
|||
this.cbEnableMaster.Location = new System.Drawing.Point(139, 16);
|
||||
this.cbEnableMaster.Name = "cbEnableMaster";
|
||||
this.cbEnableMaster.Size = new System.Drawing.Size(128, 17);
|
||||
this.cbEnableMaster.TabIndex = 18;
|
||||
this.cbEnableMaster.TabIndex = 4;
|
||||
this.cbEnableMaster.Text = "Sound Master Enable";
|
||||
this.cbEnableMaster.UseVisualStyleBackColor = true;
|
||||
this.cbEnableMaster.CheckedChanged += new System.EventHandler(this.UpdateSoundDialog);
|
||||
|
@ -328,7 +328,7 @@
|
|||
this.label3.Location = new System.Drawing.Point(161, 35);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(126, 26);
|
||||
this.label3.TabIndex = 19;
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Controls whether cores even generate audio.";
|
||||
//
|
||||
// SoundConfig
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 115 KiB |
Binary file not shown.
After Width: | Height: | Size: 745 B |
|
@ -49,7 +49,7 @@
|
|||
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.StopOnFrameCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.StopOnFrameTextBox = new BizHawk.Client.EmuHawk.WatchValueBox();
|
||||
this.MovieView = new BizHawk.Client.EmuHawk.VirtualListView();
|
||||
this.MovieView = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
|
@ -269,7 +269,6 @@
|
|||
this.MovieView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.MovieView.BlazingFast = false;
|
||||
this.MovieView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1,
|
||||
this.columnHeader2,
|
||||
|
@ -279,16 +278,13 @@
|
|||
this.MovieView.FullRowSelect = true;
|
||||
this.MovieView.GridLines = true;
|
||||
this.MovieView.HideSelection = false;
|
||||
this.MovieView.ItemCount = 0;
|
||||
this.MovieView.VirtualListSize = 0;
|
||||
this.MovieView.Location = new System.Drawing.Point(12, 28);
|
||||
this.MovieView.MultiSelect = false;
|
||||
this.MovieView.Name = "MovieView";
|
||||
this.MovieView.SelectAllInProgress = false;
|
||||
this.MovieView.selectedItem = -1;
|
||||
this.MovieView.Size = new System.Drawing.Size(480, 322);
|
||||
this.MovieView.TabIndex = 5;
|
||||
this.MovieView.UseCompatibleStateImageBehavior = false;
|
||||
this.MovieView.UseCustomBackground = true;
|
||||
this.MovieView.View = System.Windows.Forms.View.Details;
|
||||
this.MovieView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.MovieView_ColumnClick);
|
||||
this.MovieView.SelectedIndexChanged += new System.EventHandler(this.MovieView_SelectedIndexChanged);
|
||||
|
@ -381,7 +377,7 @@
|
|||
private System.Windows.Forms.Button Cancel;
|
||||
private System.Windows.Forms.Button OK;
|
||||
private System.Windows.Forms.Button BrowseMovies;
|
||||
private VirtualListView MovieView;
|
||||
private System.Windows.Forms.ListView MovieView;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader2;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader3;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue