L3DT users' wiki
Large 3D terrain generator

Upgrading a plugin to Zeolite v11.08

Author Aaron
Date 19 Aug 2011

Version 11.08 of theZeolite plugin API for L3DT is a major revision that breaks backward compatibility with previous versions of both L3DT and the plugin API. That is to say, old plugins will not work with the new L3DT, and new plugins will not work with the old L3DT.

This update removes many idiosyncrasies and cuts out about five years of accumulated cruft in Zeolite, which had been backwards compatible until this point. Whilst these changes will make it easier to write new plugins, they will require existing plugins to be modified and recompiled. This tutorial explains how to update a plugin to Zeolite v11.08.

API files

The first thing to note about the new version of Zeolite is that the core files have changed; 'CExtAPI.h', 'CExtAPI.cpp', and 'CExtAPI_defines.h' have been replaced by 'Zeolite.h', 'Zeolite.cpp' and 'Zeolite_defines.h'.

Furthermore, some sets of functions formerly included in the CExtAPI class have been spun out into separate files, including the project functions (in zProj.h/cpp), file helper functions (in zFile.h/cpp), menu functions (in zMenu.h/cpp) and view functions (in zView.h/cpp). If you use these functions, you will need to include these files in your project also.

In previous versions of the API, a set of calculation helper files were included in the 'calc' subdirectory. These have been moved into the 'helper' subdirectory, alongside the other various helper functions.

Additional helper files have been added, including variable type casting (in zVarCast.h/cpp), backup/restore functions (in zBackup.h/cpp), functions for reading/writing L3DT's XML settings files (in zXML.h/cpp), and several others.

Include directories

The #include statements in the API files have been written with the assumption that you have added to your project's include paths the following directories:

  1. The root directory for your project's source files (specifically, the folder containing 'stdafx.h' in MSVC projects.)
  2. The Zeolite API folder.

In the case of the 'ZeoScript' plugin, the include paths in the project configuration look like this (in MSVC 2008):

:tutorials:zeolite:upgrade_to_v3:includepaths.png
Include paths for the zeolite-based plugin 'ZeoScript'.

No CExtAPI

In previous versions of Zeolite, API functions were accessed through the CExtAPI class and the one and only declared instance thereof, theAPI. In Zeolite v11.08, this class has been removed, and all functions have can be accessed directly. However, to avoid conflicts with functions from other libraries or code, Zeolite API function names have been prepended with 'z'. For example, the CExtAPI::format_GetFormatByExt function is now zformat_GetFormatByExt.

Hence, to update a plugin to Zeolite v11.08, find all instances of 'theAPI.' in your code and and replacing with 'z'. This replacement will account for most of the changes required to use Zeolite v11.08.

Error reporting

The error reporting functions CExtAPI::ReportError (which opens the event log) and CExtAPI::WriteToLog (which does not) have been renamed zeoReportError and zeoWriteToLog. A simple search and replace should be sufficient to change to the new scheme.

zeoexport and the exports table

In previous versions of Zeolite, it was necessary to include your plugin's exported functions in the EXPORTS list of the module definition file (*.def) so that the functions were exported without name decoration or mangling. This is no longer necessary when using Zeolite v11.08 if functions are exported using the zeoexport keyword.

For example, using older versions of Zeolite you could export the a function called ExampleFunc by declaring it like so:

bool __stdcall ExampleFunc(ZVAR hReturnVar, ZLIST hArgList);

.. and then listing it in the module definition exports table thusly:

EXPORTS
    ; Explicit exports can go here

ExampleFunc @1

In Zeolite v11.08, the module definition file is no longer needed, and the function may instead be declared as:

zeoexport bool __stdcall ExampleFunc(ZVAR hReturnVar, ZLIST hArgList);

Functions declared with the zeoexport keyword may optionally be listed in the exports table, but it is unnecessary to do so.

ExtInitPlugin

In previous versions of Zeolite is was necessary to declare a function called ExtInitPlugin and include this in the exports table. In Zeolite v11.08 the name of this function has changed to zeoInitPlugin and the argument list has also changed:

New
zeoexport bool __stdcall zeoInitPlugin()
Old
bool __stdcall ExtInitPlugin(FARPROC pFunc, LPVOID hID)

Note that the function no longer takes any arguments. These were previously required to initialise the plugin API by calling the CExtAPI::InitAPI function from within the ExtInitPlugin function. This is no longer required (or possible), as L3DT now initialises the plugin API directly before calling zeoInitPlugin.

It was also previously necessary to list ExtInitPlugin in the exports table. This is no longer required, as the zeoexport keyword handles the name decoration and exporting of the zeoInitPlugin function.

A plugin's instance of the Zeolite API is initialised after the plugin is loaded into the process but before zeoInitPlugin is called. Hence, users must not call any Zeolite API functions before zeoInitPlugin is called.

ExtShutdown

In previous versions of Zeolite it was optional to include a function called ExtShutdown, which would be called before the plugin is unloaded, and may be used for cleaning up memory or releasing resources before the library is released from memory. In Zeolite v11.08, this function name has changed to zeoShutdown, and it should now be declared using the zeoexport keyword:

New
zeoexport void __stdcall zeoShutdown(void)
Old
void __stdcall ExtShutdown(void)

It was previously necessary to list ExtShutdown in the exports table. This is no longer required, as the zeoexport keyword handles the exporting and name decoration of the zeoShutdown function.

ExtSaveMapFile and friends

To load an save map files, plugins previously had to export one or more of the ExtSaveMapFile, ExtLoadMapFile, ExtSaveTileFile and ExtLoadTileFile functions, and these functions needed to be included in the plugin's EXPORTS table. For Zeolite v11.08, these functions must be been renamed zeoSaveMapFile, zeoLoadMapFile, zeoSaveTileFile and zeoLoadTileFile, they must be declared with the zeoexport keyword, and they do not need to be included in the EXPORTS table.

The old and new function prototypes are given below:

zeoSaveMapFile

New
zeoexport bool __stdcall zeoSaveMapFile(ZMAP hMap, LPCSTR lpFileName, ZFORMAT hFormat, ZVAR hProgWnd);
Old
bool __stdcall ExtSaveMapFile(ZMAP hMap, LPCSTR lpFileName, ZFORMAT hFormat, ZVAR hProgWnd);

zeoLoadMapFile

New
zeoexport bool __stdcall zeoLoadMapFile(ZMAP hMap, LPCSTR lpFileName, long MapTypeID, ZFORMAT hFormat, ZVAR hProgWnd);
Old
bool __stdcall ExtLoadMapFile(ZMAP hMap, LPCSTR lpFileName, long MapTypeID, ZFORMAT hFormat, ZVAR hProgWnd);

zeoSaveTileFile

New
zeoexport bool __stdcall zeoSaveTileFile(ZMAP hMap, LPVOID hTile, LPCSTR lpFileName, ZFORMAT hFormat);
Old
bool __stdcall ExtSaveTileFile(ZMAP hMap, LPVOID hTile, LPCSTR lpFileName, ZFORMAT hFormat);

zeoLoadTileFile

New
zeoexport bool __stdcall zeoLoadTileFile(ZMAP hMap, LPVOID hTile, LPCSTR lpFileName, ZFORMAT hFormat);
Old
bool __stdcall ExtLoadTileFile(ZMAP hMap, LPVOID hTile, LPCSTR lpFileName, ZFORMAT hFormat);

zfunc_Load

The CExtAPI::zeofunc_LoadFunc and CExtAPI::zeofunc_LoadFuncEx functions have been replaced by zfunc_Load. The function prototype and usage of zfunc_Load is otherwise identical to the old CExtAPI::zeofunc_LoadFuncEx function.

zmenu_InsertItem

The function for adding menu items was changed from CExtAPI::menu_InsertItem2 to zmenu_InsertItem, which was moved to the 'zMenu.h/cpp' files, and the function prototypes are given below:

New long zmenu_InsertItem(const char* lpScript, const char* lpItemText, unsigned long MenuContext, unsigned long Flags)
Old long CExtAPI::menu_InsertItem2(const char* lpFnName, const char* lpItemText, unsigned long MenuContext, unsigned long Flags)

You will note that all the arguments are the same, except for the first (lpScript vs. lpFnName). In previous versions of Zeolite, menu items could only be added as calls to a single extension function specified by lpFnName. In Zeolite v11.08, menu items now run complete script (specified by lpScript, and in the ZeoScript language), which may call multiple functions. To translate from lpFnName to lpScript, you only need to update the function name to include the full namespace for the function as loaded using zfunc_Load.

zvar_Create, zvar_CreateShared and zvar_GetSharedVar

In previous versions of Zeolite, the following functions were used to create private variables, create shared variables, and retrieve handles to shared variables:

ZVAR CExtAPI::var_CreateTemp(long VarID) Creates a private variable.
ZVAR CExtAPI::var_Create(long VarID, const char* lpVarName) Creates a shared variable.
ZVAR CExtAPI::var_GetVar(const char* lpVarName) Retrieves handle to shared variable.

In Zeolite v11.08, these functions have been renamed to:

ZVAR zvar_Create(long VarID) Creates a private variable.
ZVAR zvar_CreateShared(long VarID, const char* lpVarName) Creates a shared variable.
ZVAR zvar_GetSharedVar(const char* lpVarName) Retrieves handle to shared variable.

These changes were made to reflect the observation that it is far more common to create private variables than it is to create shared variables. Consequently, this change marks the functions used to handle shared variables explicitly (zvar_CreateShared and zvar_GetSharedVar), whilst the default function for creating variables is unadorned (zvar_Create).

Private or shared

The difference between shared and private variables is that shared variables may be accessed by other plugins or by L3DT directly by using the zvar_GetSharedVar function, at any time, and without the knowledge or permission of the plugin that created the variable. In contrast, private variables may only be accessed by the handle returned by zvar_Create, which is given only to the plugin that creates the variable, and may only be used by other plugins if the creator plugin explicitly provides the variable handle to another plugin’s function.

Historical note

In the very earliest versions of Zeolite, plugins could exchange data only by storing and retrieving shared variables. With the advent of extension functions in Zeolite v1.2, plugins could exchange data using a more controlled and functional mechanism. Consequently, shared variables have largely fallen into disuse.

zfile functions

All the file name helper functions previously included in the CExtAPI class (listed below) have been spun out to the 'zFile.h/cpp' files.

These functions have also been renamed; for instance the function for trimming the directory path from a filename has been renamed from CExtAPI::file_GetFilenameNoDir to zfile_TrimDir. All other file helper functions have been similarly renamed with a name prefixed by zfile_. Importantly, the order of arguments for these functions have been changed so that the output result string (ZSTR hResult) is now the last argument, rather than the first. This means that a simple search-and-replace operation should not be performed for converting CExtAPI::file_ function calls to zfile_ function calls, because the operation will not change the argument order as required.

The prototypes of some of the more commonly-used file helper functions are listed below:

zfile_GetExt

New bool zfile_GetExt(const char* lpFileName, ZSTR hResult);
Old bool CExtAPI::file_GetExt(ZSTR hStr, const char* lpFileName);

zfile_GetDir

New bool zfile_GetDir(const char* lpPathName, ZSTR hResult);
Old bool CExtAPI::file_GetDir(ZSTR hStr, const char* lpFileName);

zfile_TrimExt

New bool zfile_TrimExt(const char* lpFileName, ZSTR hResult);
Old bool CExtAPI::file_GetFilenameNoExt(ZSTR hStr, const char* lpFileName);

zfile_TrimDir

New bool zfile_TrimDir(const char* lpFileName, ZSTR hResult);
Old bool CExtAPI::file_GetFilenameNoDir(ZSTR hStr, const char* lpFileName);

Combination, file and directory selectors

The CzComboSel, CzFileSel and CzSirSel classes are all conceptually similar, in that they all provide a simple user interface to allow users to select:

  • an item or combination of items from a list (combosel),
  • a file from a file selection window (filesel), and;
  • a directory from a directory selection window (dirsel).

However, they were implemented at different times, and their member function names were not entirely consistent. This has been fixed in Zeolite v11.08, as detailed below:

filesel

  • The CExtAPI::filesel_InitFS function was renamed zfilesel_Init, with no changes to arguments or return values.
  • The CExtAPI::filesel_GetFilename function was renamed zfilesel_GetPathA, the return type was changed to bool, and a ZSTR hReturnStr argument was added.

The function prototypes are given below:

New:

bool zfilesel_Init(ZVAR hFileSel, bool OpenFileFlag, const char* lpFileName, const char* lpFilterStr, const char* lpDefaultExt, const char* lpDefaultDir);
bool zfilesel_GetPathA(ZVAR hFileSel, ZSTR hReturnStr);

Old:

bool CExtAPI::filesel_InitFS(ZVAR hFileSel, bool OpenFileFlag, const char* lpFileName, const char* lpFilterStr, const char* lpDefaultExt, const char* lpDefaultDir);
const char* CExtAPI::filesel_GetFilename(ZVAR hFileSel);

Corresponding changes were made to the CzFileSel class.

dirsel

  • The CExtAPI::dirsel_InitDS function was renamed zdirsel_Init, with no changes to arguments or return values.
  • The CExtAPI::dirsel_GetDirname function was renamed zdirsel_GetPathA, the return type was changed to bool, and a ZSTR hReturnStr argument was added.

The function prototypes are given below:

New:

bool zdirsel_Init(ZVAR hDirSel, const char* lpStartDir);
bool zdirsel_GetPathA(ZVAR hDirSel, ZSTR hReturnStr);

Old:

bool CExtAPI::dirsel_InitDS(ZVAR hDirSel, const char* lpStartDir);
const char* CExtAPI::dirsel_GetDirname(ZVAR hDirSel);

Corresponding changes were made to the CzDirSel class.

combosel

  • The CExtAPI::combosel_InitCS function was renamed combosel_Init, with no changes to arguments or return values.
  • The CExtAPI::combosel_GetCurSel function was renamed zcombosel_GetCurSelA (i.e. get current selection, as ASCII text), the return type was changed to bool, and a ZSTR hReturnStr argument was added.
  • The CExtAPI::combosel_SetCurSel function was renamed zcombosel_SetCurSelA (i.e. set current selection, as ASCII text), with no changes to arguments or return values.
  • The CExtAPI::combosel_GetOptions function was renamed zcombosel_GetOptionsA (i.e. get options list, as pipe '|' delimited ASCII text), the return type was changed to bool, and a ZSTR hReturnStr argument was added.
  • The CExtAPI::combosel_SetOptions function was renamed zcombosel_SetOptionsA (i.e. set options list, as pipe '|' delimited ASCII text), with no changes to arguments or return values.

The function prototypes are given below:

New:

bool zcombosel_Init(ZVAR hComboSel, const char* lpOptionsStr, const char* lpCurSelStr);
bool zcombosel_GetCurSelA(ZVAR hComboSel, ZSTR hReturnStr);
bool zcombosel_SetCurSelA(ZVAR hComboSel, const char* lpCurSelStr);
bool zcombosel_GetOptionsA(ZVAR hComboSel, ZSTR hReturnStr);
bool zcombosel_SetOptionsA(ZVAR hComboSel, const char* lpOptionsStr);

Old:

bool CExtAPI::combosel_InitCS(ZVAR hComboSel, const char* lpOptionsStr, const char* lpCurSelStr);
const char* CExtAPI::combosel_GetCurSel(ZVAR hComboSel);
bool CExtAPI::combosel_SetCurSel(ZVAR hComboSel, const char* lpCurSelStr);
const char* CExtAPI::combosel_GetOptions(ZVAR hComboSel);
bool CExtAPI::combosel_SetOptions(ZVAR hComboSel, const char* lpOptionsStr);

Furthermore, two new functions were added to allow developers to get and set the current selection by index, rather than by text string. These functions are:

long zcombosel_GetCurSelI(ZVAR hComboSel);
bool zcombosel_SetCurSelI(ZVAR hComboSel, long CurSelID);

Corresponding changes were made to the CzComboSel class.

zvar_GetValueText and zvar_SetValueText

The functions for getting and setting the value of a variable using a text string have been renamed from CExtAPI::var_GetValueA and CExtAPI::var_SetValueA to zvar_GetValueText zvar_SetValueText. This change change is intended to make their purpose more obvious.

Virtual mosaic maps

A major change in L3DT v11.08 is that the program now takes a more active role in map memory management. Previously, developers could call CExtAPI::map_Init to allocate an in-RAM map, or CExtAPI::map_InitMosaic to allocate a dynamically paged mosaic map. Now, to prevent memory exhaustion in projects with many large maps, L3DT may disregard the caller's preference and split 'large' maps allocated by zmap_Init into virtual mosaic maps, where 'large' is arbitrary, unspecified and subject to change. Virtual mosaic maps, when loaded into L3DT, function exactly like conventional mosaic maps, but are loaded from and saved to single map files, just like in-RAM maps.

You can determine how a map is allocated in memory using the zmap_GetAllocMode function, which returns the following possible values:

Symbol Value (hex) Description
MAPALLOC_INVALID 0x0 The map is not allocated.
MAPALLOC_RAM 0x00000001 The map is allocated in a contiguous block of RAM.
MAPALLOC_MOSAIC 0x00000002 The map is allocated as a mosaic, and is saved to disk with a mosaic master file.
MAPALLOC_MOSAIC_TEMP 0x00000004 The map is allocated as a mosaic map that is temporarily stored in the applications temp folder. When saved, the map will be written to a single map file, as with MAPALLOC_RAM maps.
MAPALLOC_MOSAIC_SYSPAGEFILE 0x00000010 Same as MAPALLOC_MOSAIC_TEMP, but the mosaic is backed by the system pagefile.
MAPALLOC_MOSAIC_MEMMAPFILE 0x00000020 Same as MAPALLOC_MOSAIC_TEMP, but the mosaic is backed by a large memory-mapped raw file.

To force a particular type of memory allocation for a map, use the new zmap_Init2 function, the prototype of which is given below:

bool zmap_Init2(ZMAP hMap, long nx, long ny, long MapTypeID, float HorizScale, bool WrapFlag, unsigned long AllocMode, long TileSize);

This function is comparable to the zmap_Init function, but it also takes an argument AllocMode for the allocation mode (see table above), and an argument TileSize for the virtual mosaic tile size, if MAPALLOC_MOSAIC_TEMP, MAPALLOC_MOSAIC_SYSPAGEFILE or MAPALLOC_MOSAIC_MEMMAPFILE are selected.

Please note that the zmap_GetMosaicFlag function will return true if the map is split into tiles as a mosaic (MAPALLOC_MOSAIC) or virtual mosaic (MAPALLOC_MOSAIC_TEMP, MAPALLOC_MOSAIC_SYSPAGEFILE or MAPALLOC_MOSAIC_MEMMAPFILE), and false if the map is allocated as a single block of memory (MAPALLOC_RAM).

64-bit version

The 64-bit version of L3DT Professional requires plugins to be recompiled for the x64 architecture. No code changes should be required when recompiling a plugin in 64 bit mode, at least as far as using the plugin API is concerned. However, the output plugin file must have an extension of '.x64.zeo'.

Other miscellaneous functions

Various other functions have been renamed slightly. Often this is due to the fact that the old deprecated functions have been finally removed from Zeolite, which has allowed the replacement functions to be renamed. For instance, the CExtAPI::map_GenMipmaps2 function, which previously replaced the defective CExtAPI::map_GenMipmaps function, has now become zmap_GenMipmaps. Another example is CExtAPI::menu_InsertItemEx, which is now zmenu_InsertItem. In most instances, unless noted elsewhere on this page, the replacement function name should be obvious by looking in the relevant header file (usually 'zeolite.h').

Check your scripts

If you plugin uses scripts, it is likely that they will need to be updated also. The names of many script functions have been changed to better match those of the Zeolite API functions. Also, many file format related functions were moved into the 'file' namespace, whilst user interface related functions moved into the 'UI' namespace. To browse through the names of the available functions, I recommend you use the 'function browser' tool in the script editor.

Have I missed anything?

If you find that this tutorial does not cover an important aspect of updating your plugin to Zeolite v11.08, please e-mail aaron@bundysoft.com for assistance.

 
tutorials/zeolite/upgrade_to_v3.txt · Last modified: 2017/08/31 05:23 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki