You can improve the performence of your project when not using the engine intern sheduler. Instead just use linked lists. We use this for our own projects (zombies etc.) wink

without linked-list:


with linked-list:


//////////////////////////////////////////////////////////////////////
// Link List Example
//--------------------------------------------------------------------
// Modul : Entity helper funcs
// Created : crew51 GbR : 2010-06-21
// $Id$
//--------------------------------------------------------------------
// todo:
/*

*/
//--------------------------------------------------------------------

#define USE_LINK_LIST

#include <acknex.h>
#include <default.c>

// Header
ENTITY* pEmeter_first;
ENTITY* pEmeter_last;

void ent_listFuncFrm(ENTITY* p);

#define ent_prevListObj skill96
#define ent_nextListObj skill97

//--------------------------------------------------------------------
// Add an object to the list
//--------------------------------------------------------------------
void ent_listAdd(ENTITY* p, ENTITY** first, ENTITY** last)
{
if (*first == NULL) {
*first = p;
*last = p;
return;
}

(**last).ent_nextListObj = p;
p.ent_prevListObj = *last;
*last = p;
}

//--------------------------------------------------------------------
// Remove from the entity list
//--------------------------------------------------------------------
void ent_listRemove(ENTITY* p, ENTITY** first, ENTITY** last)
{
//we're the last one
if (p.ent_nextListObj == NULL) {
if (p.ent_prevListObj != NULL) {
*last = p.ent_prevListObj;
(**last).ent_nextListObj = NULL;
} else {
*last = NULL;
}
}

//we're the first one
if (p.ent_prevListObj == NULL) {

if (p.ent_nextListObj != NULL) {
*first = p.ent_nextListObj;
(**first).ent_prevListObj = NULL;
} else {
*first = NULL;
}
}

//in the middle
if ((p.ent_nextListObj != NULL) && (p.ent_prevListObj != NULL)) {
ENTITY* p1 = p.ent_prevListObj;
ENTITY* p2 = p.ent_nextListObj;

p1.ent_nextListObj = p2;
p2.ent_prevListObj = p1;
}

}

//--------------------------------------------------------------------
// Test func for cube
//--------------------------------------------------------------------
void cube_rotate(ENTITY* p)
{
p.pan += 23 * time_step;
}

//--------------------------------------------------------------------
// Run all funcs
//--------------------------------------------------------------------
void ent_listExec(ENTITY* first, void* f)
{
ent_listFuncFrm = f;

ENTITY* p = first;
while (p != NULL) {
my = p;
you = NULL;

ent_listFuncFrm(p);
p = p.ent_nextListObj;

my = NULL;
you = NULL;
}
}

void cube_func()
{
while(1) {
wait(1);
my.pan += 23 * time_step;
}

}
void main()
{
warn_level = 99;
level_load(NULL);

wait(2);

pEmeter_first = NULL;
pEmeter_last = NULL;

int i;
VECTOR v;
ENTITY* p;
vec_set(v.x, nullvector);


for (i = 0; i < 1000; i ++) {
#ifdef USE_LINK_LIST
p = ent_create(CUBE_MDL,v.x,NULL);
ent_listAdd(p, &pEmeter_first, &pEmeter_last);
#else
p = ent_create(CUBE_MDL,v.x,cube_func);
#endif

}

#ifdef USE_LINK_LIST
while (1) {
wait(1);
ent_listExec(pEmeter_first, cube_rotate);

//remoce cubes...
/*
vec_set(v.x, vector(500, 0, 0));
vec_rotate(v.x, camera.pan);
vec_add(v.x, camera.x);

c_trace(camera.x, v.x, IGNORE_SPRITES);
if (trace_hit) {
draw_point3d(hit.x,vector(0,0,255),100,5);
if ((key_space) && (hit.entity != NULL)) {
ent_listRemove(hit.entity, &pEmeter_first, &pEmeter_last);
ent_remove(hit.entity);
}
}


if (pEmeter_first != NULL) {
draw_point3d(pEmeter_first.x,vector(1,255,255),100,15);
}
if (pEmeter_last != NULL) {
draw_point3d(pEmeter_last.x,vector(255,255,1),100,15);
}
*/

}
#endif

}