26 Sep 2018 @ 1:38 PM 

I have a feeling this will be a topic I will cover at length repeatedly, and each time I will have learned things since my previous installments. The Topic? Programming Languages.

I find it quite astonishing just how much Polarizations and fanaticism we can find over what is essentially a syntax for describing operations to a computer. A quick google can reveal any number of arguments about languages, people telling you why Java sucks, people telling you why C# is crap, people telling you why Haskell is useless for real-world applications, people telling you that Delphi has no future, people telling you that there is no need for value semantics on variables, people telling you mutable state is evil, people telling you that Garbage collection is bad, people telling you that manual memory management is bad, etc. It’s an astonishing, never-ending trend. And it’s really quite fascinating.


I suppose the big question is- Why? Why do people argue about languages, language semantics, capabilities, and paradigms? This is a very difficult question to answer. I’ve always felt that polarization and fanaticism is far more likely to occur when you only know and understand one Programming Language. Of course, I cannot speak for everybody, only from experience. When I only knew one language “fluently”, I was quick to leap to it’s defense. It had massive issues that I can see now, looking back, but which I didn’t see at the time. I justified omissions as being things you didn’t need or could create yourself. I called features in newer languages ‘unnecessary’ and ‘weird’. So the question really is, who was I trying to prove this to? Was I arguing against those I was replying too- or was it all for my own benefit? I’m animate that the reasons for my own behaviour -and, to jump to a premature and biased conclusion, possibly those in which I see similar behaviour over other Languages- was the result of feeling trivialized by the attacks on the language I was using. Basically, it’s the result of programmers rating themselves based on what languages they know and use everyday. This is a natural- if erroneous – method of measuring one’s capabilities. I’ve always been a strong proponent that it isn’t the Programming Language that matters, but rather your understanding of Programming concepts, and how you apply them, as well as not subverting to the religious dogmas that generally surround a specific language design. (I’m trying very hard not to cite specific languages here). Programming Languages generally have set design goals. As a result, they typically encourage a style of programming- or even enforce it through artificial limitations. Additionally, those limitations that do exist (generally for design reasons) are worked around by competent programmers in the language. So when the topic enters the domain of their favourite language not supporting Feature X, they can quickly retort that “you don’t need feature X, because you can use Feature Q, P and R to create something that functions the same”. But that rather misses the point, I feel.

I’ve been careful not to mention specific languages, but here I go. Take Visual Basic 6. That is, Pre .NET. As a confession, I was trapped knowing only Visual Basic 6 well enough to do anything particularly useful with it for a very long time. Looking back- and having to support my legacy applications, such as BCSearch- and I’m astonished by two things that are almost polar opposites; The first is simply how limited the language is. For example, If you had a Object Type CSomeList and wanted to ‘cast’ it to a IList interface, you would have to do this:

Basically, you ‘cast’ by setting it directly to a variable of the desired type you want to cast. These types of little issues and limitations really add up. The other thing that astonished me was the ingenuity of how I dealt with the limitations. At the time, I didn’t really consider some of these things limitations, and I didn’t think of how I dealt with them as workarounds. For example, the above casting requirement I found annoying, so I ended up creating a GlobalMultiUse Class (which means all the Procedures within are public); in this case the Function might be called “ToIList()” and would attempt to cast the parameter to a IList and return it. Additionally, at some point I must have learned about Exception handling in other languages, and I actually created a full-on implementation of Exception handling for Visual Basic 6. Visual Basic 6’s Error Handling was, for those that aren’t aware, rather simple. You could basically say “On Error Goto…” and redirect program flow to a specific label when an error occured. All you would know about the error is the error number, though. My “Exception” implementation built upon this. To Throw an exception, you would create it (usually with an aforementioned public helper), and then throw it. in the Exception’s “Throw()” method, it would save itself as the active Unwind Exception (global variable) and then raise an Application defined error. Handlers were required to recognize that error number, and grab the active exception (using GetException(), if memory serves). GetException would also recognize many Error codes and construct instances of the appropriate Exception type to represent them, so in many cases you didn’t need to check for that error code at all. The result? Code like this:

would become:

There was also a facility to throw inner exceptions, by using ThrowInner() with the retrieved Exception Type.

So what is wrong with it? well, everything. The Language doesn’t provide these capabilities, so I basically have to nip and tuck it to provide them, and the result is some freakish plastic surgery where I’ve grafted Exceptions onto somebody who didn’t want Exceptions. Fact is that, once I moved to other languages, I now see just how freakish some of the stuff I implemented in VB was. That implementation was obviously not thread safe, but that didn’t matter because there was no threading support, for example.

Looking forward

With that in mind, it can be valuable to consider one’s current perspectives and how they may be misguided by that same sort of devotion. This is particularly important when dealing with things that you only have a passing knowledge of. It’s perhaps more applicable if you’ve gained experience with something to be able to recognize flaws, but it’s easy to find flaws or repaint features or aspects as flaws for the purpose of making yourself feel wiser for not having used it sooner.

Posted By: BC_Programming
Last Edit: 26 Sep 2018 @ 01:38 PM

EmailPermalinkComments Off on Programming Languages (2)
 17 Sep 2016 @ 3:42 PM 

Previously I wrote about implementing a Alpha-blended form with VB.NET. In that implementation, I had an abstract class derive from Form and then the actual forms derive from that. This causes issues with using the Form in the designer.

In order to workaround that issue I’ve redone parts of the implementation a bit to get it working as it’s own separate class. Rather than rely on the CreateParams() to adjust the GWL_EXSTYLE when the form is initially created, it merely uses SetWindowLong() to change it at runtime. Otherwise, the core of what it does is largely the same- just refactored into a package that doesn’t break the designer.

It should be noted, however, that adding controls to the form will not function as intended, though- this is inherent in the Alpha Blending feature, as it effectively just draws the bitmap. This is why it works well for Splash Screens. Controls will still respond to events and clicks however they will be invisible; making them visible would require drawing them onto the Bitmap and then setting it as the new Layered Window bitmap each time controls change.

Here is the changed code:

In usage it is no more complex than before, really:

The end result is largely the same:


Posted By: BC_Programming
Last Edit: 15 Oct 2016 @ 01:51 PM

EmailPermalinkComments Off on Alpha-Blended Forms revisited
 08 May 2015 @ 6:02 AM 

One of the things I find myself doing occasionally is looking at my old code. When you have over a decade of source code and projects that you’ve worked on, you can, perhaps ironically, learn a lot by reading your own code. When you read your old work, you really should seldom be impressed- that’s not a good thing, by any means, because it means that you have become a better developer in the meantime. It’s when you find your past self to be incredibly skilled even relative to yourself now that you may need to consider that you’ve stagnated. Following this, I thought I would write about some old code I wrote, provide it, and point out where I went wrong and where I went right.

As an example, pretty much my first program that did anything useful was a small Visual Basic 2.0 program, which allowed the selection of colours for HTM LBody tags (the old BGCOLOR, TEXT, LINK, ALINK, VLINK, etc settings), this, despite working with 16-color graphics. At some point, I became rather- obsessed- with gradients. Styles, colours, easing…. the signs of insanity were all there. Thus was the start of my first “Module” for code-sharing- “GRAPHICS.BAS”.

GRAPHICS.BAS ballooned in size as I basically just slapped all sorts of functions into it. the seed was “paintfrm” which itself became rather ridiculous. The comments make me incredibly glad that I was not regularly posting on the Internet at those times, and interestingly I see the symptoms today, where somebody who is 15,16, etc. seems to think they have it all figured out and their silly little program/routine should be heralded as creating a new era for humankind- but that is another story altogether. Just glad that my early contributions to the world wide web are difficult to associate with me personally, as they are quite embarassing.

Despite them being somewhat cringey, I kept the comments in the function intact. This is a Visual Basic routine, and it is rather long.

Just look at this. The hubris in the comment at the start. It uses a few other functions (regularPolygon, HLS, CMY) but those have the sort of implementation you would expect (dare I say, reasonable). What can we say about this function? Some obvious considerations come to mind for criticism:

It tries to do too much

14 special cases for special purpose gradients? Each of which interpret the actual parameters slightly differently? And it isn’t even an enumeration- it’s just a flat Integer value. To be fair to my former self I think I originally wrote it in VB2 which didn’t have enumerations, but nonetheless, it would have been possible to use Constants.

Variables are poorly named

I don’t even know what have of these do. what is SA? LOOPS? objgood? the XT! Array? Why do some of them declare their type with a type declaration character, while others declare their type specifically?


I mean… come on. Really? This isn’t Commodore BASIC, we can create new functions. What was I thinking

In my defense, this was before I learned about Object Oriented programming concepts and really before I learned anything about good design. Of course if you asked me back then I would have said I was a “good programmer” but I think this stuff shows that I would have been a liar to do so. Furthermore, this leaves one thinking.

I like to think I’m a capable programmer, but when I see my old code like this I always consider otherwise. It is notable that more recent programs (Like BCSearch) are really only annoying now because of the technology I used (VB6) and a few minor design decisions. If anything, they are often over-engineered.

One interesting approach is to try to be working on something where your skill level is that low. The goal being that in ten years you can look back and go “man, I barely knew how to use X, but now I consider all those trouble points trivial considerations”. It let’s you know that you’ve progressed.

Posted By: BC_Programming
Last Edit: 08 May 2015 @ 06:02 AM

EmailPermalinkComments Off on Critiquing the code of an amateur
Categories: Visual Basic, Visual Basic
 23 Nov 2013 @ 8:43 PM 

Visual Basic has a useful Operator, the “Like” Operator. Observe it in action:

The Like operator is a pattern matching operator. It can be useful in many situations and is certainly a lot shorter to use than fiddling about with Regular Expression Objects, matches, etc. So the question becomes, how can we best bring this to C#? We could have a static method in a separate class:

And use it like this:

But that’s not very concise. One alternative is to cheat and use operator overloads; we can’t define a new operator full stop, but we can fake it by creating a new class and a explicit operator for it that converts a string. Resulting in something like this:

In order to do this, we need as mentioned a new class that has an explicit cast from a String as well as an equality operator.

And… That’s it! Now you can have something approximating the Like Operator. Note that because it uses Regular Expressions it’s not actually the Like Operator, which is more restricted. If you really need exact replication of VB.NET’s Like Operator, you can create an Assembly in VB.NET and expose a public function that simply returns the result of a Like Operator on it’s parameters.

Posted By: BC_Programming
Last Edit: 23 Nov 2013 @ 08:43 PM

EmailPermalinkComments Off on How to Like C#
Categories: .NET, C#, Visual Basic
 11 May 2013 @ 6:29 PM 

In what will hopefully be a recurring series on older Development Tools, Languages, and Platforms, I will be covering some information on my old flame, Visual Basic.

Visual Basic has a relatively long history, going back to around 1991. BASIC itself, of course, has an even longer history, starting at Dartmouth College in the 70’s.

The question is- What made Visual Basic Special? One of the big things going for it at the time were that it was the easiest way to develop applications for the booming Windows Desktop. It made many development tasks easy, provided form designers where you would otherwise need to write layout code, and in general made the entire process of Windows Application Development a lot more accessible.

Visual Basic was one of the earliest examples of a “RAD” Tool. RAD- or “Rapid Application Development” essentially allowed a company or other entity to get a feel for how a idealized Application might look and feel with minimal effort. By making UI design something that requires very little to no code, the task requires less expertise- that is, the Company doesn’t need to use their Development Team Resources for that part of the design process. Another huge boon of the technology was that it made Application Development on Windows far more accessible- at least to those with big wallets, but considering the cost of a computer and software in those days finding a person with a computer that wasn’t in a financially secure situation was not very likely. A full synopsis of the history of Visual Basic and it’s origins isn’t really appropriate here, and has been covered far better by those actually involved in the process. You can read one such overview Here.

In this series, I will first cover Visual Basic Versions from 1.0 through 6.0; and possibly go through the various .NET implementations as well. As I flow through one version to the next, we will see the Language and it’s surrounding Toolset (IDE) evolve.

The First Split

Visual Basic 1.0 for Windows was released in 1991. It was part of a move by many companies to get Powerful development Tools on the increasingly popular Windows Desktop Environment. Visual Basic itself grew out of it’s spiritual predecessor, QuickBASIC. It made some cosmetic changes to the language, and changed it to be Event Driven. Visual Basic also introduced two modes of operation, Design-Time and Run-Time. At Design Time you would edit your code and your forms. During Run-time, you could stop the application (using either the Stop statement or a breakpoint).

Visual Basic 1.0 for Windows running under Window 3.11

Visual Basic 1.0 for Windows running under Window 3.11

As we see above, Visual Basic 1.0, Running on Windows 3.11, showing the Form View. I’m not sure why I went with BRICKS.BMP, usually I’m more a MARBLE.BMP guy but hey no accounting for taste. One thing that may surprise those used to later versions of Visual Basic might be that you can still see the Desktop. the MDI interface wouldn’t be around until Visual Basic 5, at which point it was optional for VB5 as well as VB6. (you can invoke both with the /sdi command line argument to switch to SDI and /mdi to switch to MDI, in addition to configuration options). The “Project Explorer” if we can call it that- is shown on the right. Right now it’s showing Global.bas- a Module inserted into every application, and also the only module in VB1 allowed to have Globals, which may be responsible for the name, and FRMLSTVI.FRM, which is the form file I created; that form is shown to the left, and to it’s left is the Toolbox, from which you can choose a variety of Visual Basic Controls. One of the interesting features of Visual Basic was it’s support for Custom Controls. Custom controls were specially coded DLL files with the .VBX Extension, which stands for “Visual Basic eXtension” because I guess using X’s in extensions was the cool thing to do back then- we didn’t know any better. These had to be written in C or another language capable of using the appropriate Visual Basic Control Development Kit, or CDK. There were a lot of Custom Controls Available for VB 1.0 that added a lot to VB Applications.

Along the Main Window (shown at the top) we notice two things: first, it lacks the Toolbar we would normally come to expect, and the Properties Editor is rather spartan, and takes up that area of the window.

Visual Basic 1.0 however did not forget Menus. A Window->Menu Design Window Item exists which gives you this dialog for editing the Menu layout of the Active Form:
Visual Basic 1 Menu Design Window

We’ll watch this Dialog evolve Through each version of Visual Basic- (and eventually disappear, be sure to stay tuned for that exciting conclusion). One interesting thing about This first version of Visual Basic is that it actually was released primary for Windows 3.0. That isn’t particularly amazing in and of itself, but it meant that it had to “hand-weave” scarves that Windows 3.1 gave Applications, because it might be on Windows 3.0. Behold:

Visual Basic 1 File Open Dialog

A hand-built, Custom File Open Dialog. And, a fairly terrible one, at that. Of course the one included with Windows 3.1 wasn’t exactly the pinnacle of UI ease of use either. We will see this dialog evolve over time as well with new versions.

Visual Basic 1 showing the Code of a Command Button

Visual Basic 1 showing the Code of a Command Button

Here we see the code Editor. I’ll be frank: it’s terrible, even for the standards of the time. It’s little more than a glorified Notepad, really. It also forces you to edit your source files one procedure at a time. unpleasant, really. It does auto-correct your casing, which I suppose is something. Breakpoints are shown in bold. The Form Designer doesn’t let you select multiple controls by dragging a box around them, but you can use Control+Click to do that.

One other curious limitation of Visual Basic 1.0 is the lack of the ability to save in text format; All the files are saved in a proprietary, undocumented text format. You can export and import to and from text files, but allow me to be the first to note that this is a gigantic pain in the ass. Using the Code->Export Text Menu option, this is the result:

To be fair this isn’t much different than the same Program would probably look in VB6; with a few exceptions that we will obviously touch on as we move up through the versions.

Visual Basic 1.0 was a runaway success. For some reason this popularity apparently impacted the DOS toolset teams, since the successor to QuickBASIC PDS 7.1 was a new version of QuickBASIC that did not have the same name- Visual BASIC 1.0 for DOS.

Visual BASIC 1.0 for DOS in Form Design View.

Visual BASIC 1.0 for DOS in Form Design View.

Visual BASIC for MS-DOS in Code View

What makes Visual BASIC 1.0 for MS-DOS interesting is that’s it’s only kinda sorta a Version of Visual Basic. For one, all the literature uses BASIC in capitals for whatever reason, and working with it feels very much the same as working with QuickBASIC 7.1 PDS, but with a special Character-Set GUI thing. In many ways it was more of a stopgap version for transitioning QuickBASIC users to Visual Basic for Windows.

In the next entry in this series, we’ll take a look at Visual Basic 2.0; what does it improve over 1.0 and How does it move RAD forward? Stay tuned and find out!

Posted By: BC_Programming
Last Edit: 13 May 2013 @ 05:29 PM

EmailPermalinkComments (1)
 04 Feb 2013 @ 9:24 PM 

Is XNA Going Away?

The following consists of my opinion and does not constitute the passing on of an official statement from Microsoft. All thoughts and logic is purely my own and I do not have any more ‘insider’ information in this particular topic than anybody else

I’ve been hearing from the community a bit of noise about Microsoft’s XNA Framework- a Programming library and suite of applications designed to ease the creation of Games- being cut. A google reveals a lot of information, but a lot of it is just plain old rumours. The only one I could find that was based on actual information still makes a lot of assumptions. It is based on this E-mail:

Our goal is to provide you the best experience during your award year and when engaging with our product groups. The purpose of the communication is to share information regarding the retirement of XNA/DirectX as a Technical Expertise.

The XNA/DirectX expertise was created to recognize community leaders who focused on XNA Game Studio and/or DirectX development. Presently the XNA Game Studio is not in active development and DirectX is no longer evolving as a technology. Given the status within each technology, further value and engagement cannot be offered to the MVP community. As a result, effective April 1, 2014 XNA/DirectX will be fully retired from the MVP Award Program.

Because we continue to value the high level of technical contributions you continue to make to your technical community, we want to work with you to try to find a more alternate expertise area. You may remain in this award expertise until your award end date or request to change your expertise to the most appropriate alternative providing current contributions match to the desired expertise criteria. Please let me know what other products or technologies you feel your contributions align to and I will review those contributions for consideration in that new expertise area prior to the XNA/DirectX retirement date.

Please note: If an expertise change is made prior to your award end date, review for renewal of the MVP Award will be based on contributions in your new expertise.

Please contact me if you have any questions regarding this change.

This is an E-Mail that was sent out- presumably- to XNA/DirectX MVPs. I say presumably because for all we know it was made up to create a news story. If it was sent out, I never received it, so I assume it would have been sent to those that received an MVP Award with that expertise. It might have been posted to an XNA newsgroup as well. Anyway, the article that had this E-mail emblazoned as “proof” that MS was abandoning XNA seemed to miss the ever-important point that it actually says nothing about XNA itself, but actually refers to the dropping of XNA/DirectX as a technical Expertise. What this means is that there will no longer be Awards given for XNA/DirectX development. It says nothing beyond that. Now, it could mean they plan to phase it out entirely- but to come to that conclusion based on this is a bit premature, because most such expertise-drops actually involved a merge. For example, in many ways, an XNA/DirectX expertise is a bit redundant, since XNA/DirectX works using a .NET Language such as VB.NET and C# and very few XNA/DirectX MVPs truly can work with XNA in any language at all, it might make sense to just clump them with us lowly Visual C# and Visual Basic MVPs.

To make the assumption that XNA is being dropped based on this E-mail is a bit premature. In my opinion, I think the choice was made for several reasons. I guess some of the misconceptions might be the result of misconceptions about just what a Microsoft MVP is. First, as I mentioned before, a lot of the expertise of XNA/DirectX involves an understanding- and expertise- in some other area. Again, Visual C#, Visual Basic, Visual C++, etc. So in some ways they might have considered a separate XNA/DirectX expertise redundant. Another reason might have to do with the purpose of an MVP. MVP Awards are given to recognize those who make exceptional community contributions in the communities that form around their expertise. For example, my own blog typically centers around C#, solving problems with C# and Visual Studio, and presents those code solutions and analyses to the greater community by way of the internet, as well as sharing my knowledge of C# and .NET in those forums in which I participate. MVP awardees don’t generally receive much extra inside information- and that they do get is typically covered by a NDA agreement. The purpose of the award is to also establish good community members with which Microsoft can provide information to the community. MVPs are encouraged to attend numerous events where they can, quite literally, talk directly to the developers of the Products with which they acquainted. in some way you could consider MVPs “representatives” of the community, who are chosen because their contributions mean they likely have a good understanding of any prevalent problems with the technologies in question, and interacting with MVPs can give the product teams insight into the community for which their product is created. Back to the particulars here, however- as the E-mail states, XNA Game Studio is not under active development. Now, following that, it seems reasonable to work with the assumption that either that product has no Product Team, or those that are on that Product Team are currently occupied in other endeavours, or other products for which their specific talents are required.

It’s not so much that they are “pulling the plug in XNA”- the product is currently in stasis. As a direct result of this, it makes sense that without an active Product Team, having specific MVP Awardees for that expertise isn’t particularly useful for either side- MVPs gain from personal interactions with the appropriate Microsoft Product team as well as fellow MVPs, and Microsoft gains from the aggregate “pulse of the community” that those MVPs can provide. Without a Product Team for a expertise, that expertise is redundant, because there is nobody to get direct feedback. This doesn’t mean the XNA community is going away, just that, for the Moment, there is no reason for Microsoft to watch it’s pulse, because the product is “in stasis” as the OS and other concerns surrounding the technology metamorphize and stabilize (The Windows 8 UI style, Windows Store, and other concerns in particular). Once the details and current problems with those technologies are sussed out, I feel they will most certainly look back and see how they can bring the wealth of game software written in XNA to the new platform. Even if that doesn’t happen, XNA is still heavily used for XBox development- which is also it’s own expertise.

I hope this helps clear up some of the confusion that has been surrounding XNA. It doesn’t exactly eliminate uncertainty- this could, in fact, be a precursor to cutting the technology altogether. But there is nothing to point to that being the direction, either.

Posted By: BC_Programming
Last Edit: 04 Feb 2013 @ 09:24 PM

EmailPermalinkComments Off on Is XNA going away?
 20 Jan 2013 @ 8:14 PM 
Note: This Post has been (partly) superceded by the implementation described in the more recent Alpha blended forms revisited Post.

One common problem that comes up in the creation of stylized windows such as Splash screens is the desire to have parts of the form be “shadowed” or, in other words, blend with the forms behind them. You can see this effect in action with other application splash screens, such as photoshop:

Photoshop Splash Screen in front of a dead-sexy website

Photoshop Splash Screen in front of a dead-sexy website

What witchcraft is this? How does Photoshop do it? One of the first things you might try with .NET is something like the TransparencyKey of the form. Of course, this doesn’t work, instead you get this unsightly ring of the transparency key around it.

The solution, of course, is a bit more complicated.

Starting with Windows 2000, the Win32 API and Window Manager has supported the idea of “layered” Windows. Before this, Windows had concepts known as “regions”; this basically allowed you to define regions of your window where the background would show through. This didn’t allow for per-pixel blending, but that sort of thing was not widely supported (or even conceived of, really) by most graphics Adapters. The “Layered” Windowing API basically provided a way to allow Per-pixel Alpha. Which is what we want.

Windows Forms, however, does not expose this layered window API through it’s methods or properties, with the exception of the opacity property. I don’t recall if WPF does either, but I would be surprised if it’s capabilities exposed more of the Layered Windowing API. Basically- we’re on our own

So what exactly do we need to do? Well, one thing we need to do is override the CreateParams property of the desired form, so that it adds the WS_EX_LAYERED style to the window, letting the Windowing Manager know it has to do more work with this window. Since we would like a neatly decoupled implementation, we are going to create a class that derives from Form, but use that as the base class for another form. This let’s us override the CreateParams property within that base class, but this has a bit of a caveat as well, since I’ve found that makes the Designer a bit annoyed and it complains and won’t let you use the designer. So you will have to deal with that particular point yourself. (I imagine there is a way to make it work, but I don’t want to bloat the class with such functionality). If necessary, the appropriate functions and the CreateParams override can be put into the classes that need this functionality instead.

Here is the PerPixelAlphaForm class. By the way, I’m going with Visual Basic.NET because there are already a million hits for this functionality with C#:

This provides the core implementation. The “Win32” class here provides the needed API declarations.

In order to use this, we need to make our form derive from it, and then use the inherited SetBitmap function:

(Here I just used an image on my second Hard disk that had a transparency channel, but the Bitmap constructor parameter can easily be changed.). The result:

The code in action

The code in action:

The Project I used for this can be downloaded from here. This was created using Visual Studio Professional 2012, Update 1- other editions or earlier versions may have problems with the project or source files.

Posted By: BC_Programming
Last Edit: 17 Sep 2016 @ 03:46 PM

EmailPermalinkComments (13)

 Last 50 Posts
Change Theme...
  • Users » 47469
  • Posts/Pages » 397
  • Comments » 105


    No Child Pages.

Windows optimization tips

    No Child Pages.

Soft. Picks

    No Child Pages.

VS Fixes

    No Child Pages.

PC Build 1: “FASTLORD”

    No Child Pages.