Reviews & Opinions
Independent and trusted. Read before buy Conitec 3D Gamestudio - A4!

Conitec 3D Gamestudio - A4


Bookmark
Conitec 3D Gamestudio - A4

Bookmark and Share

 

Conitec 3D Gamestudio - A4About Conitec 3D Gamestudio - A4
Here you can find all about Conitec 3D Gamestudio - A4 like manual and other informations. For example: review.

Conitec 3D Gamestudio - A4 manual (user guide) is ready to download for free.

On the bottom of page users can write a review. If you own a Conitec 3D Gamestudio - A4 please write about it to help other people.
[ Report abuse or wrong photo | Share your Conitec 3D Gamestudio - A4 photo ]

 

 

Manual

Preview of first few manual pages (at low quality). Check before download. Click to enlarge.
Manual - 1 page  Manual - 2 page  Manual - 3 page 

Download (English)
Conitec 3D Gamestudio-A4 - Programmer S Manual, size: 177 KB

 

Conitec 3D Gamestudio - A4

 

 

User reviews and opinions

<== Click here to post a new opinion, comment, review, etc.

Comments to date: 3. Page 1 of 1. Average Rating:
tonyr1988 11:03pm on Monday, September 6th, 2010 
My Company uses Citrix, so I am able to run Windows Applications, SAP, even flash and all my GO TO corporate applications on the device. The iPad is exactly what I expected, easy to use, very well executed so long as you understand that it is mainly a device to consume media.
Elvensight 8:45pm on Wednesday, June 30th, 2010 
PROS: OS, look, Awesomeness ITs great, and the idea is well along with the OS its a Mac downsized. its size is a bit big Bought the 16G WiFi for my wife. She enjoys playing games, surfing the web, reading books, reading email and catching up on her Soaps at ABC.com.
BDoc 7:19pm on Saturday, June 26th, 2010 
I replaced my first-gen iPod Touch, which I had since they first came out a few years ago, with this new beast of a device. First of all.

Comments posted on www.ps2netdrivers.net are solely the views and opinions of the people posting them and do not necessarily reflect the views or opinions of us.

 

Documents

doc0

// plugin.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }
That's the main entry point of your DLL and you can leave that function unchanged. Copy all of the SDK files (except the Borland/Delphi subfolders of course) into the folder that is created by VC++. Now for compiling an A5 plugin DLL, you have to link the a5dll.lib (one of the files of the SDK) to the project (Project Properties -> Linker Input -> Additional Dependencies), and include the a5dll.h and a5funcs.h files to your main.cpp file. These 3 files are what you need for creating A5 DLLs. You can see in the ackdll.cpp example how it should look like.
Now you can begin to add functions to the DLL that can then later be called by a script, or by the main function of your game. To be recognized by the engine, all such functions must be of type DLLFUNC fixed function(.), like this:
// returns the value of x * 2n DLLFUNC fixed ldexp(fixed x,fixed n) { return (FLOAT2FIX(FIX2FLOAT(x)*pow(2.0,FIX2FLOAT(n)))); }
This example function just returns an arithmetic expression of its arguments. DLLFUNC is not a part of C++ - it's just a convenience shortcut for declaring DLL export functions. fixed is the all-purpose numeric variable type of A5 and C-Script - a long integer that can be used either as 22.10 fixed point value, or as a pointer. Both are declared in the a5dll.h together with some conversion functions:
#define DLLFUNC extern "C" __declspec(dllexport) typedef long fixed; // fixed inline fixed INT2FIX(int i) { inline int FIX2INT(fixed x) { inline double FIX2FLOAT(fixed inline fixed FLOAT2FIX(double point 22.10 number format used by C-Script return i<<10; } return x>>10; } x) { return ((double)x)/(1<<10); } f) { return (fixed)(f*(1<<10)); }
The engine will pass and expect all numbers coordinates, variables, no matter what in fixed type. So convert any number to fixed before you return it to the engine, like in the example above. Ready? Now compile your DLL let's assume that you named it plugin.dll and copy it into your work folder. How can we now call our ldexp function by a script? We have to do two things: declare the function, and open the DLL. The first is achieved by a dllfunction prototype in the script:

dllfunction ldexp(x,n); // declaration of a DLL function
This makes our ldexp function known to C-Script. Before we can call it, we have to open the DLL. A good place to do this is the main() function of your script:
function main() {. dll_open("plugin.dll");
and do not forget to close the DLL before exiting the game:
. dll_close(dll_handle); exit; // just use the default handle as long as there's only one DLL
After this is done, you can now enjoy that C-Script has gotten one extra instruction:
. x = ldexp(y,n); // calculates x = y * 2n.
For debugging your DLL in VC++, set the command in Project Properties -> Debug to the engine EXE path (like "C:\program files\gstudio\bin\acknex.exe"), the command arguments to your script and command line parameters (like "mygame.wdl -wnd") and the working directory to your game directory (like "C:\program files\gstudio\mygame"). In Project Properties -> General, set the output directory and the intermediate directory to. (a period, meaning the working directory) for the engine to find the intermediate files. Then you can compile and debug your DLL by setting breakpoints as usual. Ok, this was the basics of writing plugin DLLs. Of course, there's a lot more to learn. The methods for exchanging data with the engine are described in the following. All DLL functions can be declared and called in scripts just like each other C-Script function, after having activated the DLL through the dll_open and dll_close instructions described in the script manual.
Using C-Script objects in a DLL
We have learned how to add new C-Script instructions, but how can we access C-Script variables, objects and functions from within a DLL? We have some library functions to do that. All library functions provided by the SDK are preceded by a5dll_. The most often used function is
long a5dll_getwdlobj(char *name);
This function returns the address of the C-Script object or variable with the given name. It can be used to read or write any defined C-Script object from inside a DLL plugin. If the object does not exist, NULL is returned and an error message will pop up. Examples for DLL functions that access C-Script objects:
// adds the given value to a C-Script vector fixed AddToVector(fixed value) { // get the address of the variable fixed *myvector = (fixed *)a5dll_getwdlobj("myvector"); // add the same value to the 3 components myvector[0] += value; myvector[1] += value; myvector[2] += value; return value; }

// returns free distance in front of MY entity until next obstacle fixed DistAhead(long p_ent) { if (!my) return 0; // retrieve the pointer to the given entity A4_ENTITY *ent = (A4_ENTITY *)p_ent; // get the address of some script variables and functions fixed *tracemode = (fixed *)a5dll_getwdlobj("trace_mode"); wdlfunc2 vecrotate = (wdlfunc2)a5dll_getwdlfunc("vec_rotate"); wdlfunc2 trace = (wdlfunc2)a5dll_getwdlfunc("trace"); fixed target[3] = { FLOAT2FIX(1000.0),0,0 }; // trace target vector // rotate vector by entity engles, just as in C-Script (*vecrotate)((long)target,(long)&(ent->pan)); // add entity position to target target[0] += ent->x; target[1] += ent->y; target[2] += ent->z; // set trace_mode, then trace a line between entity and target, // and return the result *tracemode = INT2FIX(TRM_IGNORE_ME + TRM_IGNORE_PASSABLE + TRM_USE_BOX); return (*trace)((long)&(ent->x),(long)target); }
Let's examine the important part of the code in detail:
wdlfunc2 vecrotate = (wdlfunc2)a5dll_getwdlfunc("vec_rotate");
wdlfunc2 is a convenience typedef for a pointer to a C-Script instruction that takes 2 arguments.
Because all C-Script instructions take either 1, 2, 3, or 4 arguments, there are 4 such typedefs in the a5dll.h:
fixed fixed fixed fixed (*wdlfunc1)(long); (*wdlfunc2)(long,long); (*wdlfunc3)(long,long,long); (*wdlfunc4)(long,long,long,long);
typedef typedef typedef typedef
Once we've gotten the pointer to that instruction again, it's recommended to retrieve pointers to all used instructions in a startup function we can just call it:
// rotate vector by entity engles, just as in C-Script (*vecrotate)((long)target,(long)&(ent->pan));
This looks a little different than you are used to call a function in C++! However, it's quite straightforward: We have a pointer to that function, so for calling the function itself we have to use the (*.). And the arguments passed are always fixed or long. We have casted them to long instead of fixed as a convention to indicate that we are passing pointers. All vector instructions expect pointers to fixed. All this pointer handling and typecasting may seem a little complicated at first, but because it's logical you'll fast get the grip of it.
What if a C-Script instruction expects not a vector or value, but something more complicated like an entity? Well, we'll then just pass the A4_ENTITY pointer casted to long. And what if it expects a string must we really use a pointer to A4_STRING or can we just pass char*? We must use A4_STRING I'm afraid. But in the example ackdll.cpp you can find an easy way how to pass a string constant to a C-Script instruction:

long pSTRING(char* chars) // convenience function to make string passing easy { static A4_STRING tempstring; static char tempname[256]; strncpy(tempname,chars,255); tempstring.chars = tempname; return (long)&tempstring; } // example for passing a string to create an entity DLLFUNC fixed create_warlock(long vec_pos) { wdlfunc3 ent_create = (wdlfunc3)a5dll_getwdlfunc("ent_create"); return (*ent_create)(pSTRING("warlock.mdl"),vec_pos,0); }
Some special C-Script functions, like keyboard entry, can not be called directly from a DLL. However they can be executed indirectly by calling a script that executes that function. Scripts can be called from a DLL through the following functions:
long a5dll_getscript(char *name);
This function returns an addresss of the user-defined script function with the given name. It can be used to call user defined C-Script actions or functions from inside a DLL plugin. If the function is not found, NULL is returned and an error message will pop up.
fixed a5dll_callscript(long script,long p1=0,long p2=0,long p3=0,long p4=0); fixed a5dll_callname(char *name,long p1=0,long p2=0,long p3=0,long p4=0);
These functions call a user-defined script function with given address or given name. The 4 parameters can be a fixed point number, an array, or a pointer to a C-Script object. If the function expects less than 4 parameters, the superflous ones can just be set a 0. Example for a DLL function that calls a function that must be defined in the C-Script code:
DLLFUNC fixed WDLBeep(fixed value) { // get the function long beeptwice = a5dll_getscript("beeptwice"); // call it return a5dll_callscript(beeptwice,0,0,0,0); }
This DLL function expects the following function in the C-Script which is then called:
function beeptwice() { beep; beep; } // in the script
Now that we have learned to access every part of C-Script by a DLL and vice versa, let's continue with some special applications for DLL functions.

Using Direct3D functions

The following example shows how easy it is to use Direct3D functions for creating some effects on the screen. As all initialization is done by the engine, it is sufficient just to call the draw functions. All Direct3D functions are accessed through a LPDIRECT3DDEVICE8 pointer that is available through the DLL. For details refer to the DirectX documentation that is available, along with the DirectX 8.1 SDK, from the Microsoft site. The example paints a multicolored triangle onto the screen. You'll see the triangle briefly flashing in the upper left corner when you call PaintD3DTriangle() once. If you call it in a wait(1)-loop, the triangle will be permanently on the screen.

#include <d3dx8.h> // from the DIRECTX8.1 sdk // dllfunction PaintD3DTriangle(); // draws a red/blue/green triangle in D3D mode DLLFUNC fixed PaintD3DTriangle (void) { // get the active D3D device LPDIRECT3DDEVICE8 pd3ddev = (LPDIRECT3DDEVICE8) a5dx->pd3ddev8; if (!pd3ddev) return 0; // define a suited vertex struct struct VERTEX_FLAT { float x,y,z; float rhw; D3DCOLOR color; }; #define D3DFVF_FLAT (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) // define the three corner vertices VERTEX_FLAT v[3]; v[0].x = 10.0; v[0].y = 10.0; v[0].color = 0xFFFF0000; // the red corner v[1].x = 310.0; v[1].y = 10.0; v[1].color = 0xFF0000FF; // the blue corner v[2].x = 10.0; v[2].y = 310.0; v[2].color = 0xFF00FF00; // the green corner v[0].z = v[1].z = v[2].z = 0.0; // z buffer - paint over everything v[0].rhw = v[1].rhw = v[2].rhw = 1.0; // no perspective // begin a scene - needed before D3D draw operations pd3ddev->BeginScene(); // set some render and stage states (you have to set some more, normally) pd3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); pd3ddev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE); pd3ddev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG2); // now draw the triangle pd3ddev->SetVertexShader(D3DFVF_FLAT); pd3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,1,(LPVOID)v,sizeof(VERTEX_FLAT)); // do not forget to do a clean closing of the scene pd3ddev->EndScene(); return 0; }
Note: Depending on the 3D hardware, sometimes A5 has to release and reallocate the Direct3D device when the video output is switched between window and fullscreen mode. If you use the pd3ddev8 for allocating an object, like a texture or a buffer, you have to release the object before switching video, and recreate it afterwards. Otherwise the device can't be released and you'll receive an Uninitialized Device error message. Particle functions DLL functions can also be used for particles, using the A4_PARTICLE struct defined in a5dll.h. They can be used the same way as C-Script defined particle functions. A pointer to the particle is the sole argument of a DLL particle function. Example:
// examples for a particle effect function // dllfunction DLLEffect_Explo(particle); // dllfunction DLLPart_Alphafade(particle);
// start the particle effect by // effect(DLLEffect_Explo,1000,my.x,nullvector); fixed *var_time = NULL; long func_alphafade = 0; // helper function: fades out a particle DLLFUNC fixed DLLPart_Alphafade(long particle) { if (!var_time || !particle) return 0; A4_PARTICLE* p = (A4_PARTICLE*) particle; p->alpha -= *var_time * 2; if (p->alpha <= 0) p->lifespan = 0; return 0; } // helper function: return a random float float random(float max) { return (float)(rand()*max)/(float)RAND_MAX; }

// particle effect: generate a blue explosion DLLFUNC fixed DLLEffect_Explo(long particle) { if (!particle) return 0; // initialize time var and alphafade function (must only be done once) if (!var_time) var_time = (fixed *)a5dll_getwdlobj("time"); if (!func_alphafade) func_alphafade = a5dll_getscript("DLLPart_Alphafade"); A4_PARTICLE* p = (A4_PARTICLE*) particle; // initialize particle parameters p->flags |= EPF_STREAK|EPF_MOVE|ENF_FLARE|ENF_BRIGHT; p->vel_x = FLOAT2FIX(random(10) - 5); p->vel_y = FLOAT2FIX(random(10) - 5); p->vel_z = FLOAT2FIX(random(10) - 5); p->red = 0; p->green = 0; p->blue = INT2FIX(255); p->alpha = FLOAT2FIX(50 + random(50)); p->function = func_alphafade; return 0; }
Sending information over the network The SDK can use A5's send and receive functions for sending user-defined messages in a multiplayer environment. For this, the SendPacket and ReveivePacket function pointers are available via the ENGINE_INTERFACE:
typedef struct { byte *save_block;// pointer to block of variables for save/load (not used) int save_size; // size of block of variables for saving (not used) long (*Exec)(long n,long p1,long p2,long p3); // DLLLIB internal use only // only available in A5.51 or above - first packet byte must be 17 (0x11) for user defined packets void (*SendPacket)(long to,void *data,long size,long guaranteed); // the send function of the engine void (*ReceivePacket)(long from,void *data,long size); // user provided function } ENGINE_INTERFACE;
SendPacket sends a user defined packed from the client to the server, or vice versa.
Parameters: to - Identifier number for the client to receive the message. Set to 0 for sending to all clients. data - Data packet to be sent. First byte must be 17 (0x11) for identifying a user-defined packet. size - Size of the packet in bytes. guaranteed - set to 1 for TCP/IP mode, 0 for UDP mode.
ReceivePacket can be set to a user provided void(long,void*,long) function that receives and interprets messages sent with SendPacket.
Parameters: from ID Number of the sender. If at 0, the message was received from the server. data - Data packet to be sent. First byte is always 17 (0x11) for identifying a user-defined packet. size - Size of the packet in bytes. Note that the receive function should be very short and mainly just store the message, for not interfering the receive process. It must not send, open a file, render, or do anything time consuming. Programming a game in C++ Using the A4_ENTITY object (see below), a DLL can implement complex AI functions that would be harder to code in C-Script. Even the whole gameplay could be written in a DLL. The following example shows how to change entity parameters through a DLL function.

// rolls the given entity by 180 degrees DLLFUNC fixed FlipUpsideDown(long entity) { if (!entity) return 0; // retrieve the pointer to the given entity A4_ENTITY *ent = (A4_ENTITY *)entity; // set the entity's roll angle to 180 degrees ent->roll = FLOAT2FIX(180); return 0; }
This would be called by C-Script through FlipUpsideDown(my). For controlling entities totally through a DLL for instance, when you intend to write your whole game in C++ or Delphi, instead of C-Script C-Script dummy actions can be assigned to the entity, like this:
var appdll_handle; dllfunction dll_entmain(entity); dllfunction dll_entevent(entity); function main() { // open the application DLL appdll_handle = dll_open("myapp.dll");. } action myent_event { dll_handle = appdll_handle; dll_entevent(my); // this DLL function handles all entity events } action myentity { my.event = myent_event; while(1) { dll_handle = appdll_handle; dll_entmain(my); // this DLL function controls the entity wait(1); } }
DLL interface structures and special functions
Interface structs are initialized at DLL startup for accessing essential engine variables and pointers. There are three such interfaces, which are defined in the a5dll.h: the WDL_INTERFACE a5wdl that contains C-Script access functions and he MY and YOU entity pointers, the ENGINE_INTERFACE a5eng that contains basic engine functions, and the DX_INTERFACE a5dx that contains pointers to all DirectX devices initialized by A5. Normally you'll only need the last one. For instance, a5dx>pd3ddev8 will get you the pointer to the Direct3D 8.1 device. Some utility functions are provided for manipulation of textures and entities:
A4_TEX *a5dll_tex4ent(A4_ENTITY *entity,int frame,int texnum=0);
This function returns the texture of a sprite, model or terrain entity. It can be used to directly access D3D textures (see example below). Frame is the frame or skin number, texnum the subtexture number if it is split into several subtextures.
A4_ENTITY *a5dll_entnext(A4_ENTITY *entity);
This function enumerates local entities, and can be used to access all entities in a level. If called with NULL, it returns a pointer to the first entity in the level. If called with a level entity pointer, it returns a pointer to the next level entity. If called with a pointer to the last entity or no entity at all, it returns NULL. Example for a function that uses DirectX 8.1 for painting the textures of model, sprite and terrain entities red:

// dllfunction PaintEntitiesRed(); // paints the first mipmap of all sprite and model entities red DLLFUNC fixed PaintEntitiesRed(void) { // find the first entity in the level A4_ENTITY *ent = NULL; while (1) { // find the next entity ent = a5dll_entnext(ent); if (!ent) break; // we can not be sure that the entity texture exists - it could be purged A4_TEX *tex = a5dll_tex4ent(ent,0,0); if (!tex) continue; LPDIRECT3DTEXTURE8 dx8tex = (LPDIRECT3DTEXTURE8) tex->pd3dtex; if (!dx8tex) continue; // check the texture format D3DSURFACE_DESC ddsd; if (FAILED(dx8tex->GetLevelDesc(0,&ddsd))) continue; // lock the texture and retrieve a pointer to the surface D3DLOCKED_RECT d3dlr; if (FAILED(dx8tex->LockRect(0,&d3dlr,0,0))) continue; byte *pixels = (byte *)(d3dlr.pBits); // do we have a 16 bit or 32 bit format? if (ddsd.Format == D3DFMT_A8R8G8B8) for (unsigned y = 0; y < ddsd.Height; y++ ) { DWORD *target = (DWORD *)(pixels + y*d3dlr.Pitch); for (unsigned x = 0; x < ddsd.Width; x++ ) *target++ = 0xFFFF0000; // that's red in 8888 } else if (ddsd.Format == D3DFMT_A4R4G4B4) for (unsigned y = 0; y < ddsd.Height; y++ ) { WORD *target = (WORD *)(pixels + y*d3dlr.Pitch); for (unsigned x = 0; x < ddsd.Width; x++ ) *target++ = 0xFF00; // that's red in 4444 } else if (ddsd.Format == D3DFMT_A1R5G5B5) for (unsigned y = 0; y < ddsd.Height; y++ ) { WORD *target = (WORD *)(pixels + y*d3dlr.Pitch);
for (unsigned x = 0; x < ddsd.Width; x++ ) *target++ = 0xFC00; // that's red in 1555
} else if (ddsd.Format == D3DFMT_R5G6B5) for (unsigned y = 0; y < ddsd.Height; y++ ) { WORD *target = (WORD *)(pixels + y*d3dlr.Pitch); for (unsigned x = 0; x < ddsd.Width; x++ ) *target++ = 0xF800; // that's red in 565 } // Unlock the surface again dx8tex->UnlockRect(0); } a5dll_errormessage("Entities are now red!"); return 0; }
void a5dll_errormessage(char *text);
This function pops up an Error #1527 message requester with the given text. It can be used to display diagnostic messages, or notify the user of wrong DLL calls, like with an invalid entity pointer. One final consideration. On accessing system resources like sound, video, joystick and so on, the DLL must take care of possible resource conflicts. The engine shares its resources and expects the same from the code inside the DLL. For instance, code that requires exclusive access to the sound device (like some old MOD players) won't work. Some resources (like the midi player) can't be shared - if midi music is played by the DLL, the engine must not play a midi file at the same time and vice versa.

svc_fill svc_create svc_remove svc_entsound
0x01 0x03 0x04 0x05 Short Entity_Index Short Identifier Short Entity_Index Short Entity_Index Short Sound_Index Scale(2000) Volume Long Sound_Handle Short Action_Index Short Number Position Start[3] Fixed Vel[3]
Created entity with given index (TCP). Removed entity from server (TCP). Play an entity sound on the clients (UDP).

svc_effect

Generate a particle or beam effect on the clients (UDP).

svc_info

Send a sync value and the server time Long 0x11191218 Byte Protocol_Version to the clients (TCP). This is sent once a frame. Float Server_Time Float Frame_Time Send a variable to the client (TCP). Short Var_Index Short Var_Length Fixed Var[Var_Length]

svc_var

svc_string svc_skill
Short String_Index String Text Short Entity_Index Short Struct_Offset Fixed Skill Short Entity_Index Short Struct_Offset Fixed Skill[3] Short Entity_Index Short Function_Index
(Parameters see below) (Parameters see below) (Parameters see below)
Send a string to the client (TCP). Send an entity skill to the client (TCP). Struct_Offset gives the byte offset of the skill in the A4_ENTITY struct. Send an entity vector skill to the client (TCP). Start the given function with the given MY entity on the client (TCP). Update entity parameters 1 (UDP). Update entity parameters 2 (UDP). Update entity parameters 3 (UDP).

svc_skill3

svc_local svc_update1 svc_update2 svc_update3
0x40.0x7f Short Entity_Index 0x80.0xbf Short Entity_Index 0xc0.0xff Short Entity_Index
For the 3 entity parameter update messages, bits 0.5 of the svc_update bytecode give the parameter combination to be sent or received, in the order given below. All parameters are sent through the UDP protocol. Parameter Update.Bit Arguments Remarks XYZ position

position pan tilt roll

2.0 2.1 2.2 2.3
CPosition Pos[3] Angle Pan Angle Tilt Angle Roll
Parameter Update.Bit Arguments

Remarks

Short Frame_Int Scale(1) Frame_Frc Short Nextframe Short Flags 8.23 String File_Name Short Scale[3] Scale(100) Ambient Scale(255) Albedo Byte Skin Scale(2000) Lightrange Scale(255) Red,Green,Blue Scale(100) Alpha Fixed U,V
Frame number, tweening target

tweening

factor,
flags1 type scale ambient albedo skin lightrange color alpha uv
2.5 1.0 1.1 1.3 1.4 1.2 3.0 3.1 3.2 3.3
Name of the mdl, wmb, pcx, etc. file XYZ scale*0.25

Skin number

RBG color packed in 3 bytes
UV offset or speed for entity textures
For instance, the code sequence
0x83 0x07 0x00 0x80 0x00 0x00 0x00 0x01 0x00 0x80 0x01 0x00 0x80 0x00
updates position and pan angle (0x83 has bits 0 and 1 set) of entity No. 7 (0x07 0x00). The position uses the packed format and is set at coordinates x=1 (0x80 0x00 0x00), y=2 (0x00 0x01 0x00) and z=3 (0x80 0x01 0x00), and the pan angle is set at 180 degrees (0x80 0x00).

The MDL5 model format

Despite the engine uses model files with.MDL extension, it's internal MDL5 format differs from the Quake MDL format. A wireframe mesh, made of triangles, gives the general shape of a model. 3D vertices define the position of triangles. For each triangle in the wireframe, there will be a corresponding triangle cut from the skin picture. Or, in other words, for each 3D vertex of a triangle that describes a XYZ position, there will be a corresponding 2D vertex positioned that describes a UV position on the skin picture. It is not necessary that the triangle in 3D space and the triangle on the skin have the same shape (in fact, it is normally not possible for all triangles), but they should have shapes roughly similar, to limit distortion and aliasing. Several animation frames of a model are just several sets of 3D vertex positions. The 2D vertex positions always remain the same. A MDL file contains: - A list of skin textures in 8-bit palettized, 16-bit 565 RGB or 16 bit 4444 ARGB format. - A list of skin vertices, that are just the UV position of vertices on the skin texture. - A list of triangles, which describe the general shape of the model. - A list of animation frames. Each frame holds a list of 3D vertices. - A list of bone vertices, which are used for creating the animation frames. MDL file header Once the file header is read, all the other model parts can be found just by calculating their position in the file. Here is the format of the.MDL file header:

{-0.688191, 0.587785, -0.425325}, {-0.587785, 0.425325, -0.688191}, {-0.425325, 0.688191, -0.587785}, {-0.425325,-0.688191, -0.587785}, {-0.587785,-0.425325, -0.688191}, {-0.688197,-0.587780, -0.425327} };
A whole frame has the following structure:
typedef struct { long type; // 0 for byte-packed positions, and 2 for word-packed positions mdl_trivertx_t bboxmin,bboxmax; // bounding box of the frame char name[16]; // name of frame, used for animation mdl_trivertx_t vertex[numverts]; // array of vertices, either byte or short packed } mdl_frame_t;
is either mdl_trivertxb_t or mdl_trivertxs_t, depending on whether the type is 0 or 2. In the MDL3 format the type is always 0. The beginning of the frames

sizeof(mdl_triangle_t).

MDL bones This is for future expansion of the MDL format, and not supported yet. Bones are a linked list of 3D vertices that are used for animation in the MDL5 format. Each bone vertex can have a parent, and several childs. If a bone vertex is moved, the childs move with it. If on moving a bone vertex the connection line to his parent rotates, it's childs are rotated likewise about the parent position. If the distance of the bone vertex to its parent changes, the change is added onto the distance between childs and parent. So the movement of the childs is done in a spherical coordinate system, it is a combination of a rotation and a radius change. Each bone vertex has an influence on one or more mesh vertices. The mesh vertices influenced by a bone vertex move the same way as it's childs. If a mesh vertex is influenced by several bone vertices, it is moved by the average of the bone's movement. can be found in the.MDL file at offset
The size of each frame is while mdl_trivertx_t
sizeframe = 20 + (numverts+2) * sizeof(mdl_trivertx_t), baseframes = basetri + numtris

The HMP5 terrain format

A terrain is basically a rectangular mesh of height values with one or several surface textures. It is a simplified version of the GameStudio Model format, without all the data structures that are unnecessary for terrain. HMP file header Once the file header is read, all the other terrain parts can be found just by calculating their position in the file. Here is the format of the.HMP file header:
typedef float vec3[3]; typedef struct { char version[4]; long nu1; vec3 scale; vec3 offset; long nu6; float ftrisize_x; float ftrisize_y; float fnumverts_x; long numskins ; long nu8,nu9; long numverts; long nu10; long numframes; long nu11; long flags; long nu12; } hmp_header;

// // // // // // // // // // // // // // // //
"HMP4" or "HMP5"; only the newer HMP5 format is described here not used heightpoint scale factors heightpoint offset not used triangle X size triangle Y size number of mesh coordinates in X direction number of textures not used total number of mesh coordinates not used number of frames not used always 0 not used
The size of this header is 0x54 bytes (84). The "HMP4" format is used by the A5 engine prior to 5.230, while the new "HMP5" format is used by the A5 engine since version 5.230. The number of vertices in the rectangular mesh can be determined by
int numverts_x = (int) fnumverts_x; int numverts_y = numverts/numverts_x;
After the file header follow the textures and then the array of height values. HMP texture format The terrain surface textures are flat pictures. There can be more than one texture. By default, the first texture is the terrain skin, and the second texture is the detail map if it has a different size. Further textures are not used yet. You will find the first texture just after the model header, at offset baseskin = 0x54. There are numskins textures to read. The texture and pixel formats are the same as for MDL skins, and are described in detail in the MDL format description. HMP height values A terrain contains a set of animation frames, which each is a set of height values. Normally only the first frame is used, because terrain does not animate. Each mesh vertex is defined by a height value and a normal.
typedef byte unsigned char; typedef word unsigned short; typedef struct { word z; // height value, packed on 0.65536 byte lightnormalindex; // index of the vertex normal byte unused; // not used } hmp_trivertx_t;
To get the real Z coordinate from the packed coordinates, multiply it by the Z scaling factor, and add the Z offset. Both the scaling factor and the offset can be found in the mdl_header struct. Thus the formula for calculating the real height positions is:
float height = (scale[2] * z) + offset[2];
The X and Y position of the vertes results of the number of the vertex in the mesh, and thus must not be stored. The lightnormalindex field is an index to the actual vertex normal vector, just like in the MDL format description. A whole frame has the following structure:

typedef struct { long type; // always 2 mdl_trivertx_t bboxmin,bboxmax; // bounding box of the frame see mdl description char name[16]; // name of the frame, used for animation hmp_trivertx_t height[numverts]; // array of height values } hmp_frame_t;

doc1

A4 Programmers Manual

Conitec 2000
3D GameStudio A4 Programmer's Manual
1999, 2000 Johann Christian Lotter / Conitec GmbH
This manual is protected under the copyright laws of Germany and the U.S. Any reproduction of the material and artwork printed herein without the written permission of Conitec is prohibited. We undertake no guarantee for the accuracy of the information given. Conitec reserves the right to make alterations or updates without further announcement.

Contents

The A5 DLL interface _________________________________________________________ 4
WDL object structures ____________________________________________________________ 4
The WMP map format ________________________________________________________ 6
Blocks __________________________________________________________________________ 8 Map Properties___________________________________________________________________ 9

The MDL model format

_____________________________________________________ 10
MDL file header _________________________________________________________________ 10 MDL skin format ________________________________________________________________ 11 MDL skin vertices _______________________________________________________________ 11 MDL mesh triangles _____________________________________________________________ 11 MDL frames ____________________________________________________________________ 12 MDL bones _____________________________________________________________________ 13

The A5 DDL interface

DLLs are customer-programmed extensions to the engine and to the WDL language. They can be used with the commercial and professional editions, but can only be created with the SDK (source development kit) that comes with the professional edition. This way, professional edition owners can create arbitrary DLLs for adding new effects, actor AI or WDL instructions, and distribute or sell them to other 3D GameStudio users. The Microsoft Visual C++ development system is required for creating DLL extensions. The DLL SDK contains an interface library that must be linked to any DLL. An example VC++ project with a DLL template is also provided, which makes it pretty easy to create extensions even for not-soexperienced C programmers who have never used DLLs before. DLL extensions work bidirectionally: WDL instructions can access DLL functions, and DLL functions can access essential engine functions and variables. On opening a DLL, the engine transfers the pointer to an internal interface structure to the interface library. The interface contains pointers to engine variables and functions, like the frame buffer, the DirectX interface, the network interface, the DirectInput interface, the level, the WDL functions and so on. Theoretically everything - MP3 or MOD players, a physics engine, another 3D engine or even another scripting language could be added to the engine this way. On accessing system resources like sound, video, joystick and so on, the DLL must take care of possible resource conflicts. The engine shares its resources and expects the same from the code inside the DLL. For instance, code that requires exclusive access to the sound device (like some old MOD players) won't work. Some resources (like the midi player) can't be shared - if midi music is played by the DLL, the engine must not play a midi file at the same time and vice versa. Also care must be taken that for writing something into the frame buffer it must be locked before, and unlocked afterwards. The interface library provides functions for that. WDL object structures Pointers to WDL objects can be transferred to DLL functions, thus allowing object manipulation. The internal engine format of important WDL objects is listed here.
typedef long fixed; typedef struct { long index; // char *name; // long next; // long modelindex; // internal 22.10 fixed point number format

A4 A4 A4 //

internal use only internal use only internal use only A4 internal use only
// the following variables can be externally used by WDL or DLL functions fixed x,y,z; // position of the entity fixed pan,tilt,roll; // angles fixed scale_x,scale_y,scale_z; long flags; fixed frame; // model or sprite frame fixed nextframe; // next frame for inbetweening fixed skin; // skin number fixed ambient; // brightness added to the entity, in percent fixed alpha; // transparency of the entity, in percent fixed lightrange; // range of dynamic light emitted by the entity fixed red,green,blue; // colour of dynamic light emitted by the entity long emask; // event enable flags long eflags; // internal status flags
fixed min[3],max[3]; fixed trigger_range; fixed push; fixed shadow_range; fixed floor_range; long client_id; // fixed skill[48]; // } A4_ENTITY; // bounding box
// collision behaviour // range within a shadow is projected onto to the floor // range within the entity reflects light from the floor client who has created this entity (when in multiplayer mode) entity skills

(to be continued)

The WMP map format
WMP files are plain ASCII files that can be viewed with any text editor. They contain blocks, entities, and objects that are built of them or of further objects. This is a typical WMB file:
// WMP2 // ACKWED V 4.39 // Created 11.09.2000 blocks 1 entities 2 objects 4 wed { palette { 00 7b 7b 7b 0f 0b 3b 1b 0b 0b 0f 4f 4f 5f 07 8f 0b 7f 53 3f ab 8b abb 73 9f 5f 33 3f db c3 bb 6b 6f 83 7b 2f ff f3 1b 7b ff 2f 2f 7f 2b b0f a7 7b 3b 8b }
0f 8b 17 5b 13 5b 07 3f 0f 4f 1b 6b 2f 9f 1b 8b 9f 4b af 53 cb 5f 67 2b ef 6b 0b 2f 3b c3 b7 b3
0f 8b 0f 5b 07 3f 1b 4b 17 4f 13 5f 7f 2f 6b 2b b3 4b 7b 3b df 53 0b 2f 00 4b 9b 00
0f 8b 0b 1f 1b 7f 00 0b 0b 37 8f 37 a7 3b 6f 2f ef 6f 00 1b 37 00
1f 9b 1f 63 1b 63 0b 77 3b af 2b 9b abf 53 5f 23 db 5b 13 2f 4b cf c7 d7
1f 9b 17 4b 1b 63 0b 53 1f 6b 5f 23 a3 3f cb 2f c3 00
1f 9b 0b 1f 27 8b 00 0f 0f 2f 0f 2f 83 2b 9b 00 df 5f 00 2b 37 00
2f ab 27 6b 27 6b 13 4b 1f 5f 2f 83 4b bf 37 a7 8b 3b af 1f cb 4b 1b 2b 5f db e7 ff
2f ab 1b 6b 13 4b 2b 77 2b 7b 67 1f 57 1f 6b 2b b1b 2b 07 7f e3 00
2f ab 0f 1f 00 0b 13 2f 13 5f 7b 23 8b 27 5f 1f 0f 00 cf 4f 00 3b 57 00
3f bb 2f 73 2f 73 1b 8b 57 cf 47 b7 7f 2b 8b 2f a4f 17 bb 3b 6f e3 7f ff
3f bb 2f 73 1b 00 2f 5b 2b 8f 5b 17 4f 2b a7 2b 0f 97 bf f3
3f bb 13 1f 3f a0b 17 2b 1b 6b 6f 1b 6b 1b 7b 1f 0f 00 bf 3f 00 4f ff 93
4b cb 37 7b 37 7b 23 5b 2f 6f 63 df 53 c23 7f 0f ab 2b 2b 1b 7f e7 ab ff
4b cb 2b 5f 37 7b 23 5b 37 5f 2f ab 4b 13 7b 1f 5b 1b 97 1f 2b 1b 17 ab e7 f7
4b cb 4b af 00 0b 00 1b 1f 7b 5f 13 6f 17 4f 13 0b 00 af 2f 07 5f ff c7

5b db 3f 83 3f 83 2b 77 4b aef 63 d3 6b 1b 3f 0b 9b 1b 2f ef d7 ff
5b db 2f 67 3f 83 2b 00 3b cb 3f a3 4b 0b 43 0b 6f 0f 2f 13 1f bf ff ff
5b db 57 bb 07 0b 07 1f 23 1f 2b 8b 57 0b 53 0b 5f 0f 47 0b 9f 1f ff ff
6b eb 4b 8f 47 8b 2f 6b 3f 7f 57 af 7f ff 6f e3 5f 0f 6b 0f 7b 0f 8b 0b 2f 0b a3 f9f
6b eb 37 6f 47 8b 2f 6b 3b fb3 3f 07 3b 0b 4b 0b 2f 0b 27 d5b
6b eb 1b cb 07 0f 2b 1b 4b 07 4b 07 3f 00 8f 0f 0b 8b 00 53
wad { 0 <standard.wad> 1 } bookmark { *waterblue earthtile ; ; ; ; ; } view { xy.1 -0.0 0.0 0.0 1536.0 0.745 3d.327 250.0 -250.0 250.0 1536.0 -0.785398 -0.61548 0.0 xz.1 -0.0 0.0 0.0 1536.0 0.745 yz.603 0.0 0.0 0.0 1536.0 0.745 textures 0 0
object } } block 0 { ( 0.0 0.0 32.0 ) ( 0.0 500.0 32.0 ) ( 32.0 0.0 0.0 ) ( 32.0 0.0 500.0 ) ( 0.0 -32.0 0.0 ) ( 0.0 -32.0 500.0 ( -32.0 0.0 0.0 ) ( -32.0 500.0 0.0 ( 0.0 32.0 0.0 ) ( 500.0 32.0 0.0 ) ( 0.0 0.0 -32.0 ) ( 500.0 0.0 -32.0 { 0000 ndef } } level 0 { <block.$$w> <Palette.raw> 30 0.000 60.000 <test.wdl> 19.60784340 19.60784340 19.60784340 3.92156863 3.92156863 3.92156863 } light 1 { 49.84313583 49.84313583 49.84313583 300.0 } object 0 { (0.0 0.0 0.0) (0.0 0.0 0.0) (1.0 1.0 1.0) object 1 level 0 } object 1 { (0.0 0.0 0.0) (0.0 0.0 0.0) (1.0 1.0 1.0) object 2, 3 } object 2 { (-44.0 4.0 0.0) (0.0 0.0 0.0) (1.0 1.0 1.0) block 0 } object 3 { (80.0 0.0 48.0) (1.570796 0.0 0.0) (1.0 1.0 1.0) light 1 }

( ( ) ) ( )

500.0 0.0 32.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.32.0 500.0 0.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.( 500.0 -32.0 0.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.( -32.0 0.0 500.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.0.0 32.0 500.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.( 0.0 500.0 -32.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.0 0000
All elements of the WMP file are surrounded by winged brackets { }. The WED element has no influence on the level, it just stores the palette of WEDs texture and 3D display (which has only 256 colors) and the WED settings when the level was saved. The important elements are the level properties, the blocks, lights, sounds, entities, and the objects that store the group information.
A4 Programmers Manual Blocks
A4 uses a right-handed XYZ coordinate system with the Z-axis standing upright. If you're not familiar with the reference of "right-handed" to a coordinate system, it basically provides a tactile and visual discription of the mechanics of the system. If you wrap your right hand around the zaxis, with your thumb facing the positive position, and clench your hand, your knuckles will face in the direction of the positive x-axis and your fingertips will face the postitive y-axis. Here's a picture of A4's coordinate system:

^ z | ^ y | / | / |/ --------> x
Blocks are the primary componens of a MAP file. Each block defines a solid or passable convex region. Blocks define this region as the intersection of four or more planes. Each plane is defined by three non-colinear points. These points must go in a clockwise orientation:
1--2-----> | / |/ 3 | V
Each block statement looks like this:
block 0 { ( 0.0 0.0 32.0 ) ( 0.0 500.0 32.0 ) ( 32.0 0.0 0.0 ) ( 32.0 0.0 500.0 ) ( 0.0 -32.0 0.0 ) ( 0.0 -32.0 500.0 ( -32.0 0.0 0.0 ) ( -32.0 500.0 0.0 ( 0.0 32.0 0.0 ) ( 500.0 32.0 0.0 ) ( 0.0 0.0 -32.0 ) ( 500.0 0.0 -32.0 { 0000 ndef } } ( ( ) ) ( ) 500.0 0.0 32.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.32.0 500.0 0.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.( 500.0 -32.0 0.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.( -32.0 0.0 500.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.0.0 32.0 500.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.( 0.0 500.0 -32.0 ) wood 0 1.00 1.00 : 0000 0.0 50.0 ndef ndef 0.0 0000
That's probably just a bit confusing when you first see it. It defines a cube that extends from (-32,32,-32) to (32,32,32). Here's what a single line means:
( 0.0 0.0 32.0 ) ( 0.0 500.0 32.0 ) ( 500.0 0.0 32.0 ) wood 0 1.00 1.00 : 1st point 2nd point 3rd point texture x_offs y_offs angle x_scale y_scale 0000 0.0 50.0 flags ambient albedo ndef ndef 0.future expansion not used yet
Here are more details about those fields: 1st point \ Those three points define a plane, so they must not be colinear. 2nd point > Each plane should only be defined once. 3rd point / Plane normal is oriented towards the cross product of (p1 - p2) and (p3 -p2) Texture - name of the texture. X_offs - texture x-offset in pixels Y_offs - texture y-offset in pixels
Angle - texture rotation angle, in degree X_scale - size of a pixel in x-direction (pixels per quant) Y_scale - size of a pixel in y-direction (pixels per quant) flags - render mode flags for the texture. ambient - brightness value in percent albedo - albedo/fog value in percent Map Properties The following structure contains the global level or map properties:

level 0 { <block.$$w> <Palette.raw> 30 0.000 60.000 <test.wdl> 19.6 19.6 19.6 3.9 3.9 3.9 } interim WAD palette nexus azimuth elevation script fog 1 fog 2 fog 3 fog 4 sun ambient
WAD the name of the interim WAD file that contains all textures used in the level. Palette the name of the palette file. The.RAW format just consists of 768 bytes r,g,b values for the 256 colors. Nexus the nexus value, used for running and publishing the game. Azimuth the horizontal angle of the sun in degrees, counterclockwise beginning with 0 = East. Elevation the vertikal angle of the sun in degrees. Script the WDL script that runs the game Fog 1.4 the four fog colors in RGB percent Sun the strength and colour of the sun light in RGB percent Ambient the strength and colour of the ambient brightness in RGB percent (to be continued) Light and Sound Sources Entities Groups
A wireframe mesh, made of triangles, gives the general shape of a model. 3D vertices define the position of triangles. For each triangle in the wireframe, there will be a corresponding triangle cut from the skin picture. Or, in other words, for each 3D vertex of a triangle that describes a XYZ position, there will be a corresponding 2D vertex positioned that describes a UV position on the skin picture. It is not necessary that the triangle in 3D space and the triangle on the skin have the same shape (in fact, it is not possible for all triangles), but they should have shapes roughly similar, to limit distortion and aliasing. Several animation frames of a model are just several sets of 3D vertex positions. The 2D vertex positions always remain the same. A MDL file contains: - A list of skin textures in 8-bit palettized or 16-bit 5-6-5 format. - A list of skin vertices, that are just the UV position of vertices on the skin texture. - A list of triangles, which describe the general shape of the model. - A list of animation frames. Each frame holds a list of 3D vertices. - A list of bone vertices, which are used for creating the animation frames. MDL file header Once the file header is read, all the other model parts can be found just by calculating their position in the file. Here is the format of the.MDL file header:

typedef float vec3[3]; typedef struct { char version[4]; long final; vec3 scale; vec3 offset; float pad; vec3 eye; long numskins ; long skinwidth; long skinheight; long numverts; long numtris; long numframes; long numskinverts; long flags; long numbones; } mdl_header;
// // // // // // // // // // // // // // //
"MDL3" or "MDL4" not used yet 3D position scale factors. 3D position offset. not used yet. not used yet. number of skin textures width of skin texture; must be a multiple of 2 height of skin texture number of 3d wireframe vertices number of triangles surfaces number of frames number of 2D skin vertice 0 = normal, 1 = terrain model number of bone vertices (MDL4 only, otherwise 0)
The size of this header is 0x54 bytes (84). The "MDL3" format is used by the A4 engine, while the "MDL4" format is used by the A5 engine. After the file header follow the skins, the skin vertices, the triangles, the frames, and finally the bones (future expansion).
A4 Programmers Manual MDL skin format
The model skins are flat pictures that represent the texture that should be applied on the model. There can be more than one skin. You will find the first skin just after the model header, at offset baseskin = 0x54. There are numskins skins to read. Each of these model skins is either in 8-bit palettized (type == 0) or in 16-bit 5-6-5 format (type == 2). The structure is:
typedef byte unsigned char; typedef struct { int skintype; // 0 for 8 bit (bpp == 1), 2 for 16 bit (bpp == 2) byte skin[skinwidth*skinheight*bpp]; // the skin picture } mdl_skin_t;
8 bit skins are a table of bytes, which represent an index in the level palette. If the model is rendered in overlay mode, index 0x00 indicates transparency. 16 bit skins are a table of shorts, which represent a true colour with the upper 5 bits for the red, the middle 6 bits for the green, and the lower 5 bits for the blue component. Green has one bit more because the human eye is more sensitive to green than to other colours. If the model is rendered in overlay mode, colour value 0x0000 indicates transparency. The width of skins should be a multiple of 4, to ensure long word alignement. The skin pictures are usually made of as many pieces as there are independent parts in the model. For instance, for the a player, there may be two pieces that defines the body, and two others that define the gun. MDL skin vertices The list of skin vertices indicates only the position on texture picture, not the 3D position. That's because for a given vertex, the position on skin is constant, while the position in 3D space varies with the animation. The list of skin vertices is made of these structures:

typedef struct { short u; // position, horizontally in range 0.skinwidth-1 short v; // position, vertically in range 0.skinheight-1 } mdl_uvvert_t; mdl_uvvert_t skinverts[numskinverts];
u and v are the pixel position on the skin picture. The skin vertices are stored in a list, that is stored at offset basestverts = baseskin + skinsize. skinsize is the sum of the size of all skin pictures. If they are all 8-bit skins, then skinsize = (4 + skinwidth * skinheight) * numskins. If they are 16-bit skins, then skinsize = (4 + skinwidth * skinheight * 2) * numskins. MDL mesh triangles The model wireframe mesh is made of a set of triangle facets, with vertices at the boundaries. Triangles should all be valid triangles, not degenerates (like points or lines). The triangle face must be pointing to the outside of the model. Only vertex indexes are stored in triangles. Here is the structure of triangles:
typedef struct { short index_xyz[3]; // Index of 3 3D vertices in range 0.numverts short index_uv[3]; // Index of 3 skin vertices in range 0.numskinverts } mdl_triangle_t; mdl_triangle_t triangles[numtris];
At offset basetri = baseverts + numskinverts * sizeof(uvvert_t) in the.MDL file you will find the triangle list. MDL frames A model contains a set of animation frames, which can be used in relation with the behavior of the modeled entity, so as to display it in various postures (walking, attacking, spreading its guts all over the place, etc). Basically the frame contains of vertex positions and normals. Because models can have ten thousands of vertices and hundreds of animation frames, vertex posistion are packed, and vertex normals are indicated by an index in a fixed table, to save disk and memory space. Each frame vertex is defined by a 3D position and a normal for each of the 3D vertices in the model. In the MDL3 format, the vertices are always packed as bytes; in the MDL4 format that is used by the A5 engine they can also be packed as words (unsigned shorts). Therefore the MDL4 format allows more precise animation of huge models, and inbetweening with less distortion.
typedef struct { byte rawposition[3]; // X,Y,Z coordinate, packed on 0.255 byte lightnormalindex; // index of the vertex normal } mdl_trivertxb_t; typedef struct { unsigned short rawposition[3]; // X,Y,Z coordinate, packed on 0.65536 byte lightnormalindex; // index of the vertex normal byte boneindex; // index of the bone this vertex belongs to } mdl_trivertxs_t;

To get the real X coordinate from the packed coordinates, multiply the X coordinate by the X scaling factor, and add the X offset. Both the scaling factor and the offset for all vertices can be found in the mdl_header struct. The formula for calculating the real vertex positions is:
float position[i] = (scale[i] * rawposition[i] ) + offset[i];
The lightnormalindex field is an index to the actual vertex normal vector. This vector is the average of the normal vectors of all the faces that contain this vertex. The normal is necessary to calculate the Gouraud shading of the faces, but actually a crude estimation of the actual vertex normal is sufficient. That's why, to save space and to reduce the number of computations needed, it has been chosen to approximate each vertex normal. The ordinary values of lightnormalindex are comprised between 0 and 161, and directly map into the index of one of the 162 precalculated normal vectors:
float lightnormals[162][3] = { {-0.525725, 0.000000, 0.850650}, {-0.442863, 0.238856, 0.864188}, {-0.295242, 0.000000, 0.955423}, {-0.309017, 0.500000, 0.809017}, {-0.162460, 0.262866, 0.951056}, {0.000000, 0.000000, 1.000000}, {0.000000, 0.850651, 0.525731}, {-0.147621, 0.716567, 0.681718}, {0.147621, 0.716567, 0.681718}, {0.000000, 0.525731, 0.850651}, {0.309017, 0.500000, 0.809017}, {0.525731, 0.000000, 0.850651}, {0.295242, 0.000000, 0.955423}, {0.442863, 0.238856, 0.864188}, {0.162460, 0.262866, 0.951056}, {-0.681718, 0.147621, 0.716567}, {-0.809017, 0.309017, 0.500000}, {-0.587785, 0.425325, 0.688191}, {-0.850651, 0.525731, 0.000000}, {-0.864188, 0.442863, 0.238856}, {-0.716567, 0.681718, 0.147621}, {-0.688191, 0.587785, 0.425325}, {-0.500000, 0.809017, 0.309017}, {-0.238856, 0.864188, 0.442863}, {-0.425325, 0.688191, 0.587785}, {-0.716567, 0.681718, -0.147621}, {-0.500000, 0.809017, -0.309017}, {-0.525731, 0.850651, 0.000000}, {0.000000, 0.850651, -0.525731}, {-0.238856, 0.864188, -0.442863}, {0.000000, 0.955423, -0.295242}, {-0.262866, 0.951056, -0.162460}, {0.000000, 1.000000, 0.000000}, {0.000000, 0.955423, 0.295242}, {-0.262866, 0.951056, 0.162460}, {0.238856, 0.864188, 0.442863}, {0.262866, 0.951056, 0.162460}, {0.500000, 0.809017, 0.309017}, {0.238856, 0.864188, -0.442863}, {0.262866, 0.951056, -0.162460}, {0.500000, 0.809017, -0.309017}, {0.850651, 0.525731, 0.000000}, {0.716567, 0.681718, 0.147621}, {0.716567, 0.681718, -0.147621}, {0.525731, 0.850651, 0.000000}, {0.425325, 0.688191, 0.587785}, {0.864188, 0.442863, 0.238856}, {0.688191, 0.587785, 0.425325},

A whole frame has the following structure:
typedef struct { long type; // 0 for byte-packed positions, and 2 for word-packed positions mdl_trivertx_t bboxmin,bboxmax; // bounding box of the frame char name[16]; // name of frame, used for animation mdl_trivertx_t vertex[numverts]; // array of vertices, either byte or short packed } mdl_frame_t;
The size of each frame is sizeframe = 20 + (numverts+2) * sizeof(mdl_trivertx_t), while mdl_trivertx_t is either mdl_trivertxb_t or mdl_trivertxs_t, depending on whether the type is 0 or 2. In the MDL3 format the type is always 0. The beginning of the frames can be found in the.MDL file at offset baseframes = basetri + numtris * sizeof(mdl_triangle_t). MDL bones This is only for future expansion of the MDL format, and not implemented yet.
Bones are a linked list of 3D vertices that are used for animation in the MDL4 format. Each bone vertex can have a parent, and several childs. If a bone vertex is moved, the childs move with it. If on moving a bone vertex the connection line to his parent rotates, it's childs are rotated likewise about the parent position. If the distance of the bone vertex to its parent changes, the change is added onto the distance between childs and parent. So the movement of the childs is done in a spherical coordinate system, it is a combination of a rotation and a radius change. Each bone vertex has an influence on one or more mesh vertices. The mesh vertices influenced by a bone vertex move the same way as it's childs. If a mesh vertex is influenced by several bone vertices, it is moved by the average of the bone's movement.

 

Tags

SMH9151B Strap MC-E4013 2443BW Digital Mackie TT24 Powershot G11 Review VLF8126 C 702 37LG2000-ZA AEU Integrated-homelink-transciever W3301 AP140R-e1 EP-50 EWX14540W SX-218-K 66320KF-N 64I EPL-N2050 AA8XE SS-RXD8S T240MD NRX-3 BAR986HG SGH-A867 DTH8060 SCD-XE597 BAR938HG Expedition-2007 Suite 10 AKG 659 IC-RP1510 KDL-46W4220 AD18A1e09 Phone-MD4260 EUU6174 LAV4750 YH-999 Translator DSC-H7-B CJ110MV Lowrance X97 Concept 30 P92 Echo BC 2255 EX774N L-558 Reference Cruise MX2500 Es500 VVX 2000 2012NB Locator A1018S BCR 2000 S-locomotion 1 5 LE-26S81B Motorola A760 8410D GC3230 KG36VX13 105 X BDM750 Firmware Recorder 8 Aastra 8314 Navman F10 ZI720 9K MG15fxmsdm Rummikub Server E-660 Envoy-2004 R-631 Factor Digital DVD-P370 1830 PSS Iphone NV-SD440B X340N Km001 XVS650AL MEX-BT3600U 8 X Xperia X2 Magic Semi Auto MC240 AW2092F-1 Esam 4400 Guide RF267aars-XAA STA-1100 Deskjet 5652 CLP-320 M1712N Harmonyg-XT Processor DFC7

 

manuel d'instructions, Guide de l'utilisateur | Manual de instrucciones, Instrucciones de uso | Bedienungsanleitung, Bedienungsanleitung | Manual de Instruções, guia do usuário | инструкция | návod na použitie, Užívateľská príručka, návod k použití | bruksanvisningen | instrukcja, podręcznik użytkownika | kullanım kılavuzu, Kullanım | kézikönyv, használati útmutató | manuale di istruzioni, istruzioni d'uso | handleiding, gebruikershandleiding

 

Sitemap

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101