Inside Ultimate - Part 1: Introduction
as you may have noticed, the “Articles” section has been there for quite a long time. Unfortunately, I never got around to actually putting articles into it. Also, I intended to write the articles in both English and German, as most of this site is. However, I now decided I would write them in English only since this language is understood by most of the people (unlike German), and I simply do not have enough time (and endurance) to go for the multi-lingual way.
Go ahead and guess what this article is all about… correct, about the RPG Maker 2009 Ultimate. Some people might find it useful (or at least interesting) to read about how it internally works, and what the key problems and their solutions were, that’s why I am now going to write a series of articles about this topic. Please note that these articles are targeting advanced developers!
Let’s start with what RPG Maker 2009 Ultimate basically is. One could compare it to a game trainer, because it works in a similar way. It consists of the following components:
- rpg2009.exe – The so-called “mini-loader”, written in FreeBasic.
- ultimate.dll – The main component (written in FreeBasic too), containing both the loader which injects my code into the RPG Maker and the code which is going to be injected. (It also contains the language file editor.)
- vclxhg5.dll and vclxchg6.dll – Helper libraries written in Delphi 5/6 which are necessary to do the “really powerful” things. (More about these libraries later.)
- detoured.dll, DockWnd.dll and RAGrid.dll – They are just 3rd-party libraries (a bit customized, though) used by ultimate.dll.
rpg2009.exe is called mini-loader because all it does is loading the loader.
This is the FreeBasic source code of rpg2009.exe:
#Inclib "ultimate" Declare Function LdrMain Cdecl Alias "LdrMain" () As Integer End(LdrMain())
All it does is importing the function LdrMain from ultimate.dll and calling it. Putting both the loader and the main (injected) code into ultimate.dll simplified development for me.
The loader in ultimate.dll now displays the loader dialog (unless you use the “langed” command-line parameter, in this case the language file editor is opened), after loading the configuration and the language file. From this dialog, you can select a project and start the RPG Maker.
If you do so, the splash screen (with or without debug info, depending on the setting at the loader dialog) is shown and the magic begins. The RPG Maker is started and special code is injected which loads the ultimate.dll into the rpg2000.exe/rpg2003.exe process and calls the “Init” function (this function is not exported from ultimate.dll because it wouldn’t do any good if it were called from any other process than the RPG Maker’s) with the loader dialog’s window handle as parameter. This handle is used to allow communication between the rpg200X.exe process and the rpg2009.exe (loader) process using registered window messages.
The Init function then looks for all necessary code pointers, etc. and applies necessary hooks and patches. It then waits for the main window to be opened and initialized (identified by the class name “TFormLcfGameMain”) and then applies further modifications (layout changes, undocking the tool panel, replacing menu and toolbar and soforth). And then the splash screen is closed, the loader window is hidden (unless debug mode is activated) and everything is ready!
Next time we will take a closer look at the vclxchg5.dll and vclxchg6.dll files to find out why they are needed and how they work.