After completing my updates to the Blowfish object, I wasn’t thoroughly convinced that it was perfect. I thought it could benefit from some testing by people who didn’t make the thing. Often developers don’t accurately foresee all of the ways users will try to use their software, so it can be difficult to account for all possible situations. I was advised by Clickteam to post the updated object on one of their forums so that others could test it out. Now, I wasn’t expecting a large response to my update, but I also wasn’t expecting no response to it. As of writing this, my post has only 12 views and no replies. The only comment I received was in Clickteam’s chat room where a user informed me that he couldn’t believe I had updated the Blowfish object because it was so old. He has a point. The object is years old and may have been replaced by something better in my time away, or perhaps it has simply fallen into obscurity. I probably should have verified its use within the community before making the major updates that I did. Oh well. Maybe there are some people who will find it useful should they ever realize it’s been updated.
Clickteam has also asked me if I could port some of my extensions to their other platforms. Specifically, they asked for the Expression Evaluator, Boolean, and Associative Array objects. The request for ports of the Associative Array object didn’t surprise me since it’s my most popular extension. The other two objects did surprise me. I believe the Boolean object was my first extension. It has some neat features but was awkward to use due to restrictions in MMF’s event list architecture. I wasn’t aware that anyone used it to be honest, especially not enough people to warrant a request from Clickteam for it to be ported. The Expression Evaluator object is a pretty neat extension. It allows for the execution of mathematical expressions and allows the user to create their own custom functions for use in those expressions. This was probably my favorite extension, but I wasn’t aware of anyone making much use of it. I want to at least attempt to port these extensions, but the list of new platforms seems a bit overwhelming. There are now SDKs for Flash (ActionScript3), iOS (Objective-C), Java, XNA (C#), and HTML5 (Javascript). I’m pretty familiar with ActionScript3, C#, and Javascript. I’ve used Java in the past but never extensively. I’ve never used Objective-C, but I probably won’t bother with iOS because that’s Apple’s platform and I despise Apple. The other platforms seem reasonable, though.
I decided that I would port the Associative Array object first since most of these languages support such structures natively. When I started, I noticed that my current source code for the Associative Array object was in an intermediate state. Great. Five years ago, I was in the process of some sort of update because I had variables that I initialized but never defined or used and I had a function header with a comma after the last parameter as if I was about to add a new parameter. I’m going to have to spend some time analyzing my code so that I can make sure everything is working properly. I’m not looking forward to this, but it’s a necessary step along the path I am about to take. In the future, I suppose I should make a to-do list part of each of my projects in case I get sidetracked for a few years
Sunday, June 24, 2012
Monday, June 18, 2012
Multimedia Fusion and Blowfish
Multimedia Fusion is a great program made by a company called Clickteam. If you’ve ever heard of Klik ‘n’ Play, Multimedia Fusion (MMF) is the latest version of that. I started using Klik ‘n’ Play way back in the late 90s (probably 1998). I made some pretty bad games with it, which are still available for download on my web page. About a year later, I purchased my first copy of MMF and discovered that the makers of the software had their own web site and community. I never made any particularly good software with MMF, which is not to say MMF is incapable of good software. It is. In fact, several people I know have made successful commercial ventures with games they made in MMF. I really found my niche in the community when I started learning C++ the summer before my senior year in high school. Suddenly, I could make extensions for MMF, adding new functionality to the program. I may not have been much of a game maker, but I wasn’t too bad with making useful extensions. Eventually, I developed a relationship with some members of the company. In fact, they’ve sent me a few free copies of their software over the years. Alas, over time, I grew apart from MMF and the community. Throughout college, I focussed more and more on traditional programming paradigms and less on MMF. I preferred the more flowing structure of languages like C++ than the event list structure of MMF.
Eventually, I lost all contact with the community. This is something I regret quite a bit. Occasionally, I would get e-mails from people asking about my extensions but not too often. Back in 2008, I was made aware of a bug in one of my extensions, the Blowfish encryption object. This is the one extension that I had actually sold to Clickteam, so when I decided that I would try to fix the bug, I had to get a copy of the source from them. I actually found and fixed the bug. It turns out that the Blowfish algorithm expects data in big-endian form (I’ll discuss this more later), so I just needed to reverse the byte ordering before and after encryption. I did this, but then I got an even bigger idea in my head. It seems silly that each object that wants to use encryption should have to implement the algorithm itself. What if there were a generalized encryption system where any object that wanted to encrypt data could simply be passed the information of an encryption object and could then make use of the encryption object’s own algorithms? Well, I set about working on that model and got in over my head. After a while, I gave up and never returned the fixed source code to Clickteam. I was in a time in my life where motivation is difficult to find. Years passed. I’m finally now trying to dig myself out of this rut. In fact, this blog is one of the ways I’m trying to do it. I figure that the more I tell people what I’m doing, the more likely I am to follow through with it. Granted, no one reads this blog, but maybe, some day, someone will. I consider not correcting the bug in the Blowfish object to be a significant failing on my part, so finally fixing it is of great importance to my sense of self-wroth.
The bug in question, as mentioned earlier, had to do with the byte ordering of data sent to the encryption/decryption functions. If you don’t plan to use any encrypted data with any other implementations of Blowfish, this isn’t actually a problem, but it is likely that you’d want to do that. When passing data (stored as an array of characters) to the Blowfish functions, I would just typecast addresses into the array as pointers to unsigned longs. In little-endian formats, this puts the first character as the lowest byte of the newly formed long. It seems that Blowfish implementations prefer that this first character be in the highest byte of the long. I’m not entirely sure if this means that Blowfish implementations prefer big-endianness or if it’s simply that they convert the array of characters using bit-shifts and ors rather than simple typecasts. I wasn’t satisfied, however, with just fixing this bug. I wanted to add some different cipher block modes. In the past, I had only used the electronic codebook mode (ECB) because I simply wasn’t aware of the other modes in use. At first, I was only going to add cipher-block chaining mode (CBC), but after further investigation, I realized that cipher feedback mode (CFB) and output feedback mode (OFB) were relatively simple to implement. I decided to add all three new modes to the object. I’m not sure what the relative advantages and disadvantages are of each mode, but since they were so simple to add, I decided to just add them and let the user sort it out.
I also wanted to rewrite the file-handling function. In my younger days, I seemed to have a strange dislike of keeping files open, so I would read entire files into memory and then process the data. Once done, I would reopen the file and write the new data. For small files, this is fine, but for large files, this can be problematic. In rewriting the function, I had to open the file in both read and write modes. I had never used a file in this manner before and was unaware of one of the quirks involved. In my first tests, I was able to read and write my first block of data, but I was unable to read subsequent blocks. My first test took a little 1.82 MB file and turned it into a gigantic 64 MB file because I would keep reading and writing the same block of data over and over. After some research, I discovered than when switching between using fread and fwrite, you need to have a call to fseek. Before writing data back to the file, I would call fseek to jump back to the start of the block, but since the write operation placed me at the location in the file of the next block of data to read, I had no reason to call fseek again. Because an fseek call is required before switching back to fread, I had to add a dummy call to fseek that doesn’t change my position in the file. After fixing that problem, my updated file handling worked perfectly.
I took me nearly a week to make and debug all of the changes that I wanted, but I feel it was worth it to remove this blemish from my psyche. I’ve returned the updated object to Clickteam to see what they think of the update object.
Eventually, I lost all contact with the community. This is something I regret quite a bit. Occasionally, I would get e-mails from people asking about my extensions but not too often. Back in 2008, I was made aware of a bug in one of my extensions, the Blowfish encryption object. This is the one extension that I had actually sold to Clickteam, so when I decided that I would try to fix the bug, I had to get a copy of the source from them. I actually found and fixed the bug. It turns out that the Blowfish algorithm expects data in big-endian form (I’ll discuss this more later), so I just needed to reverse the byte ordering before and after encryption. I did this, but then I got an even bigger idea in my head. It seems silly that each object that wants to use encryption should have to implement the algorithm itself. What if there were a generalized encryption system where any object that wanted to encrypt data could simply be passed the information of an encryption object and could then make use of the encryption object’s own algorithms? Well, I set about working on that model and got in over my head. After a while, I gave up and never returned the fixed source code to Clickteam. I was in a time in my life where motivation is difficult to find. Years passed. I’m finally now trying to dig myself out of this rut. In fact, this blog is one of the ways I’m trying to do it. I figure that the more I tell people what I’m doing, the more likely I am to follow through with it. Granted, no one reads this blog, but maybe, some day, someone will. I consider not correcting the bug in the Blowfish object to be a significant failing on my part, so finally fixing it is of great importance to my sense of self-wroth.
The bug in question, as mentioned earlier, had to do with the byte ordering of data sent to the encryption/decryption functions. If you don’t plan to use any encrypted data with any other implementations of Blowfish, this isn’t actually a problem, but it is likely that you’d want to do that. When passing data (stored as an array of characters) to the Blowfish functions, I would just typecast addresses into the array as pointers to unsigned longs. In little-endian formats, this puts the first character as the lowest byte of the newly formed long. It seems that Blowfish implementations prefer that this first character be in the highest byte of the long. I’m not entirely sure if this means that Blowfish implementations prefer big-endianness or if it’s simply that they convert the array of characters using bit-shifts and ors rather than simple typecasts. I wasn’t satisfied, however, with just fixing this bug. I wanted to add some different cipher block modes. In the past, I had only used the electronic codebook mode (ECB) because I simply wasn’t aware of the other modes in use. At first, I was only going to add cipher-block chaining mode (CBC), but after further investigation, I realized that cipher feedback mode (CFB) and output feedback mode (OFB) were relatively simple to implement. I decided to add all three new modes to the object. I’m not sure what the relative advantages and disadvantages are of each mode, but since they were so simple to add, I decided to just add them and let the user sort it out.
I also wanted to rewrite the file-handling function. In my younger days, I seemed to have a strange dislike of keeping files open, so I would read entire files into memory and then process the data. Once done, I would reopen the file and write the new data. For small files, this is fine, but for large files, this can be problematic. In rewriting the function, I had to open the file in both read and write modes. I had never used a file in this manner before and was unaware of one of the quirks involved. In my first tests, I was able to read and write my first block of data, but I was unable to read subsequent blocks. My first test took a little 1.82 MB file and turned it into a gigantic 64 MB file because I would keep reading and writing the same block of data over and over. After some research, I discovered than when switching between using fread and fwrite, you need to have a call to fseek. Before writing data back to the file, I would call fseek to jump back to the start of the block, but since the write operation placed me at the location in the file of the next block of data to read, I had no reason to call fseek again. Because an fseek call is required before switching back to fread, I had to add a dummy call to fseek that doesn’t change my position in the file. After fixing that problem, my updated file handling worked perfectly.
I took me nearly a week to make and debug all of the changes that I wanted, but I feel it was worth it to remove this blemish from my psyche. I’ve returned the updated object to Clickteam to see what they think of the update object.
Wednesday, June 6, 2012
User Interfaces and my Secret Project
I don’t make it a secret that I despise designing and implementing user interfaces. One of the beauties of the command line interface is that it is so simple to implement. Unfortunately, unless you’re using the application programmatically (e.g. in batch files), the command line interface isn’t very user-friendly. It’s simple to use but, in a Windows environment, opening a console, navigating to the proper directory, and then typing out the command line can be cumbersome.
Ultimately, you need to design your user interface for your intended users. For more esoteric programs like my FLV Script Data Extractor, a command line interface is fine because anyone interested in that sort of thing is likely to be handy with the Windows console. However, for my secret project, my intended users are not necessarily going to be hardcore computer users. They’re much more likely to be casual computer users who may never have used a console application or a command line interface before. Unfortunately, that means that I had to design a graphical user interface for my secret project. I considered using .NET to make the interface because Visual Studio 2010 makes creating GUIs in .NET very easy, but I thought the overhead of .NET for such a simple application was overkill. To my dismay, Visual C++ 2010 Express does not provide any interfaces or templates for creating GUIs in Win32. You just have to code the whole thing. I’m not familiar with making GUIs in Win32 so I was kind of stumbling all over myself at first. I tried using Windows controls (static text, edit boxes, etc.) but I couldn’t get the coloring right without doing extra work that I didn’t feel like doing. After banging my head against the wall for several hours, I decided to try using a dialog box interface. I’ve done my fair share of dialog box programming from my time making objects for Multimedia Fusion. I wasn’t sure how to make a Win32 program that was just a dialog box, so I had to play around with it. Finally, I realized I could just scrap all of the default window creation code Visual C++ created for me and simply use the DialogBox function by itself. A handy trick I’ve used in the past is to create my dialogs in Visual C++ 6.0, which has a neat little dialog box designer, and then copy the proper code over to Visual C++ 2010. I suppose I could just draw the interface on paper and then code it manually but designing it visually is so much faster. After several days, I finally finished the interface. The code is messy, with way more global variables than I’d like, but I’ll just blame that on a lack of experience.
I toyed with the idea of also allowing the user to use the command line if they so desired, but I ran into a bit of a speed bump. In a Win32 application, Windows does not break up the command line into argv and argc. Instead, it passes the whole command line as a single string. Windows does provide a function (CommandLineToArgvW) for converting this string into something similar to argv and argc but it only works on wide chars (Unicode). This really shouldn’t be a problem since I did design the program to use Unicode, but I was using TCHAR, which is a Windows type that can be either wide char or char depending on preprocessor definitions. I thought about using CommandLineToArgvW but that would defeat the whole point of using TCHAR. Given that no one is ever likely to use the command line, I decided it wasn’t worth the effort to write my own function to parse the command line.
Ultimately, you need to design your user interface for your intended users. For more esoteric programs like my FLV Script Data Extractor, a command line interface is fine because anyone interested in that sort of thing is likely to be handy with the Windows console. However, for my secret project, my intended users are not necessarily going to be hardcore computer users. They’re much more likely to be casual computer users who may never have used a console application or a command line interface before. Unfortunately, that means that I had to design a graphical user interface for my secret project. I considered using .NET to make the interface because Visual Studio 2010 makes creating GUIs in .NET very easy, but I thought the overhead of .NET for such a simple application was overkill. To my dismay, Visual C++ 2010 Express does not provide any interfaces or templates for creating GUIs in Win32. You just have to code the whole thing. I’m not familiar with making GUIs in Win32 so I was kind of stumbling all over myself at first. I tried using Windows controls (static text, edit boxes, etc.) but I couldn’t get the coloring right without doing extra work that I didn’t feel like doing. After banging my head against the wall for several hours, I decided to try using a dialog box interface. I’ve done my fair share of dialog box programming from my time making objects for Multimedia Fusion. I wasn’t sure how to make a Win32 program that was just a dialog box, so I had to play around with it. Finally, I realized I could just scrap all of the default window creation code Visual C++ created for me and simply use the DialogBox function by itself. A handy trick I’ve used in the past is to create my dialogs in Visual C++ 6.0, which has a neat little dialog box designer, and then copy the proper code over to Visual C++ 2010. I suppose I could just draw the interface on paper and then code it manually but designing it visually is so much faster. After several days, I finally finished the interface. The code is messy, with way more global variables than I’d like, but I’ll just blame that on a lack of experience.
I toyed with the idea of also allowing the user to use the command line if they so desired, but I ran into a bit of a speed bump. In a Win32 application, Windows does not break up the command line into argv and argc. Instead, it passes the whole command line as a single string. Windows does provide a function (CommandLineToArgvW) for converting this string into something similar to argv and argc but it only works on wide chars (Unicode). This really shouldn’t be a problem since I did design the program to use Unicode, but I was using TCHAR, which is a Windows type that can be either wide char or char depending on preprocessor definitions. I thought about using CommandLineToArgvW but that would defeat the whole point of using TCHAR. Given that no one is ever likely to use the command line, I decided it wasn’t worth the effort to write my own function to parse the command line.
Labels:
C++,
command line,
dialog box,
GUI,
interface,
software,
Win32
Subscribe to:
Posts (Atom)