diff --git a/Changelog.txt b/Changelog.txt index ffa8fb5..578c4cb 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,14 +1,18 @@ 2.5.0 -- Finally a merge of the source code of B2SBackglassServer & B2SBackglassServerEXE into one. Should not be noticed while running, but huge for development. -- Added new method B2SSetPos(ImageId, xpos, ypos) to move the images on the backglass. -- Added new method B2SServerBuild() returning float version number: 20500.0295 +- **Finally a merge of the source code** for B2SBackglassServer & B2SBackglassServerEXE into one. _Should not be noticed_ while running, but huge for development. +- Added new method B2SSetPos(ImageId, xpos, ypos) to move the images on the backglass. Currently only as DLL!!! +- Added new method B2SBuildVersion() returning float version number: 20500.0295 +- #122 Only crop "standard" images which does not rotate, while fixing "Events of overlapping pictures get merged #76" too many images was cropped. +- #121 B2S 2.1.2 Throws System NullReferenceException, a crash on certain tables fixed. +- #119 B2S Table Settings Saving But WIll Not Apply, the backglass hide flag was forgotten to be read. +- #96 Improve Fuzzy Matching to not use the DOS short names: "Fuzzy Matching" now cuts the table name after the first ")" and then tries to find a backglass named something like that. 2.1.2 - Request to turn off backglass in b2s settings #80 Thanks @stevejones72! It is a setting per table, so the table you save with hidden backglass will have it's backglass not shown. You can still get settings opened on the background or b2s-dmd using right click though. To edit the B2SBackglassSettings.xml file manually search for 1 and set to zero. -- Backglasses using overlapping partly transparent pictures get it's events merged. This is now deactivated by default. And cannot be deactivated! +- Backglasses using overlapping partly transparent pictures get it's events merged. This is now deactivated by default. 2.1.1 diff --git a/b2sbackglassserver/b2sbackglassserver/Classes/B2SAnimation.vb b/b2sbackglassserver/b2sbackglassserver/Classes/B2SAnimation.vb index 44205ae..cc1a5cb 100644 --- a/b2sbackglassserver/b2sbackglassserver/Classes/B2SAnimation.vb +++ b/b2sbackglassserver/b2sbackglassserver/Classes/B2SAnimation.vb @@ -404,10 +404,10 @@ Public Class B2SAnimation With DirectCast(currentForm, formBackglass) MainFormBackgroundImage = .BackgroundImage .BackgroundImage = .DarkImage - .Refresh() + .Invalidate() End With Else - currentForm.Refresh() + currentForm.Invalidate() End If End If End If diff --git a/b2sbackglassserver/b2sbackglassserver/Classes/B2SScreen.vb b/b2sbackglassserver/b2sbackglassserver/Classes/B2SScreen.vb index 54880b5..e70be6a 100644 --- a/b2sbackglassserver/b2sbackglassserver/Classes/B2SScreen.vb +++ b/b2sbackglassserver/b2sbackglassserver/Classes/B2SScreen.vb @@ -1,7 +1,5 @@ -Imports System Imports System.Windows.Forms Imports System.Drawing -Imports Microsoft.Win32 Imports System.IO Imports System.Reflection Imports System.Text.RegularExpressions @@ -368,9 +366,9 @@ Public Class B2SScreen ((Me.DMDViewMode = eDMDViewMode.ShowDMD) OrElse (Me.DMDViewMode = eDMDViewMode.ShowDMDOnlyAtDefaultLocation AndAlso Me.DMDAtDefaultLocation) OrElse (Me.DMDViewMode = eDMDViewMode.DoNotShowDMDAtDefaultLocation AndAlso Not Me.DMDAtDefaultLocation))) -#If B2S = "DLL" Then + On Error Resume Next -#End If + ' get the correct screen Me.BackglassScreen = ScreensOrdered(0) Dim s As Screen @@ -423,7 +421,7 @@ Public Class B2SScreen Me.formbackground.Size = Me.BackgroundSize Me.formbackground.Text = "B2S Backglass Server" Me.formbackground.BackColor = Color.Black - If (IO.File.Exists(Me.BackgroundPath)) Then + If (File.Exists(Me.BackgroundPath)) Then Me.formbackground.BackgroundImage = Image.FromFile(Me.BackgroundPath) ' ("C:\backglass.png") End If Me.formbackground.Show() @@ -515,11 +513,6 @@ Public Class B2SScreen formBackglass.Text = "B2S Backglass Server" formBackglass.Show() End If -#If B2S = "DLL" Then - ' bring backglass screen to the front - If B2SSettings.FormToFront Then formBackglass.TopMost = True - formBackglass.BringToFront() -#End If ' maybe show DMD form If IsDMDToBeShown Then ' set DMD location relative to the backglass location @@ -529,11 +522,7 @@ Public Class B2SScreen Me.formDMD.ControlBox = False Me.formDMD.MaximizeBox = False Me.formDMD.MinimizeBox = False -#If B2S = "DLL" Then - Me.formDMD.Location = formBackglass.Location + Me.DMDLocation -#Else Me.formDMD.Location = Me.BackglassScreen.Bounds.Location + DMDKeepBackglassLocation + Me.DMDLocation -#End If Me.formDMD.Size = Me.DMDSize Me.formDMD.Text = "B2S DMD" diff --git a/b2sbackglassserver/b2sbackglassserver/Classes/B2SSettings.vb b/b2sbackglassserver/b2sbackglassserver/Classes/B2SSettings.vb index 234450a..962f2a6 100644 --- a/b2sbackglassserver/b2sbackglassserver/Classes/B2SSettings.vb +++ b/b2sbackglassserver/b2sbackglassserver/Classes/B2SSettings.vb @@ -256,13 +256,8 @@ Public Class B2SSettings Public Shared Function GetSettingFilename() As String If IO.File.Exists(settingsFilename) Then Return settingsFilename -#If B2S = "DLL" Then - ElseIf StartAsEXE And B2STableSettingsExtendedPath And IO.File.Exists(IO.Path.Combine(Application.StartupPath(), settingsFilename)) Then - Return IO.Path.Combine(Application.StartupPath(), settingsFilename) -#Else ElseIf B2STableSettingsExtendedPath And IO.File.Exists(IO.Path.Combine(Application.StartupPath(), settingsFilename)) Then Return IO.Path.Combine(Application.StartupPath(), settingsFilename) -#End If ElseIf B2STableSettingsExtendedPath And IO.File.Exists(IO.Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), settingsFilename)) Then Return IO.Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), settingsFilename) End If @@ -272,6 +267,7 @@ Public Class B2SSettings Public Shared Sub LoadGlobalAndTableSettings(xmlNode As Xml.XmlNode) If xmlNode.SelectSingleNode("DisableBuiltInEMReelSound") IsNot Nothing Then DisableBuiltInEMReelSound = (xmlNode.SelectSingleNode("DisableBuiltInEMReelSound").InnerText = "1") If xmlNode.SelectSingleNode("HideGrill") IsNot Nothing Then HideGrill = CInt(xmlNode.SelectSingleNode("HideGrill").InnerText) + If xmlNode.SelectSingleNode("HideB2SBackglass") IsNot Nothing Then HideB2SBackglass = (xmlNode.SelectSingleNode("HideB2SBackglass").InnerText = "1") If xmlNode.SelectSingleNode("HideB2SDMD") IsNot Nothing Then HideB2SDMD = (xmlNode.SelectSingleNode("HideB2SDMD").InnerText = "1") If xmlNode.SelectSingleNode("HideDMD") IsNot Nothing Then HideDMD = CInt(xmlNode.SelectSingleNode("HideDMD").InnerText) If xmlNode.SelectSingleNode("LampsBlackTurns") IsNot Nothing Then LampsSkipFrames = CInt(xmlNode.SelectSingleNode("LampsBlackTurns").InnerText) diff --git a/b2sbackglassserver/b2sbackglassserver/Classes/Processes.vb b/b2sbackglassserver/b2sbackglassserver/Classes/Processes.vb index 7dd0638..3aee7f9 100644 --- a/b2sbackglassserver/b2sbackglassserver/Classes/Processes.vb +++ b/b2sbackglassserver/b2sbackglassserver/Classes/Processes.vb @@ -34,8 +34,10 @@ Public Class Processes For Each proc As ProcInfo In windowlist If Not String.IsNullOrEmpty(proc.Name) Then If proc.Name.StartsWith("Visual Pinball - ", StringComparison.CurrentCultureIgnoreCase) Then + 'Visual Pinball - [Tom and Jerry (Original 2019) v 1.33] If String.IsNullOrEmpty(_tablename) Then _tablename = proc.Name.Substring(17) + '[Tom and Jerry (Original 2019) v 1.33]___ If _tablename.StartsWith("[") AndAlso Not _tablename.EndsWith("]") Then Dim i As Integer = _tablename.Length - 1 Dim found As Boolean = False @@ -48,10 +50,13 @@ Public Class Processes Loop If found Then _tablename = _tablename.Substring(0, i + 1) + '[Tom and Jerry (Original 2019) v 1.33] End If End If If _tablename.StartsWith("[") Then _tablename = _tablename.Substring(1) + 'Tom and Jerry (Original 2019) v 1.33] If _tablename.EndsWith("]") Then _tablename = _tablename.Substring(0, _tablename.Length - 1) + 'Tom and Jerry (Original 2019) v 1.33 If _tablename.EndsWith("*") Then _tablename = _tablename.Substring(0, _tablename.Length - 1) If _tablename.EndsWith(".vpt") Then _tablename = _tablename.Substring(0, _tablename.Length - 4) If _tablename.EndsWith("*") Then _tablename = _tablename.Substring(0, _tablename.Length - 1) diff --git a/b2sbackglassserver/b2sbackglassserver/Controls/B2SLEDBox.vb b/b2sbackglassserver/b2sbackglassserver/Controls/B2SLEDBox.vb index 2170d91..7d200db 100644 --- a/b2sbackglassserver/b2sbackglassserver/Controls/B2SLEDBox.vb +++ b/b2sbackglassserver/b2sbackglassserver/Controls/B2SLEDBox.vb @@ -106,7 +106,11 @@ Public Class B2SLEDBox Set(ByVal newvalue As Integer) If _Value <> newvalue OrElse refresh Then _Value = newvalue - Me.Refresh() + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If End If End Set End Property diff --git a/b2sbackglassserver/b2sbackglassserver/Controls/B2SPictureBox.vb b/b2sbackglassserver/b2sbackglassserver/Controls/B2SPictureBox.vb index 09efd9b..1b565b4 100644 --- a/b2sbackglassserver/b2sbackglassserver/Controls/B2SPictureBox.vb +++ b/b2sbackglassserver/b2sbackglassserver/Controls/B2SPictureBox.vb @@ -24,27 +24,17 @@ Public Class B2SPictureBox Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs) - ' rectangle area for painting - Dim rect As Rectangle = New Rectangle(0, 0, Me.Width - 1, Me.Height - 1) - - ' draw dashed frame - Dim pen As Pen = New Pen(Brushes.LightGray) - pen.DashPattern = New Single() {3.0F, 3.0F} - e.Graphics.DrawRectangle(pen, rect) - pen.Dispose() - - ' draw text - 'If Not String.IsNullOrEmpty(Me.Text) Then - ' TextRenderer.DrawText(e.Graphics, Me.Text, Me.Font, rect, Color.White, TextFormatFlags.WordBreak Or TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter) - 'End If + + 'e.Graphics.DrawImage(BackgroundImage, e.ClipRectangle) End Sub Public Sub New() + ' set some drawing styles Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True) 'Me.SetStyle(ControlStyles.ResizeRedraw Or ControlStyles.SupportsTransparentBackColor, True) - 'Me.DoubleBuffered = True - Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.DoubleBuffer, True) + Me.DoubleBuffered = True + Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True) ' backcolor needs to be transparent Me.BackColor = Color.Transparent diff --git a/b2sbackglassserver/b2sbackglassserver/Controls/B2SReelBox.vb b/b2sbackglassserver/b2sbackglassserver/Controls/B2SReelBox.vb index ad0bc2d..b580cc9 100644 --- a/b2sbackglassserver/b2sbackglassserver/Controls/B2SReelBox.vb +++ b/b2sbackglassserver/b2sbackglassserver/Controls/B2SReelBox.vb @@ -117,7 +117,11 @@ Public Class B2SReelBox If intermediates2go > 0 OrElse intermediates = -1 Then - Me.Refresh() + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If intermediates2go -= 1 Else @@ -143,8 +147,11 @@ Public Class B2SReelBox End If Catch End Try - Me.Refresh() - + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If intermediates2go -= 1 ElseIf intermediates2go = -1 Then intermediates2go -= 1 @@ -201,7 +208,11 @@ Public Class B2SReelBox If _Illuminated <> value Then _Illuminated = value intermediates2go = 0 - Me.Refresh() + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If End If End Set End Property @@ -215,7 +226,11 @@ Public Class B2SReelBox If _Value <> value OrElse refresh Then _Value = value reelindex = ConvertValue(_Value) - Me.Refresh() + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If End If End Set End Property @@ -236,7 +251,11 @@ Public Class B2SReelBox timer.Start() Else reelindex = ConvertText(_Text) - Me.Refresh() + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If End If End If End If diff --git a/b2sbackglassserver/b2sbackglassserver/Forms/formBackglass.vb b/b2sbackglassserver/b2sbackglassserver/Forms/formBackglass.vb index 45e50cf..9afc76a 100644 --- a/b2sbackglassserver/b2sbackglassserver/Forms/formBackglass.vb +++ b/b2sbackglassserver/b2sbackglassserver/Forms/formBackglass.vb @@ -1,4 +1,5 @@ Imports System.Drawing +Imports System.Drawing.Imaging Imports System.IO Imports System.Windows.Forms Imports Microsoft.Win32 @@ -18,17 +19,17 @@ Public Class formBackglass Private formSettings As formSettings = Nothing Private formMode As formMode = Nothing -#If B2S = "DLL" Then Private startupTimer As Timer = Nothing - Private snifferTimer As Timer = Nothing +#If B2S = "DLL" Then + + Private snifferTimer As Timer = Nothing Private snifferLamps As B2SSnifferPanel = Nothing Private snifferSolenoids As B2SSnifferPanel = Nothing Private snifferGIStrings As B2SSnifferPanel = Nothing Private chkSniffer As CheckBox = Nothing Private Const snifferTimerInterval As Integer = 311 #Else - Private timer As Timer = Nothing Private tableTimer As Timer = Nothing Private B2STimer As Timer = Nothing Private tableHandle As Integer = 0 @@ -58,7 +59,7 @@ Public Class formBackglass #Region "constructor and closing" -#If B2S = "DLL" Then + Public Sub New() InitializeComponent() @@ -70,16 +71,56 @@ Public Class formBackglass ' set key preview to allow some key action Me.KeyPreview = True - B2SScreen = New B2SScreen() +#If B2S = "EXE" Then + If My.Application.CommandLineArgs.Count > 0 Then + B2SData.TableFileName = My.Application.CommandLineArgs(0).ToString - ' load settings - B2SSettings.Load() + If B2SData.TableFileName.EndsWith(".directb2s") Then + B2SData.TableFileName = Path.GetFileNameWithoutExtension(B2SData.TableFileName) + B2SSettings.PureEXE = True + B2SSettings.GameName = String.Empty + B2SSettings.B2SName = String.Empty + Else + Using regkey As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\B2S") + B2SSettings.GameName = regkey.GetValue("B2SGameName", String.Empty) + B2SSettings.B2SName = regkey.GetValue("B2SB2SName", String.Empty) + End Using + End If + + If My.Application.CommandLineArgs.Count > 1 Then + If My.Application.CommandLineArgs(1).ToString = "1" Then + Me.TopMost = True + End If + End If + Else + MessageBox.Show("Please do not start the EXE this way.", My.Resources.AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error) + End + End If + + ' get the game name + 'B2SSettings.GameName = "bguns_l8" + 'B2SSettings.GameName = "closeenc" + 'B2SSettings.B2SName = "Baseball" + 'B2SSettings.B2SName = "Spider-Man(Stern 2007) alt full dmdON127" + 'B2SSettings.GameName = "smanve_101" + 'B2SData.TableFileName = "Spider-Man(Stern 2007) alt full dmdON127" + + ' Westworld 2016-18-11 - TableFileName is empty in some cases when launched via PinballX, we use GameName as alternativ + If String.IsNullOrEmpty(B2SData.TableFileName) Then + B2SData.TableFileName = B2SSettings.GameName + End If If B2SSettings.CPUAffinityMask > 0 Then Dim Proc = Process.GetCurrentProcess Proc.ProcessorAffinity = B2SSettings.CPUAffinityMask End If +#Else + Me.TopMost = True +#End If + B2SScreen = New B2SScreen() + ' load settings + B2SSettings.Load() ' get B2S xml and start Try LoadB2SData() @@ -87,7 +128,11 @@ Public Class formBackglass If B2SSettings.ShowStartupError Then MessageBox.Show(ex.Message, My.Resources.AppTitle, Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Error) End If +#If B2S = "DLL" Then Stop +#Else + End +#End If End Try ' initialize screen settings InitB2SScreen() @@ -104,6 +149,19 @@ Public Class formBackglass AddHandler startupTimer.Tick, AddressOf StartupTimer_Tick startupTimer.Start() +#If B2S = "EXE" Then + + ' create 'table is still running' timer + tableTimer = New Timer + tableTimer.Interval = 207 + AddHandler tableTimer.Tick, AddressOf TableTimer_Tick + + ' create B2S data timer + B2STimer = New Timer + B2STimer.Interval = 13 + AddHandler B2STimer.Tick, AddressOf B2STimer_Tick +#End If + ' create rotation timer rotateTimer = New Timer If rotateTimerInterval > 0 Then @@ -112,13 +170,12 @@ Public Class formBackglass AddHandler rotateTimer.Tick, AddressOf RotateTimer_Tick End Sub - +#If B2S = "DLL" Then Public Sub New(ByVal doNotLoadBackglassData As Boolean) InitializeComponent() ' set some styles - 'Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint, True) Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True) Me.DoubleBuffered = True @@ -172,147 +229,41 @@ Public Class formBackglass snifferTimer.Start() End Sub -#Else - Public Sub New() - - InitializeComponent() - - ' set some styles - Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True) - Me.DoubleBuffered = True - - ' set key peview to allow some key action - Me.KeyPreview = True - - ' mabye create the base registry key - If Registry.CurrentUser.OpenSubKey("Software\B2S") Is Nothing Then Registry.CurrentUser.CreateSubKey("Software\B2S") - If Registry.CurrentUser.OpenSubKey("Software\B2S\VPinMAME") Is Nothing Then Registry.CurrentUser.CreateSubKey("Software\B2S\VPinMAME") - - ' get the table - 'IO.Directory.SetCurrentDirectory("C:\Visual Pinball\Tables") - 'B2SData.TableFileName = "Big Guns (Williams 1987)_1.0" - 'B2SData.TableFileName = "ScaredStiff_FS_B2S_GI8" - 'B2SData.TableFileName = "ACDC_B2S" '"Baseball 1.0 FS" '"Elvira_and_the_Party_Monsters_VP91x_v1.2FS" '"Close_Encounters_FS" - 'B2SData.TableFileName = "Close_Encounters_FS" - 'B2SData.TableFileName = "Pinbot.uw.V1.02.1_JF_91x_BMPR_MOD_FS" - 'B2SData.TableFileName = "ScaredStiff_FS_B2S" - If My.Application.CommandLineArgs.Count > 0 Then - B2SData.TableFileName = My.Application.CommandLineArgs(0).ToString - - If B2SData.TableFileName.EndsWith(".directb2s") Then - B2SData.TableFileName = Path.GetFileNameWithoutExtension(B2SData.TableFileName) - B2SSettings.PureEXE = True - End If - - If My.Application.CommandLineArgs.Count > 1 Then - If My.Application.CommandLineArgs(1).ToString = "1" Then - Me.TopMost = True - End If - End If - Else - MessageBox.Show("Please do not start the EXE this way.", My.Resources.AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Error) - End - End If - - - ' get the game name - 'B2SSettings.GameName = "bguns_l8" - 'B2SSettings.GameName = "closeenc" - 'B2SSettings.B2SName = "Baseball" - 'B2SSettings.B2SName = "Spider-Man(Stern 2007) alt full dmdON127" - 'B2SSettings.GameName = "smanve_101" - 'B2SData.TableFileName = "Spider-Man(Stern 2007) alt full dmdON127" - - - Using regkey As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\B2S") - B2SSettings.GameName = regkey.GetValue("B2SGameName", String.Empty) - B2SSettings.B2SName = regkey.GetValue("B2SB2SName", String.Empty) - End Using - - ' Westworld 2016-18-11 - TableFileName is empty in some cases when launched via PinballX, we use GameName as alternativ - If String.IsNullOrEmpty(B2SData.TableFileName) Then - B2SData.TableFileName = B2SSettings.GameName - End If - B2SScreen = New B2SScreen() ' was started before Tablename was identified, so alternativ ScreenRes was failing - - - ' load settings - B2SSettings.Load() - - If B2SSettings.CPUAffinityMask > 0 Then - Dim Proc = Process.GetCurrentProcess - Proc.ProcessorAffinity = B2SSettings.CPUAffinityMask - End If - - ' get B2S xml and start - Try - LoadB2SData() - Catch ex As Exception - If B2SSettings.ShowStartupError Then - MessageBox.Show(ex.Message, My.Resources.AppTitle, Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Error) - End If - End - End Try - - ' initialize screen settings - InitB2SScreen() - - ' resize images - ResizeSomeImages() - - ' show snippits - ShowStartupSnippits() - - ' create 'image on' timer and start it - timer = New Timer() - timer.Interval = 2000 - AddHandler timer.Tick, AddressOf Timer_Tick - timer.Start() - - ' create 'table is still running' timer - tableTimer = New Timer - tableTimer.Interval = 207 - AddHandler tableTimer.Tick, AddressOf TableTimer_Tick - - ' create B2S data timer - B2STimer = New Timer - B2STimer.Interval = 13 - AddHandler B2STimer.Tick, AddressOf B2STimer_Tick - - ' create rotation timer - rotateTimer = New Timer - If rotateTimerInterval > 0 Then - rotateTimer.Interval = rotateTimerInterval - End If - AddHandler rotateTimer.Tick, AddressOf RotateTimer_Tick - - End Sub +#End If Private Sub formBackglass_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown +#If B2S = "EXE" Then If Not B2SSettings.FormToFront Then Me.SendToBack() End If - - - 'Me.TopMost = False - SetFocusToVPPlayer() +#Else + If Not B2SSettings.FormToFront Then + Me.SendToBack() + Else + Dim StoreTopMost As Boolean = Me.TopMost - End Sub + Me.TopMost = True + Me.BringToFront() + SetFocusToVPPlayer() + Me.TopMost = StoreTopMost + End If #End If + End Sub + Private Sub formBackglass_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing On Error Resume Next If rotateTimer IsNot Nothing Then rotateTimer.Stop() + If startupTimer IsNot Nothing Then startupTimer.Stop() + #If B2S = "DLL" Then ' stop all timers as DLL - If startupTimer IsNot Nothing Then startupTimer.Stop() If snifferTimer IsNot Nothing Then snifferTimer.Stop() #Else ' stop all timers as EXE - If timer IsNot Nothing Then timer.Stop() If tableTimer IsNot Nothing Then tableTimer.Stop() If B2STimer IsNot Nothing Then B2STimer.Stop() #End If @@ -402,23 +353,21 @@ Public Class formBackglass B2SStatistics.ClearAll() End Sub -#If B2S = "DLL" Then Private Sub formBackglass_Disposed(sender As Object, e As System.EventArgs) Handles Me.Disposed On Error Resume Next - If startupTimer IsNot Nothing Then RemoveHandler startupTimer.Tick, AddressOf StartupTimer_Tick If rotateTimer IsNot Nothing Then RemoveHandler rotateTimer.Tick, AddressOf RotateTimer_Tick - If snifferTimer IsNot Nothing Then RemoveHandler snifferTimer.Tick, AddressOf SnifferTimer_Tick - ' stop all timers as EXE - 'If timer IsNot Nothing Then RemoveHandler timer.Tick, AddressOf Timer_Tick - 'If tabletimer IsNot Nothing Then RemoveHandler tabletimer.Tick, AddressOf TableTimer_Tick - 'If B2STimer IsNot Nothing Then RemoveHandler B2STimer.Tick, AddressOf B2STimer_Tick - 'If rotateTimer IsNot Nothing Then RemoveHandler rotateTimer.Tick, AddressOf RotateTimer_Tick + If startupTimer IsNot Nothing Then RemoveHandler startupTimer.Tick, AddressOf StartupTimer_Tick +#If B2S = "DLL" Then + If snifferTimer IsNot Nothing Then RemoveHandler snifferTimer.Tick, AddressOf SnifferTimer_Tick +#Else + If tableTimer IsNot Nothing Then RemoveHandler tableTimer.Tick, AddressOf TableTimer_Tick + If B2STimer IsNot Nothing Then RemoveHandler B2STimer.Tick, AddressOf B2STimer_Tick +#End If End Sub -#End If #End Region #Region "painting" @@ -550,23 +499,12 @@ Public Class formBackglass snifferGIStrings.Invalidate() End Sub - +#End If #End Region #Region "some timer events" - Private Sub StartupTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) - - startupTimer.Stop() - - ' maybe show some 'startup on' images - ShowStartupImages() - - ' start autostarted animations - B2SAnimation.AutoStart() - - End Sub - +#If B2S = "DLL" Then Private Sub SnifferTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) If B2SStatistics.LogStatistics Then @@ -574,28 +512,33 @@ Public Class formBackglass End If End Sub -#Else - - Private Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs) +#End If + Private Sub StartupTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) - timer.Stop() + startupTimer.Stop() ' set focus to the VP player SetFocusToVPPlayer() + ' maybe show some 'startup on' images + ShowStartupImages() + ' start autostarted animations B2SAnimation.AutoStart() - ' start B2S data timer - B2STimer.Start() - ' set focus to the VP player SetFocusToVPPlayer() +#If B2S = "EXE" Then + ' start B2S data timer + B2STimer.Start() + ' start table check timer tableTimer.Start() - +#End If End Sub + +#If B2S = "EXE" Then Private Sub TableTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) If tableHandle <> 0 AndAlso Not IsWindow(tableHandle) Then @@ -606,14 +549,11 @@ Public Class formBackglass End If End Sub - Private Sub B2STimer_Tick() + Private Sub B2STimer_Tick(ByVal sender As Object, ByVal e As EventArgs) ' poll registry data PollingData() - ' show some 'startup on' images (one time) - ShowStartupImages() - End Sub #End If @@ -1250,9 +1190,8 @@ Public Class formBackglass Dim currentvalue As Integer = CInt(gistringsData.Substring(gistringid, 1)) If gistrings(gistringid) <> currentvalue Then If Not B2SData.UsedAnimationGIStringIDs.ContainsKey(gistringid) AndAlso Not B2SData.UsedRandomAnimationGIStringIDs.ContainsKey(gistringid) Then gistrings(gistringid) = currentvalue - If B2SData.UsedRomGIStringIDs.ContainsKey(gistringid) Then + If B2SData.UsedRomGIStringIDs.ContainsKey(gistringid) AndAlso B2SData.UsedRomGIStringIDs(gistringid) IsNot Nothing Then For Each picbox As B2SPictureBox In B2SData.UsedRomGIStringIDs(gistringid) - 'If picbox IsNot Nothing Then If picbox IsNot Nothing AndAlso (Not B2SData.UseIlluminationLocks OrElse String.IsNullOrEmpty(picbox.GroupName) OrElse Not B2SData.IlluminationLocks.ContainsKey(picbox.GroupName)) Then Dim visible As Boolean = (currentvalue > 4) If picbox.RomInverted Then visible = Not visible @@ -1718,7 +1657,13 @@ Public Class formBackglass B2SSettings.Save(, True) #End If Me.BackgroundImage = DarkImage - Me.Refresh() + + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() Me.Invalidate()) + Else + Me.Invalidate() + End If + ShowStartupImages() B2SAnimation.RestartAnimations() If formMode IsNot Nothing Then @@ -1746,12 +1691,11 @@ Public Class formBackglass Case B2SSettings.eImageFileType.GIF : imageformat = Imaging.ImageFormat.Gif : extension = ".gif" Case B2SSettings.eImageFileType.BMP : imageformat = Imaging.ImageFormat.Bmp : extension = ".bmp" End Select - Dim filename As String = IO.Path.Combine(B2SSettings.ScreenshotPath, IO.Path.GetFileNameWithoutExtension(B2SData.BackglassFileName) & extension) - B2SScreen.MakeScreenShot(filename, imageformat) + Dim screenshotFilename As String = IO.Path.Combine(B2SSettings.ScreenshotPath, IO.Path.GetFileNameWithoutExtension(B2SData.BackglassFileName) & extension) + B2SScreen.MakeScreenShot(screenshotFilename, imageformat) My.Computer.Audio.Play(My.Resources.camera1, AudioPlayMode.Background) End If -#If B2S = "DLL" Then -#Else +#If B2S = "EXE" Then ElseIf e.KeyCode = Keys.Escape Then ' stop the app @@ -1912,12 +1856,12 @@ Public Class formBackglass Private Sub LoadB2SData() Dim filename As String = B2SData.TableFileName & ".directb2s" - Dim shortfilename As String = B2SData.ShortFileName(filename) - Dim hyperpinfilename As String = String.Empty - Dim shorthyperpinfilename As String = String.Empty + Dim shortFilename As String = B2SData.ShortFileName(filename) & ".directb2s" + Dim hyperpinFilename As String = String.Empty + Dim shorthyperpinFilename As String = String.Empty ' check whether the table name can be found - If Not String.IsNullOrEmpty(B2SSettings.GameName) And Not IO.File.Exists(filename) AndAlso Not IO.File.Exists(shortfilename) Then + If Not String.IsNullOrEmpty(B2SSettings.GameName) And Not IO.File.Exists(filename) AndAlso Not IO.File.Exists(shortFilename) Then 'Westworld, check for gamename If IO.File.Exists(B2SSettings.GameName & ".directb2s") Then filename = B2SSettings.GameName & ".directb2s" @@ -1925,44 +1869,49 @@ Public Class formBackglass End If If Not B2SSettings.DisableFuzzyMatching Then - If Not IO.File.Exists(filename) AndAlso Not IO.File.Exists(shortfilename) Then + B2SScreen.debugLog.WriteLogEntry("FuzzyMatching") + If Not IO.File.Exists(filename) AndAlso Not IO.File.Exists(shortFilename) Then If B2SSettings.LocateHyperpinXMLFile() Then - hyperpinfilename = B2SSettings.HyperpinName & ".directb2s" - shorthyperpinfilename = B2SData.ShortFileName(hyperpinfilename) + hyperpinFilename = B2SSettings.HyperpinName & ".directb2s" + shorthyperpinFilename = B2SData.ShortFileName(hyperpinFilename) & ".directb2s" End If ' check whether the hyperpin description can be found - If Not IO.File.Exists(hyperpinfilename) AndAlso Not IO.File.Exists(shorthyperpinfilename) Then + If Not IO.File.Exists(hyperpinFilename) AndAlso Not IO.File.Exists(shorthyperpinFilename) Then If filename.Length >= 8 Then ' look for short name - B2SSettings.MatchingFileNames = IO.Directory.GetFiles(IO.Directory.GetCurrentDirectory(), filename.Substring(0, 6) & "*.directb2s") - If B2SSettings.MatchingFileNames Is Nothing OrElse Not IsArray(B2SSettings.MatchingFileNames) OrElse B2SSettings.MatchingFileNames.Length <= 0 Then - B2SSettings.MatchingFileNames = IO.Directory.GetFiles(IO.Directory.GetCurrentDirectory(), filename.Substring(0, 6).Replace(" ", "") & "*.directb2s") - End If + B2SSettings.MatchingFileNames = IO.Directory.GetFiles(IO.Directory.GetCurrentDirectory(), shortFilename.Replace(".directb2s", "*.directb2s")) + If B2SSettings.MatchingFileNames IsNot Nothing Then For i As Integer = 0 To B2SSettings.MatchingFileNames.Length - 1 Dim fileinfo As IO.FileInfo = New IO.FileInfo(B2SSettings.MatchingFileNames(i)) B2SSettings.MatchingFileNames(i) = fileinfo.Name Next + B2SScreen.debugLog.WriteLogEntry("FuzzyMatching Matching FileNames:" & String.Join(", ", B2SSettings.MatchingFileNames)) End If - shortfilename = String.Empty - For Each file As String In B2SSettings.MatchingFileNames - If String.IsNullOrEmpty(shortfilename) Then - shortfilename = file + shortFilename = String.Empty + For Each matchedFileName As String In B2SSettings.MatchingFileNames + If String.IsNullOrEmpty(shortFilename) Then + shortFilename = matchedFileName End If - If Not String.IsNullOrEmpty(B2SSettings.MatchingFileName) AndAlso file.Equals(B2SSettings.MatchingFileName, StringComparison.CurrentCultureIgnoreCase) Then - shortfilename = file + If Not String.IsNullOrEmpty(B2SSettings.MatchingFileName) AndAlso File.Equals(B2SSettings.MatchingFileName, StringComparison.CurrentCultureIgnoreCase) Then + shortFilename = matchedFileName Exit For End If Next + B2SScreen.debugLog.WriteLogEntry("FuzzyMatching Selected FileName:" & shortFilename) + End If End If + B2SScreen.debugLog.WriteLogEntry("FuzzyMatching END") + Else + B2SScreen.debugLog.WriteLogEntry("FuzzyMatching END - Found matching filename") End If End If - If Not IO.File.Exists(filename) AndAlso Not IO.File.Exists(shortfilename) AndAlso Not IO.File.Exists(hyperpinfilename) AndAlso Not IO.File.Exists(shorthyperpinfilename) Then + If Not IO.File.Exists(filename) AndAlso Not IO.File.Exists(shortFilename) AndAlso Not IO.File.Exists(hyperpinFilename) AndAlso Not IO.File.Exists(shorthyperpinFilename) Then Dim text As String = "File '" & IO.Path.Combine(IO.Directory.GetCurrentDirectory(), filename) - If Not String.IsNullOrEmpty(hyperpinfilename) AndAlso Not filename.Equals(hyperpinfilename, StringComparison.CurrentCultureIgnoreCase) Then - text &= " and file '" & IO.Path.Combine(IO.Directory.GetCurrentDirectory(), hyperpinfilename) & "'" + If Not String.IsNullOrEmpty(hyperpinFilename) AndAlso Not filename.Equals(hyperpinFilename, StringComparison.CurrentCultureIgnoreCase) Then + text &= " and file '" & IO.Path.Combine(IO.Directory.GetCurrentDirectory(), hyperpinFilename) & "'" End If text &= " not found. Please rename or download the matching directb2s backglass file." Throw New Exception(text) @@ -1971,12 +1920,12 @@ Public Class formBackglass Dim XML As Xml.XmlDocument = New Xml.XmlDocument If IO.File.Exists(filename) Then B2SData.BackglassFileName = filename - ElseIf IO.File.Exists(shortfilename) Then - B2SData.BackglassFileName = shortfilename - ElseIf IO.File.Exists(hyperpinfilename) Then - B2SData.BackglassFileName = hyperpinfilename - ElseIf IO.File.Exists(shorthyperpinfilename) Then - B2SData.BackglassFileName = shorthyperpinfilename + ElseIf IO.File.Exists(shortFilename) Then + B2SData.BackglassFileName = shortFilename + ElseIf IO.File.Exists(hyperpinFilename) Then + B2SData.BackglassFileName = hyperpinFilename + ElseIf IO.File.Exists(shorthyperpinFilename) Then + B2SData.BackglassFileName = shorthyperpinFilename End If ' maybe load XML file If Not String.IsNullOrEmpty(B2SData.BackglassFileName) Then @@ -1990,7 +1939,7 @@ Public Class formBackglass ' try to get into the file and read some XML If XML Is Nothing OrElse XML.SelectSingleNode("DirectB2SData") Is Nothing Then - Throw New Exception("File '" & filename & "' is not a valid directb2s backglass file.") + Throw New Exception("File '" & B2SData.BackglassFileName & "' is not a valid directb2s backglass file.") Else @@ -2965,18 +2914,14 @@ Public Class formBackglass End If Next End If -#If B2S = "DLL" Then - Me.TopMost = True - Me.BringToFront() - Me.TopMost = False -#Else + +#If B2S = "EXE" Then Using regkey As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\B2S", True) regkey.SetValue("B2SSetSwitch", If(animationpulseswitch, 1, 0), RegistryValueKind.DWord) End Using #End If End If - ' set info flags to dirty to load them #If B2S = "DLL" Then B2SData.IsInfoDirty = True @@ -3531,16 +3476,15 @@ Public Class formBackglass Return Drawing.Color.FromArgb(CInt(colorvalues(0)), CInt(colorvalues(1)), CInt(colorvalues(2))) End Function -#If B2S = "EXE" Then Private Sub SetFocusToVPPlayer() ' set focus to the VP player Dim proc As Processes = New Processes() SetForegroundWindow(proc.TableHandle) +#If B2S = "EXE" Then tableHandle = proc.TableHandle - - End Sub #End If + End Sub Private Function RandomStarter(ByVal top As Integer) As Integer diff --git a/b2sbackglassserver/b2sbackglassserver/Forms/formDMD.vb b/b2sbackglassserver/b2sbackglassserver/Forms/formDMD.vb index 11e8a41..179c24e 100644 --- a/b2sbackglassserver/b2sbackglassserver/Forms/formDMD.vb +++ b/b2sbackglassserver/b2sbackglassserver/Forms/formDMD.vb @@ -72,7 +72,6 @@ Public Class formDMD Private Sub formDMD_MouseClick(sender As Object, e As MouseEventArgs) Handles MyBase.MouseClick If e.Button = Windows.Forms.MouseButtons.Right Then B2SScreen.formBackglass.formBackglass_MouseClick(sender, e) - 'formBackglass.formBackglass_MouseClick(sender, e) End If End Sub diff --git a/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.Designer.vb b/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.Designer.vb index 3a48b05..2161c17 100644 --- a/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.Designer.vb +++ b/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.Designer.vb @@ -29,7 +29,6 @@ Partial Class formSettings Me.lowerPanel = New System.Windows.Forms.Panel() Me.btnCloseSettings = New System.Windows.Forms.Button() Me.btnSaveSettings = New System.Windows.Forms.Button() - Me.lblNonAvailableSettings = New System.Windows.Forms.Label() Me.btnEditScreenRes = New System.Windows.Forms.Button() Me.btnMore = New System.Windows.Forms.Button() Me.headerPanel = New System.Windows.Forms.Panel() @@ -134,7 +133,6 @@ Partial Class formSettings ' Me.lowerPanel.Controls.Add(Me.btnCloseSettings) Me.lowerPanel.Controls.Add(Me.btnSaveSettings) - Me.lowerPanel.Controls.Add(Me.lblNonAvailableSettings) Me.lowerPanel.Controls.Add(Me.btnEditScreenRes) Me.lowerPanel.Controls.Add(Me.btnMore) Me.lowerPanel.Dock = System.Windows.Forms.DockStyle.Bottom @@ -164,15 +162,6 @@ Partial Class formSettings Me.btnSaveSettings.Text = "Save settings" Me.btnSaveSettings.UseVisualStyleBackColor = True ' - 'lblNonAvailableSettings - ' - Me.lblNonAvailableSettings.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) - Me.lblNonAvailableSettings.Location = New System.Drawing.Point(229, 16) - Me.lblNonAvailableSettings.Name = "lblNonAvailableSettings" - Me.lblNonAvailableSettings.Size = New System.Drawing.Size(295, 13) - Me.lblNonAvailableSettings.TabIndex = 40 - Me.lblNonAvailableSettings.Text = "* all settings in Italic is only available when run in EXE mode!" - ' 'btnEditScreenRes ' Me.btnEditScreenRes.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles) @@ -312,7 +301,6 @@ Partial Class formSettings 'chkStartAsEXE ' Me.chkStartAsEXE.Appearance = System.Windows.Forms.Appearance.Button - Me.chkStartAsEXE.Enabled = True Me.chkStartAsEXE.Location = New System.Drawing.Point(6, 20) Me.chkStartAsEXE.Name = "chkStartAsEXE" Me.chkStartAsEXE.Size = New System.Drawing.Size(151, 21) @@ -324,7 +312,6 @@ Partial Class formSettings 'cmbDefaultStartMode ' Me.cmbDefaultStartMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList - Me.cmbDefaultStartMode.Enabled = True Me.cmbDefaultStartMode.FormattingEnabled = True Me.cmbDefaultStartMode.Items.AddRange(New Object() {"Standard", "In EXE"}) Me.cmbDefaultStartMode.Location = New System.Drawing.Point(242, 20) @@ -893,7 +880,6 @@ Partial Class formSettings Friend WithEvents btnEditScreenRes As Windows.Forms.Button Friend WithEvents lblBackground As Windows.Forms.Label Friend WithEvents cmbBackground As Windows.Forms.ComboBox - Friend WithEvents lblNonAvailableSettings As Windows.Forms.Label Friend WithEvents B2SLogoToolTip As Windows.Forms.ToolTip Friend WithEvents lowerPanel As Windows.Forms.Panel Friend WithEvents headerPanel As Windows.Forms.Panel diff --git a/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.vb b/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.vb index 47d4d69..9f017d0 100644 --- a/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.vb +++ b/b2sbackglassserver/b2sbackglassserver/Forms/formSettings.vb @@ -37,11 +37,9 @@ Public Class formSettings Return Name + If(SlowDown = 1, "", " (" & If(SlowDown = 0, "Off", SlowDown.ToString & "x") & ")") End Function End Class -#If B2S = "DLL" Then + Private Sub formSettings_Load(sender As System.Object, e As System.EventArgs) Handles Me.Load -#Else - Private Sub formSettings_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load -#End If + formSettingsMore = New formSettingsMore(Me, formBackglass) ' load data @@ -120,8 +118,8 @@ Public Class formSettings ' maybe show matching file names combo box If B2SSettings.MatchingFileNames IsNot Nothing AndAlso B2SSettings.MatchingFileNames.Length >= 2 Then cmbMatchingFileNames.Items.Clear() - For Each filename As String In B2SSettings.MatchingFileNames - cmbMatchingFileNames.Items.Add(filename) + For Each matchedFilename As String In B2SSettings.MatchingFileNames + cmbMatchingFileNames.Items.Add(matchedFilename) Next If Not String.IsNullOrEmpty(B2SSettings.MatchingFileName) Then cmbMatchingFileNames.Text = B2SSettings.MatchingFileName @@ -157,11 +155,8 @@ Public Class formSettings TimerOpacity.Start() End Sub -#If B2S = "DLL" Then + Private Sub formSettings_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp -#Else - Private Sub formSettings_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp -#End If If e.KeyCode = Keys.Escape OrElse e.KeyCode = Keys.S Then btnCloseSettings.PerformClick() End If @@ -227,8 +222,16 @@ Public Class formSettings isSettingsScreenDirty = True B2SSettings.CurrentDualMode = cmbMode.SelectedIndex + 1 If formBackglass IsNot Nothing Then - formBackglass.BackgroundImage = formBackglass.DarkImage - formBackglass.Refresh() + If Me.InvokeRequired Then + Me.BeginInvoke(Sub() + formBackglass.BackgroundImage = formBackglass.DarkImage + formBackglass.Invalidate() + End Sub + ) + Else + formBackglass.BackgroundImage = formBackglass.DarkImage + formBackglass.Invalidate() + End If End If B2SAnimation.RestartAnimations() End Sub @@ -527,6 +530,15 @@ Public Class formSettings End Sub Private Sub B2SLogo_Click(sender As Object, e As EventArgs) Handles B2SLogo.Click - B2SLogoToolTip.SetToolTip(B2SLogo, "Settings: " & B2SSettings.SettingFilePath & vbCrLf & "ScreenRes: " & B2SSettings.LoadedResFilePath & vbCrLf & "PluginPath: " & B2SSettings.PluginsFilePath) + Dim openForms As String = "" + For Each frm As Form In Application.OpenForms + openForms = openForms & " " & frm.Text & vbCrLf + Next + + Dim ToolTip As String = "Settings: " & B2SSettings.SettingFilePath & vbCrLf & vbCrLf & "ScreenRes: " & B2SSettings.LoadedResFilePath & + vbCrLf & vbCrLf & "OpenForms: " & openForms + 'vbCrLf & "PluginPath: " & B2SSettings.PluginsFilePath & + B2SLogoToolTip.SetToolTip(B2SLogo, ToolTip) End Sub + End Class \ No newline at end of file diff --git a/b2sbackglassserver/b2sbackglassserver/My Project/AssemblyInfo.vb b/b2sbackglassserver/b2sbackglassserver/My Project/AssemblyInfo.vb index 0c323e5..43b3336 100644 --- a/b2sbackglassserver/b2sbackglassserver/My Project/AssemblyInfo.vb +++ b/b2sbackglassserver/b2sbackglassserver/My Project/AssemblyInfo.vb @@ -1,5 +1,4 @@ -Imports System -Imports System.Reflection +Imports System.Reflection Imports System.Runtime.InteropServices ' General Information about an assembly is controlled through the following diff --git a/b2sbackglassserver/b2sbackglassserver/Plugin/PluginWindow.vb b/b2sbackglassserver/b2sbackglassserver/Plugin/PluginWindow.vb index 82d7c96..393a363 100644 --- a/b2sbackglassserver/b2sbackglassserver/Plugin/PluginWindow.vb +++ b/b2sbackglassserver/b2sbackglassserver/Plugin/PluginWindow.vb @@ -17,7 +17,7 @@ Public Class PluginWindow Private Set(ByVal value As PluginList) _Plugins = value Me.PluginDataGrid.DataSource = value - Me.PluginDataGrid.Refresh() + Me.PluginDataGrid.Invalidate() End Set End Property diff --git a/b2sbackglassserver/b2sbackglassserver/Server.vb b/b2sbackglassserver/b2sbackglassserver/Server.vb index 242b461..7a15852 100644 --- a/b2sbackglassserver/b2sbackglassserver/Server.vb +++ b/b2sbackglassserver/b2sbackglassserver/Server.vb @@ -1,17 +1,19 @@ -Imports System -Imports System.Text +Imports System.Text Imports System.Runtime.InteropServices Imports Microsoft.Win32 -Imports System.Linq.Expressions Imports System.Drawing -Imports System.Reflection -Imports System.Runtime.InteropServices.WindowsRuntime +Imports System.Threading +Imports System.Windows.Forms Public Class Server Implements IDisposable + Private Shared thread As Thread + Private Shared threadContext As SynchronizationContext = Nothing + Public threadReady As Boolean = False + Private Declare Function IsWindow Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, Msg As UInteger, wParam As Integer, lParam As Integer) As Integer Public Const WM_SYSCOMMAND As Integer = &H112 @@ -94,7 +96,29 @@ Public Class Server #Region "constructor and end timer" Public Sub New() + ' Create new STA thread for this dll to run in, if the thread is already running then don't start another + ' However if the thread is running, we need to stop the application from running, and then restart it by running StartThread again + If thread IsNot Nothing Then + ' stop the application from running + Application.Exit() + End If + + thread = New Thread(AddressOf StartThread) + thread.SetApartmentState(ApartmentState.STA) + thread.Name = "B2SThread" + thread.Start() + ' Dont return until the thread is ready, by checking the threadReady variable + Do While Not threadReady + Thread.Sleep(100) + Loop + End Sub + + Private Sub StartThread() + ' Create a syncronization context for the thread + SynchronizationContext.SetSynchronizationContext(New WindowsFormsSynchronizationContext()) + ' Store the context for later use + threadContext = SynchronizationContext.Current ' maybe create the base registry key If Registry.CurrentUser.OpenSubKey("Software\B2S") Is Nothing Then Registry.CurrentUser.CreateSubKey("Software\B2S") If Registry.CurrentUser.OpenSubKey("Software\B2S\VPinMAME") Is Nothing Then Registry.CurrentUser.CreateSubKey("Software\B2S\VPinMAME") @@ -105,7 +129,6 @@ Public Class Server regkey.DeleteValue("B2SB2SName", False) End Using - ' maybe prepare plugins B2SSettings.Load(, True) ' prepare error log @@ -114,7 +137,6 @@ Public Class Server .IsLogOn = B2SSettings.B2SDebugLog } - errorlog.IsLogOn = B2SSettings.B2SDebugLog If B2SSettings.ArePluginsOn Then B2SSettings.PluginHost = New PluginHost(True) End If @@ -127,6 +149,10 @@ Public Class Server AddHandler timer.Tick, AddressOf Timer_Tick timer.Interval = 37 + ' set the thread ready flag + threadReady = True + + Application.Run() End Sub Private Sub Timer_Tick() @@ -136,6 +162,7 @@ Public Class Server If tableHandle <> 0 AndAlso Not IsWindow(tableHandle) Then Try + timer.Stop() Me.Stop() Finally Me.Dispose() @@ -245,8 +272,7 @@ Public Class Server End If Catch ex As Exception - Dim st As New StackTrace(ex, True) - errorlog.WriteLogEntry(DateTime.Now & "Line: " & st.GetFrame(0).GetMethod().Name & " : " & st.GetFrame(0).GetFileLineNumber().ToString & " : " & ex.Message) + errorlog.WriteLogEntry(DateTime.Now & ex.Message & vbNewLine & ex.StackTrace) Throw ex End Try @@ -274,7 +300,7 @@ Public Class Server End Get End Property - Public ReadOnly Property B2SServerBuild() As Double + Public ReadOnly Property B2SBuildVersion() As Double Get Return CInt(B2SVersionInfo.B2S_VERSION_MAJOR) * 10000 + CInt(B2SVersionInfo.B2S_VERSION_MINOR) * 100 + @@ -393,7 +419,23 @@ Public Class Server End Get End Property + Public ReadOnly Property VPMBuildVersion() As String + Get + Try + Return VPinMAME.FullVersion + Catch ex As Exception + Return VPinMAME.Version + End Try + End Get + End Property + + Public Sub Run(Optional ByVal handle As Object = 0) + 'Make sure this is run on threadContext thread + If SynchronizationContext.Current IsNot threadContext Then + threadContext.Send(New SendOrPostCallback(AddressOf Run), handle) + Return + End If ' startup tableHandle = CInt(handle) @@ -429,6 +471,17 @@ Public Class Server Public Sub [Stop]() + Try + If SynchronizationContext.Current IsNot threadContext Then + threadContext.Send(New SendOrPostCallback(AddressOf [Stop]), Nothing) + Return + End If + + Catch ex As Exception + 'If Exception is InvalidAsynchronousStateException then the thread is already stopped, so we can ignore it and return + Return + End Try + Try Try timer.Stop() @@ -615,97 +668,75 @@ Public Class Server Private statelogChangedGIStrings As Log = New Log("GIStringsState") Private statelogChangedLEDs As Log = New Log("LEDState") - 'Private timelogChangedLamps As Log = New Log("Lamps") - 'Private timelogChangedSolenoids As Log = New Log("Solenoids") - - 'Private statChangedLamps As Statistics = New Statistics(timelogChangedLamps) - 'Private statChangedSolenoids As Statistics = New Statistics(timelogChangedSolenoids) - Public ReadOnly Property ChangedLamps() As Object Get + isChangedLampsCalled = True + Dim chg As Object = VPinMAME.ChangedLamps() Try - isChangedLampsCalled = True - Dim chg As Object = VPinMAME.ChangedLamps() If B2SData.GetLampsData() Then - 'If B2SData.IsBackglassRunning AndAlso - ' (B2SData.IsBackglassStartedAsEXE OrElse B2SData.UseRomLamps OrElse B2SData.UseAnimationLamps OrElse B2SSettings.IsLampsStateLogOn OrElse B2SData.TestMode OrElse B2SStatistics.LogStatistics) AndAlso - ' Not B2SSettings.AllOff AndAlso Not B2SSettings.LampsOff Then CheckLamps(DirectCast(chg, Object(,))) End If If B2SSettings.ArePluginsOn AndAlso B2SSettings.PluginHost.Plugins.Count > 0 Then B2SSettings.PluginHost.DataReceive(Convert.ToChar("L"), chg) End If - Return chg Catch ex As Exception errorlog.WriteLogEntry(DateTime.Now & ": ChangedLamps ('" & ex.Message & "')") - Return Nothing End Try + Return chg End Get End Property Public ReadOnly Property ChangedSolenoids() As Object Get + isChangedSolenoidsCalled = True + Dim chg As Object = VPinMAME.ChangedSolenoids() Try - isChangedSolenoidsCalled = True - Dim chg As Object = VPinMAME.ChangedSolenoids() If B2SData.GetSolenoidsData() Then - 'If B2SData.IsBackglassRunning AndAlso - ' (B2SData.IsBackglassStartedAsEXE OrElse B2SData.UseRomSolenoids OrElse B2SData.UseAnimationSolenoids OrElse B2SSettings.IsSolenoidsStateLogOn OrElse B2SData.TestMode OrElse B2SStatistics.LogStatistics) AndAlso - ' Not B2SSettings.AllOff AndAlso Not B2SSettings.SolenoidsOff Then CheckSolenoids(DirectCast(chg, Object(,))) End If If B2SSettings.ArePluginsOn AndAlso B2SSettings.PluginHost.Plugins.Count > 0 Then B2SSettings.PluginHost.DataReceive(Convert.ToChar("S"), chg) End If - Return chg Catch ex As Exception errorlog.WriteLogEntry(DateTime.Now & ": ChangedSolenoids ('" & ex.Message & "')") - Return Nothing End Try + Return chg End Get End Property Public ReadOnly Property ChangedGIStrings() As Object Get + isChangedGIStringsCalled = True + Dim chg As Object = VPinMAME.ChangedGIStrings() Try - isChangedGIStringsCalled = True - Dim chg As Object = VPinMAME.ChangedGIStrings() If B2SData.GetGIStringsData() Then - 'If B2SData.IsBackglassRunning AndAlso - ' (B2SData.IsBackglassStartedAsEXE OrElse B2SData.UseRomGIStrings OrElse B2SData.UseAnimationGIStrings OrElse B2SSettings.IsGIStringsStateLogOn OrElse B2SData.TestMode OrElse B2SStatistics.LogStatistics) AndAlso - ' Not B2SSettings.AllOff AndAlso Not B2SSettings.GIStringsOff Then CheckGIStrings(DirectCast(chg, Object(,))) End If If B2SSettings.ArePluginsOn AndAlso B2SSettings.PluginHost.Plugins.Count > 0 Then B2SSettings.PluginHost.DataReceive(Convert.ToChar("G"), chg) End If - Return chg Catch ex As Exception errorlog.WriteLogEntry(DateTime.Now & ": ChangedGIStrings ('" & ex.Message & "')") - Return Nothing End Try + Return chg End Get End Property Public ReadOnly Property ChangedLEDs(ByVal mask2 As Object, ByVal mask1 As Object, Optional ByVal mask3 As Object = 0, Optional ByVal mask4 As Object = 0) As Object Get + isChangedLEDsCalled = True + Dim chg As Object = VPinMAME.ChangedLEDs(mask2, mask1, mask3, mask4) ' (&HFFFFFFFF, &HFFFFFFFF) Try - isChangedLEDsCalled = True - Dim chg As Object = VPinMAME.ChangedLEDs(mask2, mask1, mask3, mask4) ' (&HFFFFFFFF, &HFFFFFFFF) If B2SData.GetLEDsData() Then - 'If B2SData.IsBackglassRunning AndAlso - ' (B2SData.IsBackglassStartedAsEXE OrElse B2SData.UseLEDs OrElse B2SData.UseLEDDisplays OrElse B2SData.UseReels OrElse B2SSettings.IsLEDsStateLogOn) AndAlso - ' Not B2SSettings.AllOff AndAlso Not B2SSettings.LEDsOff Then CheckLEDs(DirectCast(chg, Object(,))) End If If B2SSettings.ArePluginsOn AndAlso B2SSettings.PluginHost.Plugins.Count > 0 Then B2SSettings.PluginHost.DataReceive(Convert.ToChar("D"), chg) End If - Return chg Catch ex As Exception errorlog.WriteLogEntry(DateTime.Now & ": ChangedLEDs ('" & ex.Message & "')") - Return Nothing End Try + Return chg End Get End Property @@ -959,13 +990,6 @@ Public Class Server statelogChangedSolenoids.IsLogOn = B2SSettings.IsSolenoidsStateLogOn - 'If statelogChangedSolenoids.IsLogOn Then - ' Static stopwatch As Stopwatch = New Stopwatch() - ' If Not stopwatch.IsRunning Then stopwatch.Start() - ' statelogChangedSolenoids.WriteLogEntry(DateTime.Now & " (" & stopwatch.ElapsedMilliseconds & ")") - ' stopwatch.Restart() - 'End If - If solenoids IsNot Nothing AndAlso IsArray(solenoids) Then If B2SData.TestMode Then @@ -2134,7 +2158,7 @@ Public Class Server Else - ' only do the lightning stuff if the group has a name + ' only do the lighting stuff if the group has a name If Not String.IsNullOrEmpty(groupname) AndAlso B2SData.IlluminationGroups.ContainsKey(groupname) Then ' get all matching picture boxes For Each picbox As B2SPictureBox In B2SData.IlluminationGroups(groupname) @@ -2167,13 +2191,18 @@ Public Class Server For Each picbox As B2SPictureBox In B2SData.UsedRomLampIDs(id) If picbox IsNot Nothing AndAlso (Not B2SData.UseIlluminationLocks OrElse String.IsNullOrEmpty(picbox.GroupName) OrElse Not B2SData.IlluminationLocks.ContainsKey(picbox.GroupName)) Then If picbox.Left <> xpos OrElse picbox.Top <> ypos Then - picbox.Left = xpos - picbox.Top = ypos - ' Using RectangleF as this is used in the DrawImage within OnPaint for picturBoxes. - picbox.RectangleF = New RectangleF(CInt(picbox.Left / rescaleBackglass.Width), CInt(picbox.Top / rescaleBackglass.Height), picbox.RectangleF.Width, picbox.RectangleF.Height) - 'Invalidating this object does not work, need to Invalidate the parent. - If picbox.Parent IsNot Nothing Then - picbox.Parent.Invalidate() + If (picbox.InvokeRequired) Then + picbox.BeginInvoke(Sub() + picbox.Left = xpos + picbox.Top = ypos + picbox.RectangleF = New RectangleF(CInt(picbox.Left / rescaleBackglass.Width), CInt(picbox.Top / rescaleBackglass.Height), picbox.RectangleF.Width, picbox.RectangleF.Height) + If picbox.Parent IsNot Nothing Then picbox.Parent.Invalidate() + End Sub) + Else + picbox.Left = xpos + picbox.Top = ypos + picbox.RectangleF = New RectangleF(CInt(picbox.Left / rescaleBackglass.Width), CInt(picbox.Top / rescaleBackglass.Height), picbox.RectangleF.Width, picbox.RectangleF.Height) + If picbox.Parent IsNot Nothing Then picbox.Parent.Invalidate() End If End If End If