Sunday, July 25, 2010

Requesting data from CC3 - RDATA

Last post I introduced the two most important functions exposed by CC3: RDATA & FORMST.

In this post I'll discuss the internals of RDATA.

Here are the important elements you need to configure for every time you declare an RDATA.

  • Name - This is simply the name the holds all the separate RDATA elements together
  • Type - This is where you declare what kind of data you are requesting
  • Flags - These flags are the switches that tweak the RDATA call to do exactly what you want
  • Data Store - Where to "put" what you have requested after it has been selected
  • Prompt - This is the text that will be displayed to the user
  • FormSt declaration - This is where you decide if you want to include the prompt declaration. If you already have exactly the prompt you want already declared, you can reuse it instead of creating a new one
  • Cursor - Obviously selecting a single item you want a different cursor than if you want them to type in some text
  • Return Procedure

When I first started to write XP's, Super Guru Peter Olsen sent me a little tool that he wrote to automatically generate the RDATA call. When I was preparing for this post, I asked Peter if he still had the app. Well, he did, but he suggested that I create an online version of the tool. So, here is a Silverlight 4 application that generates an RDATA structure for you.

In my next post, I'll use the tool to generate our RDATA and select our first element. Plus, we will start to discuss what it is exactly, that we get back from our ReqData call.

Saturday, July 24, 2010

Part 2 of a Campaign Cartographer 3 XP - Or, the best part for last.

In a previous post, I discussed how an XP is in three distinct parts. This post is about the second part: Where the rubber meets the road.

Because this is the main part of the XP, describing this section in any detail would be like trying to describing how any a website works by describing how HTML works.

But, there are two main functions of every XP. Input and Communicating with the user.

Input: Feeding data from you map into your XP is a major function. If you cannot select elements or locations (points), you cannot have much of an impact on your drawing.

Communication: Having the ability to select something without telling the user what your command is expecting the user to do.

These two functions are accomplished using RDATA (Request Data) and FORMST (Format String). Using these two together, we can prompt the user, with FORMST, that we currently want a type of data (a string, a point, an element etc.) and with RDATA, we are informing CC3 that it needs to let the user collect the data we want.

Here is a simple example that implements an XP command to enter a text word:

Code Snippet: XP dll Part #2
  1. void XPCALL GotText(int Result, int Result1, int Result2);
  3. FORMST(lpszGetText, "Enter Text:")
  5. RDATA rGetText = {sizeof(RDATA), RD_TxWord, NULL, RDF_C, (DWORD *)Text,
  6. (DWORD *)&lpszGetText, RDC_NONE, GotText, NULL, NULL, 0, NULL, 0};
  8. void XPCALL GetText(void)
  9. {
  10.     ReqData(&rGetText);
  11. }
  13. void XPCALL GotText(int Result, int Result1, int Result2)
  14. {
  15.     if(Result==X_OK)
  16.     {
  17.     }
  18.     else
  19.     {
  20.         CmdEnd();
  21.     }
  22. }

Line 1: This is the prototype for the method that RDATA will call when it has gotten a hold of the data you requested.

Line 3: This is the FORMST declaration. This declaration creates a variable (lpszGetText) and assigns it the text "Enter Text:".  True, we could have created a string with this text, but RDATA is expecting a FORMST variable.  Plus, when we get further into the power of FORMST, you will see that is it not merely a replacement for a char array.

Lines 5 & 6:  This is the RDATA declaration.  When you learn to read it, you will see that it says it is going to go get a "Word" (a string of characters without whitespace), store it in the char array Text (not declared in the code snippet), diplaying no visible cursor, displaying the text in the FORMST as our prompt and calling our method, GotText, when the user is done entering the request.

Line 8 - 11: This is our commands original method.  It would have been declared and prototyped in Part 1 of the XP code.

Line 10:  This is the call that invokes our RDATA.

Line 13 - 22: This is our method that RDATA will call when it has gotten a hold of the data you requested.

Line 15:  This line shows that the Result parameter contains the "Status" of the request we made.  If it is "OK" then we can further process what we got.

Line 20:  CmdEnd() is the XP command that notifies CC3 that our XP function has come to an end.

Tuesday, July 20, 2010

Part 3 of a Campaign Cartographer 3 XP

In a previous post, I discussed how an XP is in three distinct parts. This post is about the third part: XP DllMain Boilerplate.

Here is the third part (right below your usings) of an Example XP dll. Remember that this is the very last part of a XP dll:

Code Snippet: XP dll Part #3
  1. #pragma unmanaged
  2. BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
  3. {
  4.     switch (dwReason)
  5.     {
  6.         case DLL_PROCESS_ATTACH:
  7.         {
  8.             MyXP.ModHdl=hDLL;
  9.             XPRegCmd(&MyXP);
  10.             break;
  11.         }
  12.         case DLL_PROCESS_DETACH:
  13.         {
  14.             XPUnregCmd(&MyXP);
  15.             break;
  16.         }
  17.     }
  18.     return TRUE;
  19. }

In truth, there is only one part that is optional. That is Line 1.

Line 1: This line is only needed if you are mixing standard C/C++ with .net code.

Otherwise, just copy it all at the bottom of the file and it will just work.

Sunday, July 18, 2010

Part 1 of a Campaign Cartographer 3 XP

In the last post, I discussed how an XP is in three distinct parts. This post is about the first part: XP Command declarations.

Here is the first part (right below your usings) of an Example XP dll:

Code Snippet: XP dll Part #1
  1. #define XPID 0xF000
  3. void XPCALL About(void);
  4. void XPCALL Example1(void);
  5. void XPCALL Example2(void);
  7. char CList[]="EX1\0EX2\0\0";
  8. PCMDPROC PList[]={About, Example1, Example2};
  10. XP MyXP = { 0, CList, PList, 0, 0, 0, XPID, 0, 500, 0, 0, 500 };

Line 1: This defines the Xp ID. In the official documentation from Evolution Computing, the description is:

If your XP is going to be a commercial product, you will need to obtain an XPID number from Evolution Computing.

XPID numbers are unique XP module identifiers that allow FastCAD to identify which XPs should provide support for which custom entities and tools. That is their only purpose. Numbers in the range 0xF000-0xFFFF are available for unregistered use, but will not guarantee uniqueness against other products available to customers.

The only requirement Evolution Computing makes to issue a registered XPID number is that we know the product name, the company providing support, and that the product using it is about to be released for commercial sale. Please do not ask us for a registered XPID until your product is ready for sale.

So, unless you are about ready to sell your new add-on, just use the default.

Lines 3 through 5: These are the prototypes for the entry functions into your new commands. The first one, About, is required. It is called by the XPCFG command. If you have never tried it, run it now.

Go ahead, I'll wait.

Did you run it? If you did, you saw a list of all the loaded XP's and if you selected one of those XP's and clicked the about button, you just ran the about function for that XP. Its a good practice to keep the message box that is displayed up-to-date with a list of the commands you coded in your XP.

You may have also noticed that all the prototypes, except for the name, are exactly the same. This is because when a XP command is activated, it is up to the command to retrieve any and all data it needs, so the prototype is just defining the activation function. Think of it as your commands' Main() function.

Lines 7 & 8: These lines define CList and PList. CList is a string that defines the commands you are exposing to CC3. In the above example those commands are: "EX1" and "EX2". PList is a list of procedure names.

Notice the first one is "About". Remember, "About" is required and it must be the first procedure in the list. The next two procedures are "Example1" and "Example2". These procedures are, because of CList, mapped to the CC3 commands "EX1" and "EX2. If CList listed them in the reverse order: "EX2\0EX1\0\0", then "EX2" would be mapped to "Example1". So just remember that they are order dependant and that the first command always matches with the first procedure AFTER "About", the second command always matches with the second procedure AFTER "About" ... "

And lastly Line 10 is some required boilerplate that takes CList and PList and exposes them to CC3.

Saturday, July 17, 2010

The anatomy of a basic Campaign Cartographer 3 XP

A traditional XP is written in Assembly. This is because CC3 and its predecessors were written in Assembly. But, for the last decade or more there has been a library file that allows XP development in C/C++.

An XP source code file is made up of three distinct parts.

Part 1: XP Command declarations. Here is where we place all the prototypes of the entrypoint functions of each XP command. We also add the names of each command into lists that CC3 loads. In other words, this is where CC3 looks to map a command same, like PATH, with a function to call when the user types in that command.

Part 2: This is the meat of the XP dll. This is where all the actual coding magic works.

Part 3: This is where the DllMain for the dll is declared. This boilerplate code hooks up the dll into CC3.

Thursday, July 15, 2010

All the different ways to extend CC3

There are many ways to extend Campaign Cartographer 3: Macros, XP's, Intercom and reading and writing the file format directly.

In the blog posts that follow, we will be focusing on the middle two. Macros are good for a little automation but it just is not robust enough to produce complex functionality. If you can read/write the file system you could create some amazing things but A: It is a binary file B: It is compressed. So, it is just not a good place to start when learning to extend CC3.

So that leaves XP's and Intercom. They both can do great things with CC3, but from radically different directions.

An XP is an actual extension to CC3. So, if you want to add functionality to CC3, you will program an XP.

Intercom is a communication system with CC3. So, if you have an application that you want to integrate with CC3, Intercom is the system for you.

XP's will be my primary focus, simply because of the closer integration with CC3, but I will intersperse posts on Intercom to liven things up.

Monday, July 12, 2010

Welcome to CC3 Developer!


This is the introduction to my new blog dedicated to Campaign Cartographer (CC3) by ProFantasy Add-in development.

ProFantasy has produced a wonderful Game World Cartography product. Not just a single program, but an entire suite of add-ins that allow the user to draw just about anything map related.

The learning curve is a little steep, but just like with Photoshop, once you learn it, you have access to vasts amount of power.

Now I've written some "get started developing CC3 (and its predecessor CC2)" tutorials in the past. These are long, hand holding, filled with pictures tutorials and I plan on creating more in the future, but here I want to do the smaller howto type of posts that are the hallmark of blogging.

There is a vast API exposed for making CC3 Add-ins (also known as XP's) but, it is very lightly documented with zero examples. As I blog, I hope to expand the documentation of the API.

There are also other ways to automate and expand CC3. We will be looking at those from time to time as well.

So, sit back and enjoy the ride, as we delve into the world of CC3 programming!