-
1 Attachment(s)
DirectX 2D Tutorials For VB5/VB6/VB.NET
I have completed 19 tutorials so far in DirectX8 for 2D graphics. This should help get you started in the world of DirectX. Here are the tutorials I covered so far, by order of difficulty:
- First Windowed DirectX8 Application
- First Fullscreen DirectX8 Application
- Windowed & Fullscreen Initialization Together
- 2D Polygon Drawing
- Vertex Colors
- Vertex Buffers
- Drawing Text
- Triangle Rendering Formats
- Scaling Compensation
- Texture Mapping
- Texture Mapping With Colored Vertices
- Transparency
- Alphablending
- Gamma Correction
- Rotation
- Animation
- Advanced Animation
- Time Based Animation
- Tile Engine
And here are some other tutorials I have not covered yet that will soon be here:
- Quadtrees
- Time Based Movement
- Scrolling Backgrounds
- Scrolling Textures
- Texture Coordinates
- Hardware Enumeration
- Isometric Tile Engine
- Fade In/Out
- Sprite Layers
- Animation States
- Clipping (It's in the Tile Engine but needs to be on its own)
- Scaling
- Filling Modes
- Multitexturing
- Map Editor (For Tile Engine)
- Custom Size Primary Surface
- Light Mapping
- Particles
- Bounding Box Collision Detection
- Bounding Sphere Collision Detection
- Bounding Ellipse Collision Detection
- Polygonal Region Collision Detection
- Rendering Within Textures
- Index Buffers
- Hardware Antialiasing
- Multiple Viewports
- Sprite Class
- Changing Screen Resolution
- Snap Shots
- Mouse Selection
- Custom Mouse Icon
- Triple Buffering
- Custom Graphical Text
- Rotation Using Matrices
- Time Based Rotation
- Texture Pooling
- Accessing Texture Memory
- ...and more!
Enjoy this wonderful learning experience. Comments, suggestions, and optimizations if any, please.
Note: These will probably not work on all video cards. But I can give you a hand on trying to make them compatible somehow. Let me know which tutorial isn't working for ya.
[EDIT] Update: All default resolutions have been changed from 640x480x32 to 800x600x16. Thanks Andrew G. ;)
-
1 Attachment(s)
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I'm now making a DirectX9 tutorial for VB.NET as well. Got only one tutorial done, and it looks very similar to VB6's. Ignor the massive word. It isn't massive just yet. ;)
Be sure you have the DirectX9 runtime files in your computer, so the program can run. If you don't have it, you can find them here:
DirectX 9.0c Runtime Files
After it has installed and unpacked the files, you must also run mdxredist.msi. When you are finished, the files you need to reference will be located in C:\WINDOWS\Microsoft.NET\Managed DX\v9.02.2904\.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
please help i get an error like this
runtime error - 2005530518
automation error
am using the first tutorial
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Quote:
Originally Posted by Jacob Roman
I'm now making a DirectX9 tutorial for VB.NET as well.
I am now your dedicated fan... ;) :D
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Jacob
How ofter to you reckon you will post a new tutorial?
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Well I don't have a computer just yet to even work on it, so it's gonna be awhile.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
it is only for vb6??
any tutorial for vb.net 2005??? thank you. :)
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I have both up there (look at post #2 ;) ), but only one VB.Net tutorial unfortunately since I have no computer to make em on.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Hi people,
Anyone knows a method to do use Directx9 on vb.net o WINDOWED mode?
If anyone knows plz send me a mail : paulo@7soft.info
Thx for all. :wave:
God bless you!
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
In short (Code from site at first link below, riemers.net)
VB Code:
Public Class Form1
Private device As Direct3D.Device
Public Sub Initialize()
Dim present As PresentParameters = New PresentParameters
present.Windowed = True 'we?ll draw on a window
present.SwapEffect = SwapEffect.Discard 'discuss later
device = New Direct3D.Device(0, DeviceType.Hardware, Me, CreateFlags.SoftwareVertexProcessing, present)
End Sub
End Class
But for more information try these
http://www.riemers.net/eng/Tutorials...t_triangle.php
http://gpwiki.org/index.php/DirectX:...Initialization
http://www.euclideanspace.com/softwa...sics/index.htm
http://gpwiki.org/index.php/DirectX
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I'm working on VB.NET tutorials since I now have a computer to make them on. ;)
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Excellent, I look forward to it.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Can you make a Tutorial for DX 8 for VB6 that would allow someone to draw Isometric tile engine.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I've been using the VB6 examples and I have a question. I’ve tried loading .pngs into the sample projects but it doesn’t draw properly. How can you draw images like .pngs properly (i.e. an image with a shadow), with alphablending?
-
1 Attachment(s)
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I recreated it years later but could not upload it into my tutorial cause I was banned at the time but the biggest change I made was this:
Code:
'Right here will alphablend the polygon
Direct3D_Device.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
Direct3D_Device.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
Direct3D_Device.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE
Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE
Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE
Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE
Direct3D_Device.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
Direct3D_Device.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
Direct3D_Device.SetRenderState D3DRS_BLENDOP, D3DBLENDOP_ADD
This new code allows you to mess with the alpha values of the polygons to make it as see thru and transparent as you see fit, even produce special effects such as fading away like a ghost!
Code:
Private Sub Create_Polygon()
Vertex_List(0) = Create_TLVertex(0, 0, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 0, 0)
Vertex_List(1) = Create_TLVertex(100, 0, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 1, 0)
Vertex_List(2) = Create_TLVertex(0, 100, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 0, 1)
Vertex_List(3) = Create_TLVertex(100, 100, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 1, 1)
End Sub
Here is my new improved project, and I'm using png here as well:
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
The example works fine, now I can do what I was trying to do. Thanks so much for your help!!
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I have two other questions. In the rotation example you rotated the picture nicely but it wasn't antialiased. How can I antialias a rotated image? I was also wondering if it's possible to move the camera position. I've been moving my polygons around like you demonstrated in the tiling engine. Could I instead move the camera? Thanks for answering my questions, I'm quite new to DirectX.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Antialiasing I haven't messed with in awhile. I'll see what I can find on that.
I recreated a much much better tile engine years later that I'm currently using to design my RPG game I'm working on which is pretty much World of Warcraft in 2D. You can download it here and it comes with a sample map I called a.map but you have to manually load it in the menu after running my program. Source code only. Use the left mouse button to drag the camera around the main map, tile tool bar, and collision bar. Use the right mouse button to place tiles and choose which tile you wanna use. By default there are only 2 tiles to choose from. You can go up in the menu and literally add any image at any size and it'll automatically shrink it down to 16x16. Later stages of this program I plan to have animated tiles, fog as well as other special effects, other tile sizes, ability to put sprites origin anywhere on the map, and other things that may come to mind:
Map Editor.zip 128 KB
And my incomplete game where its used (source code included). It's got a killer intro video. Use left mouse click to skip through it and even to start the game. After the game passes the loading bar screen, use W, S, A, D to move him around, and left mouse button to move the camera. Left mouse and right mouse simutaniously to have the camera come back. Prt Sc button to shoot snapshots. And Escape to exit. He currently only auto attacks. The sword buttons useless atm till I code in certain rules. If you approach the monsters aggro radius, he will attack you. Stay within melee range to attack back. One room has invisible walls as a maze. Another has hidden lava underneath foreground tiles you need to avoid. And another has a checker tile with reflection. You can even earn experience and level up. It's still in its early stages but its getting there:
Bosskillers (New).zip 32 MB
http://www.vbforums.com/attachment.p...1&d=1319869928
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
So then there's no way of moving the camera? I looked at the tiling engine but kindof got lost in the code.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
The Map.Position is the camera. The Map Editor where it says Map.Position.X = Map.Position.X +/- Speed and Map.Position.Y = Map.Position.Y +/- Speed over in the sub routing Control which is actually Keyboard controls. It's coded so well that you can literally make a map 5000 tiles x 5000 tiles (which is 25000000 tiles in size) or even bigger if you want and it'll never slow down. Note that I said tiles not pixels XD. It's designed so you can create massive size worlds just like World of Warcraft has. With the mouse it's this code:
vb Code:
Private Sub picMapgrid_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = 1 Then
Left_Mouse_Held = True
Initial_Mouse_Position.X = Mouse_Cursor.X
Initial_Mouse_Position.Y = Mouse_Cursor.Y
Initial_Map_Position.X = Map.Position.X
Initial_Map_Position.Y = Map.Position.Y
End If
End Sub
Private Sub picMapgrid_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Mouse_Cursor.X = X
Mouse_Cursor.Y = Y
Old_Mouse_Coordinates.X = Mouse_Coordinates.X
Old_Mouse_Coordinates.Y = Mouse_Coordinates.Y
Mouse_Coordinates.X = Int((Mouse_Cursor.X - Map.Position.X) / (TILE_WIDTH))
Mouse_Coordinates.Y = Int((Mouse_Cursor.Y - Map.Position.Y) / (TILE_HEIGHT))
If Mouse_Coordinates.X <= 0 Then Mouse_Coordinates.X = 0
If Mouse_Coordinates.Y <= 0 Then Mouse_Coordinates.Y = 0
If Mouse_Coordinates.X >= Map.Width - 1 Then Mouse_Coordinates.X = Map.Width - 1
If Mouse_Coordinates.Y >= Map.Height - 1 Then Mouse_Coordinates.Y = Map.Height - 1
If Left_Mouse_Held = True And Right_Mouse_Held = False Then
Map.Map_Vector.X = Initial_Map_Position.X + Mouse_Cursor.X - Initial_Mouse_Position.X
Map.Map_Vector.Y = Initial_Map_Position.Y + Mouse_Cursor.Y - Initial_Mouse_Position.Y
Map.Position.X = Map.Map_Vector.X
Map.Position.Y = Map.Map_Vector.Y
End If
End Sub
As for Bosskillers how did it work on your comp? I'm curious. With bosskillers I used no vb controls. Just pure directX but you can find the mouse stuff over in modMain's Mouse_Controls and Keyboard_Controls as well. Yeah you are probably gonna need both projects to get a better understanding. The bosskillers project is more organized modularwise while with the map editor I crammed everything into one form. Didn't organize it yet.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Ok, that's a nice setup you've got for your editor but it didn't answer my question. In the editor you're taking three factors, Xoffset, Yoffset and Zoomlevel into acount and are making the tile positions off of those. I'm wondering if all that work could be saved by moving the camera (not like i'm lazy or don't know how to do it, it's just that the other would be more convenient). For example instead of moving a box from 5,2 to 6,3 just move the camera from 0,0 to 1,1. I found where people use this to move the camera:
DX.ViewMatrix matView, Camera.FromPos, Camera.ToPos, MakeVector(0, 1, 0), 0
Device.SetTransform D3DTRANSFORMSTATE_VIEW, matView
but I can't get it to work. Is it different with 2d?
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
That camera thing is for 3D. So yes it's different. I only added the zoom factor in the editor so you can see what the heck you're doing or to see the entire world you created in one sitting. However if done correctly you can make the project 3D and treat it like 2D as another method.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Does Bosskillers work ok on your comp? O.o
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I downloaded it and got it going in the IDE. It seemed to load file but I ended to program. Sorry man, I'm not going to play a game which has a loading picture like yours has. I'm pretty sure that it would work file though because there were no problems.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Well at least it runs alright lol. Anyways you're welcome and goodluck! That bosskillers game and map editor may have some useful things you might be able to use within your programs. :)
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Just curious, have you gotten anywhere with antialiasing?
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Yes from DirectX4VB over at tip #2 in the quick snippets where it says:
vb Code:
'//These lines replace the relevant lines in the D3DPRESENT_PARAMETERS used during
'//device creation...
D3DWindow.SwapEffect = D3DSWAPEFFECT_DISCARD
D3DWindow.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES
'//Set this render state after device creation, all subsequent rendering will be anti-aliased.
D3DDevice.SetRenderState D3DRS_MULTISAMPLE_ANTIALIAS, 1
'//To Check for FSAA support:
Public Function CheckForFSAA(adapter As Byte, DispModeFormat As CONST_D3DFORMAT) As Boolean
'//0. Any variables
Dim DX As New DirectX8
Dim D3D As Direct3D8
'//1. Get the data
Set D3D = DX.Direct3DCreate
If D3D.CheckDeviceMultiSampleType(adapter - 1, D3DDEVTYPE_HAL, DispModeFormat, False, _
D3DMULTISAMPLE_2_SAMPLES) >= 0 Then
CheckForFSAA = True
Exit Function
Else
CheckForFSAA = False
Exit Function
End If
End Function
But for some reason it doesn't work in 2D even in fullscreen. Even after changing the D3DMULTISAMPLE_2_SAMPLES to other values I still get false on everything. The only time I seen it work is in my 3D apps. Maybe it depends on the graphics card, but I paid $2200 for an ASUS G73J gaming laptop fully customized with 8 gigs of ram, a special i7 processor which is a tad better than the original i7, ATI Mobility Radeon HD 5870 graphics card, Windows 7 Pro etc. So theres really no reason why it shouldnt work on mine but it didn't. Maybe it supports it with DX9 - DX11 since it's a newer comp who knows.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
I tried it on my pc and it didn't work either :(.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
There's another basic question which i'd like to ask you. How do you draw lines?
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Try my sub routines I created:
vb Code:
Public Sub Draw_Pixel(ByVal X As Single, ByVal Y As Single, ByVal Color As Long)
Direct3D_Device.SetRenderState D3DRS_FILLMODE, D3DFILL_WIREFRAME
Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, True
Vert_List(0) = Create_TLVertex(X, Y, 0, 1, Color, 0, 0, 0)
Direct3D_Device.SetTexture 0, Nothing
Direct3D_Device.DrawPrimitiveUP D3DPT_POINTLIST, 2, Vert_List(0), Len(Vert_List(0))
Direct3D_Device.SetRenderState D3DRS_FILLMODE, D3DFILL_SOLID
End Sub
Public Sub Draw_Line(ByVal X1 As Single, ByVal Y1 As Single, ByVal X2 As Single, ByVal Y2 As Single, ByVal Color As Long)
Direct3D_Device.SetRenderState D3DRS_FILLMODE, D3DFILL_WIREFRAME
Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, True
Vert_List(0) = Create_TLVertex(X1, Y1, 0, 1, Color, 0, 0, 0)
Vert_List(1) = Create_TLVertex(X2, Y2, 0, 1, Color, 0, 1, 0)
Direct3D_Device.SetTexture 0, Nothing
Direct3D_Device.DrawPrimitiveUP D3DPT_LINESTRIP, 2, Vert_List(0), Len(Vert_List(0))
Direct3D_Device.SetRenderState D3DRS_FILLMODE, D3DFILL_SOLID
End Sub
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Ok, I had a problem when using the line. It's drawing kindof funny. I popped the code into the project and inserted "Dim Vert_List(1) As TLVERTEX" to fix the error. For some reason it's always wanting to draw from 0,0 to wherever your points are.
Code:
Draw_Line 50, 50, 100, 50, D3DColorRGBA(255, 0, 0, 0)
Result is two lines - one from 0, 0 to 100, 50 and another from 100, 50 to 50, 50.
I also tried the Draw_Pixel sub routine and it worked fine.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Hmmmm weird. It works fine on my comp. And I also have Vert_List(1) as TLVERTEX and this
Code:
'My Type
Public Type TLVERTEX
X As Single
Y As Single
Z As Single
RHW As Single
Color As Long
Specular As Long
TU As Single
TV As Single
End Type
'My TLVERTEX constant:
Public Const FVF_TLVERTEX As Long = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR
'My Setup
Direct3D_Device.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
Direct3D_Device.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
Direct3D_Device.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE
Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE
Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE
Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE
Direct3D_Device.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
Direct3D_Device.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
Direct3D_Device.SetRenderState D3DRS_BLENDOP, D3DBLENDOP_ADD
'My Create_TLVertex function
Public Function Create_TLVertex(ByVal X As Single, ByVal Y As Single, ByVal Z As Single, ByVal RHW As Single, ByVal Color As Long, ByVal Specular As Long, ByVal TU As Single, ByVal TV As Single) As TLVERTEX
Create_TLVertex.X = X
Create_TLVertex.Y = Y
Create_TLVertex.Z = Z
Create_TLVertex.RHW = RHW
Create_TLVertex.Color = Color
Create_TLVertex.Specular = Specular
Create_TLVertex.TU = TU
Create_TLVertex.TV = TV
End Function
'Where it draws
Draw_Line 0, 0, 500, 500, D3DColorRGBA(255, 255, 255, 255)
I get only one line. Even when its 50, 50, 100, 50. Also be sure your DX is set on 32 bit color mode, and that the D3DColorRGBA has the alpha set at 255 so it doesnt appear invisible.
[EDIT] I spotted this but in your Draw_Line sub change the primitive count to one:
Code:
Direct3D_Device.DrawPrimitiveUP D3DPT_LINESTRIP, 1, Vert_List(0), Len(Vert_List(0))
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Quote:
Originally Posted by
Jacob Roman
I spotted this but in your Draw_Line sub change the primitive count to one:
Code:
Direct3D_Device.DrawPrimitiveUP D3DPT_LINESTRIP, 1, Vert_List(0), Len(Vert_List(0))
That's just what is was! I made the simple change and i'm in buisness. Good stuff.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Awesome :bigyello: Also note to everyone else, I'm now currently REALLY THIS TIME working on a VB.NET DirectX9 tutorial. Sorry for the years of waiting. It's a personal life thing and I wasn't always programming. I had a major addiction to World of Warcraft, have a girlfriend now, was interested in other things. I recently just got back into programming. Sooooo I'll keep building the ultimate massive tutorial. I hope even afterwards I can work on a DX11 tutorial as well in VB.NET 2010
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Hi, i've got a question for windowed directx programs. When the game is fullscreen you don't need to worry about the size of the window at all, just the resolution. But when you're in a window the drawing will become completely distored. In my program i'd like to have it so that in the form's resize event the resolution is automatically being set to the new size. I've managed to acheive this by putting this inside the resize event.
Code:
Private Sub Form_Resize()
DirectX_Initialize
LoadTextures
End Sub
As you know reinitalizing directx and loading all the textures is a horrible way of doing it and is very slow. I'm wondering how to get the same result but a much much much faster way of doing it.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Don't reinitialize DirectX and reload the textures when you resize cause yea then it'll be slow. Instead what I personally do is have the window the same size as the screen resolution. The larger the screen res, the larger the window and the less pixelated it gets. Stretching the windows obviously gonna warp it no matter what. A maximized Windowed by default is the most ideal cause even at its largest its not pixelated and as the window is stretched itll shrink everything. However if still picky you could multiply your polys by a scalefactor like window_width/window_height but no matter what it's probably gonna not be perfect.
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
Ok, i got around it another way. I simply stopped the game loop in the resize event. As soon as the form is done resizing i reinitialize dx, load textures and start drawing again. In the the whole thing is now smooth and working.
Code:
Private Sized As Boolean
Private Sub Form_Resize()
If Sized = False Then: Sized = True
Me.Cls
End Sub
Private Sub Game_Loop()
Do Until Running = False
DoEvents
If Sized = True Then
Sized = False
DirectX_Initialize
LoadTextures
End If
Wait = False
Draw
Loop
End Sub
-
Re: DirectX 2D Tutorials For VB5/VB6/VB.NET
COMING SOON for 2012!!!
Massive DirectX9 tutorial for VB 2008 & VB 2010 (Currently 12 tutorials written so far and fully working on both languages)
And a more Revamped version of the Massive DirectX8 tutorial for VB6. Noticed that it has some problems such as using Form_Activate instead of Form_Load. Form_Load is a must cause Activate gets fired when the form has focus again! Also DoEvents must be at the end of the loops and I used End when I wasn't suppose to. Putting DoEvents at the end of the loop eliminates the dreaded Automation Error when exiting. As well as other improvements I plan on making.