MGS Sources and Coding page


Here is a quick tutorial about adding your own features to MGS. We will discuss here the example of adding a DXF file reader to the 1.31 sources. (since this is what I'm currently up to)

Open the mgs.dll project

A DXF to MAP thing is not much different than prefabs loading, thus we would like to have a script like that :

DXF
{ data filename }

So .. DXF will be the script name, and data a string keyword holding the file name.

Let's start by adding a new script.
Increase #define NB_SCRIPTS in config.hpp by 1.
Now we must add some information about the script : in diplomat.cpp line 58, add a string to char * ScriptInfo[NB_SCRIPTS] something like "DXF File loading ...", this info will appear in the Radiant MGS plugin menu.
Let's add the DXF keyword for the script : in diplomat.cpp line 45, add a "DXF" string to char * ScriptKeywords[NB_SCRIPTS].

Now you should be able to recompile the DLL. Try once to make sure. There's no handler for the DXF script yet, we will add it :
Create dxf.hpp and dxf.cpp files, add a new DXF class, subclass of mgentInternal. Your header should look like that :

// dxf.hpp: interface for the DXF loader class.
//
//////////////////////////////////////////////////////////////////////
#ifndef __DXF__
#define __DXF__

/*
============================================================
DXF - version 1
yourname - date
============================================================
*/

class DXF : public mgentInternal
{
private:

EntityList elst;
DataDescriptorInternal parseinfo;

char * filename;

public:
DXF();
~DXF();

void genere(class OutData * pOutData) { Print("DXF loader\n"); elst.genere(pOutData); };
void translate(const vector);
void rotate(const vector,const vector);

class DataDescriptor * GetDataDescriptor();
void compute();

};

#endif

Now for the implementation :

/*
======================================================================
dxf.cpp
yourname - date
======================================================================
*/

#include "config.hpp"
#include "dxf.hpp"

/*
======================================================================
DXF reader - version 1
yourname - date
======================================================================
*/

DXF::DXF()
{
filename=NULL;
// Build DataDescriptor
parseinfo.Add("data",&filename);
}

DXF::~DXF()
{
};

void DXF::translate(const vector v)
{
elst.translate(v);
};

void DXF::rotate(const vector o,const vector v)
{
elst.rotate(o,v);
};

class DataDescriptor * DXF::GetDataDescriptor()
{
return &parseinfo;
};

void DXF::compute()
{
// TODO : add your code here
};

Now you can compile the file. The DataDescriptorInternal deals with the script keywords for you. In the constructor you add the data keyword connected to the char * filename member.

Last step is to hook the script into the MGS framework.
MGS uses enums to deal with the script names: enums and script keywords must match. In inout.hpp line 223 change mgs_token to typedef enum { cone = 0, cylinder , sphere , torus , pref , corrid , grnd , scripting , DXFloader , endscript , unknown } mgs_token;
Then add the dxf.hpp header to the beginning of diplomat.cpp (line 14).
The DiplomatInternal class deals with creating the scripting classes, last thing to do is to change mgentInternal * InternalDiplomat::GetEntity(int data) by adding a case DXFloader : return new DXF();

It's done ! You can now run mgswin.exe with your own mgs.dll and use the dxf { data filename } script .. only thing to do is writing the DXF::compute() member :-)