Programming - Frequently Asked Questions

Q. I'm writing a DLL that calls engine functions. However every function call crashes immediately. I can see in the VC++ debugger that the engine functions seem to have strange adresses and don't lead to any useful code.
A. Probably you've accidentally defined DLL_USE before including adll.h. Yes, you're writing a DLL, but DLL_USE is for engine plugins only, and expects the plugin library to set up the engine function pointers. When you don't write a plugin, don't define DLL_USE. Just follow the examples in the manual.

Q. Can I call the wait() function in C++?
A. The wait() function is specific to the multitasking of the lite-C language. In C++ or C# you're most likely writing a single task program, and can't call wait(). But you can sort of emulate it. In the main game loop, calling engine_frame() is equivalent to wait(1). In entity functions, use the ENABLE_FRAME event to call the function every frame, which emulates a loop with a wait(1) at the end.

Q. I've written a DLL and am calling DLL functions from lite-C. I've placed the DLL right in the work folder, and the functions seem to work - but afterwards I'm getting a crash error message! This is my simple code for declaring and calling a DLL function - I've just copied the declaration from the windows.h header:

void WINAPI myFunction(int i); // declare function prototype
API(Test,myDLL) function main() { myFunction(777); // call the DLL function }

A. You've copied a little too much - remove the "WINAPI", as you've probably defined your DLL function without __stdcall modifier. This leads to a crash because the stack is not restored.

Q. I'm calling engine functions from C++. However the functions don't do what I want - as if they don't accept my parameters. The same functions work when I call them from lite-C. What can be the reason?
A. You've probably forgotten to use the _VAR macro (read Getting Started to learn about C++ and how to write a plugin). Lite-C knows the difference between int and var, but C++ doesn't. So either use _VAR or include a var class in your C++ code. A var class (var.h) handles int->var conversion automatically.

Q. How can I assign a C++ function like an action to entities? WED only recognizes script actions and I don't want to write a script.
A. Use the ent_next function to scan through the list of your entities. Or use ent_for_name or ent_for_file to get the pointer to a particular entity. For assigning an action to that entity, set its DYNAMIC flag and its ENABLE_FRAME flag, and set it's event parameter to the function pointer. Your function is now called every frame by all entities it's assigned to. Example:

ENTITY* pEntity = ent_for_name("cube_mdl_058"); // find the entity pointer
pEntity->emask |= DYNAMIC | ENABLE_FRAME;
pEntity->event = my_function;

Q. How can I create a STRING for engine functions that need a STRING* argument?
A. All script objects must be created by their create functions - thus you'd need str_create, just defining a STRING struct won't do. However, most engine functions also accept char* as parameter. Thus you normally won't use STRINGs at all outside the script language.

Q. How can I render models with my own rendering function, instead of using the engine renderer?
A. Write a function that renders a DirectX mesh, like this:

int Render_Entity(void)
{
// Get pointers to all objects you need
ENTITY* pEntity = (ENTITY*)(ev->me);
BMAP* pSkin = (BMAP*)(ev->render_map[0]);
LPD3DXMESH pMesh = (LPD3DXMESH)(ev->render_mesh);
D3DMATERIAL9* pMaterial = (D3DMATERIAL9*)(ev->render_d3dmaterial);
LPD3DXEFFECT pEffect = (LPD3DXEFFECT)(ev->render_d3dxeffect);
IDirect3DDevice9* pd3dDevice = (IDirect3DDevice9*)(ev->pd3ddev);
// now render it ...
// tell the engine not to render the entity again
return 1024;
}

Then you need to assign the function to the entities' material event, and set the ENABLE_RENDER flag and a dummy effect. Models use mat_model by default, so:

void Render_Init(void)
{
  ev->mat_model->event = (EVENT)Render_Entity;
  ev->mat_model->flags |= ENABLE_RENDER;
  ev->mat_model->effect = "technique dummy { pass { } }";
}

Q. I've written a plugin DLL, but it is only loaded on my own PC. It is not loaded on another PC where I copied my published project to.
A. Make sure that the DLL is in the work folder (containing the executable) of the target system, and also make sure that the target system contains all other DLL libraries - for instance, MFC, VC++ runtime, DirectX, CODECs, fonts, etc. - that your DLL uses. For distributing your project, make sure to include an installer or merge module for those libraries. The most frequent reason for a DLL not working on another system is using MFC, which needs the VC++ runtime libraries that are normally not present on a PC where VC++ is not installed.

► latest version online