/* main bits go in here */

#include "gameinc.h"

static int hierarchybodge=0;

#define DOIT_ZB
//#define DOIT_ZS
/* Defined to turn off the people in the scene */
#define NOPEEPS 0

static int screensaven=0;

int editmodes_menuid[10];
extern void ToggleALightKeyb(void);

static p_O_Overlay overlay_array[32];
static int overlay_total=0;

// Module wide variables
// ---------------------
static int currentwlight=0;
static br_fmt_results *results = NULL;

static br_actor *viewcamera;
static br_actor *camera, *light, *world, *actors, *rootactor, *backactor, *actors2, *camera2;
static br_actor *anim_camera1, *anim_world, *anim_camera2;
static br_int_32 mouse_xd,mouse_yd;
br_int_32 mouse_x,mouse_y;
static br_uint_32 mouse_buttons;

br_actor *blokecam;

static int fillcolour=0;

static br_actor *sceneactor;

static br_pixelmap *engine_screen, *engine_back, *engine_depth;
br_pixelmap *screen, *screen_buffer, *back_screen, *copy_screen, *palette, *depth_buffer;

br_pixelmap *anim_subpixel1, *anim_subpixel2;

static int total_frames;
static int current_lframe=0;

br_pixelmap *con_overlay;

int maxwlights=0;
br_actor *wlight[256];

int maxwcameras=0;
br_actor *wcameras[256];

extern int msx,msy,clw,clh;

// All frames in animation and all transforms for a single frame. 

//static struct ani_frame frames[MAXFRAMES];
//static struct ani_transform transforms[MAXTRANSFORMS];

static struct ani_frame multiframes[MAXGROUPS][MAXFRAMES];
static struct ani_transform *multitransforms=NULL;
static int multitotal_frames[MAXGROUPS];

static int loadedanimations=0;
static int currentgroup=1;

static int scenerot=0;


static int lightsmenu=E_MENU_ERROR;
static int camerasmenu=E_MENU_ERROR;
static char lightnames[32][32];
static char cameranames[32][32];

void bodgenow(void)
{
	br_pixelmap *myglobalone;

	myglobalone = BrFmtTGALoad("p:\\cult\\fli\\1-1anim\\MPTEST\\pneu2.tga",0);
	BrPixelmapSave("D:\\checkme.pix",myglobalone);
}


static void recursetreeoff(br_actor *this)
{

	if (this->type==BR_ACTOR_LIGHT)
	{
			BrLightDisable(this);
	}
	if (this->next != NULL)
		recursetreeoff(this->next);
	if (this->children != NULL)
		recursetreeoff(this->children);
}


void AllLightsOffActor(br_actor *this)
{
	if (this==NULL)
		return;

	if (this==NULL)
		return;

	recursetreeoff(this);
}


void AllLightsInvert(void)
{
	int i;

	for (i=1;i<maxwlights;i++)
	{
		if (Editor_MenuGetFlags(lightsmenu,i)&E_MENU_I_TICKED)
		{
			Editor_MenuSetFlags(lightsmenu,i,Editor_MenuGetFlags(lightsmenu,i)& (~E_MENU_I_TICKED));
			BrLightDisable(wlight[i]);
		}
		else
		{
			Editor_MenuSetFlags(lightsmenu,i,Editor_MenuGetFlags(lightsmenu,i)|E_MENU_I_TICKED);
			BrLightEnable(wlight[i]);
		}
	}
}


void AllLightsOn(void)
{
	int i;

	for (i=1;i<maxwlights;i++)
	{
		Editor_MenuSetFlags(lightsmenu,i,Editor_MenuGetFlags(lightsmenu,i)|E_MENU_I_TICKED);
		BrLightEnable(wlight[i]);
	}
}

void AllLightsOff(void)
{
	int i;
	for (i=0;i<maxwlights;i++)
	{
		Editor_MenuSetFlags(lightsmenu,i,Editor_MenuGetFlags(lightsmenu,i)& (~E_MENU_I_TICKED));
		BrLightDisable(wlight[i]);
	}
}


static void recursetree(br_actor *this)
{
	br_light *thislight;

	if (this->type==BR_ACTOR_LIGHT)
	{
		BrLightDisable(this);
		thislight=(br_light *)this->type_data;
		thislight->attenuation_c=BR_MUL(thislight->attenuation_c,BR_SCALAR(1.0));
		lightnames[maxwlights][0]='\0';
		if (thislight->identifier != NULL)
		{
			strcpy(lightnames[maxwlights],thislight->identifier);
		}
		wlight[maxwlights]=this;
		maxwlights++;
	}

	if (this->type==BR_ACTOR_CAMERA)
	{
		cameranames[maxwlights][0]='\0';
		if (this->identifier != NULL)
		{
			strcpy(cameranames[maxwlights],this->identifier);
		}
		wcameras[maxwcameras]=this;
		maxwcameras++;
	}


	if (this->next != NULL)
		recursetree(this->next);
	if (this->children != NULL)
		recursetree(this->children);
}


void UpdateWLightList(br_fmt_results *results)
{
	int i;

	maxwlights=0;
	maxwcameras=0;
	if (results==NULL)
		return;

	if (results->actors[0]==NULL)
		return;

	recursetree(world);

	if (maxwlights>BR_MAX_LIGHTS-1)
		maxwlights=BR_MAX_LIGHTS-1;

	for (i=0;i<31;i++)
	{
		Editor_MenuAttachEntry(lightsmenu,i,NULL,E_MENU_I_NONE);
	}
	for (i=0;i<31;i++)
	{
		Editor_MenuAttachEntry(camerasmenu,i,NULL,E_MENU_I_NONE);
	}
	for (i=0;i<maxwlights;i++)
	{
		if (strlen(lightnames[i])==0)
		{
			sprintf(lightnames[i],"Unnamed %d",i);
		}
		Editor_MenuAttachEntry(lightsmenu,i,lightnames[i],E_MENU_I_TICKABLE | E_MENU_I_SUBMENU);
	}
	for (i=0;i<maxwcameras;i++)
	{
		if (strlen(cameranames[i])==0)
		{
			sprintf(cameranames[i],"Unnamed %d",i);
		}
		Editor_MenuAttachEntry(camerasmenu,i,cameranames[i],E_MENU_I_TICKABLE);
	}

	for (i=0;i<maxwlights;i++)
	{
		BrLightEnable(wlight[i]);
		BrLightDisable(wlight[i]);
	}
}


void ShineAWLight(int num)
{
	int i;
		
	for (i=0;i<maxwlights;i++)
	{
		if (i==num)
			BrLightEnable(wlight[i]);
		else
			BrLightDisable(wlight[i]);
	}
}

br_error LoadShadeTable( int type )
{
	br_pixelmap *pShade ;

	// Load a shade table 

	pShade = NULL ;

    switch ( type )
    {
       case BR_PMT_INDEX_8 : pShade = BrPixelmapLoad("winsh8.tab");
                             break ;

       case BR_PMT_RGB_555 : pShade = BrPixelmapLoad("winsh15.tab");
                             break ;

       case BR_PMT_RGB_565 : pShade = BrPixelmapLoad("winsh16.tab");
                             break ;
    }

    if ( !pShade )
    {
		BR_ERROR0("Could not load shade table");
		return BRE_FAIL ;
	}

    BrTableAdd(pShade);

    return BRE_OK ;
}

void
LoadTexture()
{
	br_pixelmap    *pixmap[256];
	int nummap;

	Editor_OverlayDebug("Loading textures");

	nummap = BrPixelmapLoadMany("d:\\bloodsqd\\chars\\nathan\\nathan.pix",pixmap,256);
	BrMapAddMany(pixmap,nummap);

	nummap = BrPixelmapLoadMany("d:\\bloodsqd\\backgrnd\\psx\\diner4.pix",pixmap,256);
	BrMapAddMany(pixmap,nummap);
	
}

br_token_value blend_tokens[] =
	{
    BRT_BLEND_B,BR_TRUE,
//	BRT_OPACITY_F, 160.0,		/* BRender float opacity is knackered, or something */
	BRT_OPACITY_X, 0xa00000,	/* i.e. 160 in fixed point - this is hideous */
    0
    };


void
LoadMaterial()
{
	br_material    *material[200],*mat;
	int             n,i;
	br_scalar value;


	Editor_OverlayDebug("Loading materials");

	n = BrFmtScriptMaterialLoadMany("d:\\bloodsqd\\chars\\nathan\\nathan.scr", material, 200);
	if (!n)
		BR_ERROR0("Failed to load materials.");

	for (i=0;i<n;i++)
	{
		if (material[i]->ka==0)
		{
			value=BR_SCALAR(0.098039);
			material[i]->ka=BrScalarToUFraction(value);
		}
		if (material[i]->kd==0)
		{
			value=BR_SCALAR(0.698039);
			material[i]->kd=BrScalarToUFraction(value);
		}

		if (material[i]->colour==0)
		{
			material[i]->colour=BR_COLOUR_RGB(178,178,178);
		}		

	}

	BrMaterialAddMany(material, n);


	n = BrFmtScriptMaterialLoadMany("d:\\bloodsqd\\chars\\morphed\\morphed.scr", material, 200);
	if (!n)
		BR_ERROR0("Failed to load materials.");

	for (i=0;i<n;i++)
	{
		if (material[i]->ka==0)
		{
			value=BR_SCALAR(0.098039);
			material[i]->ka=BrScalarToUFraction(value);
		}
		if (material[i]->kd==0)
		{
			value=BR_SCALAR(0.698039);
			material[i]->kd=BrScalarToUFraction(value);
		}

		if (material[i]->colour==0)
		{
			material[i]->colour=BR_COLOUR_RGB(178,178,178);
		}		

	}

	BrMaterialAddMany(material, n);


	n = BrFmtScriptMaterialLoadMany("d:\\bloodsqd\\backgrnd\\psx\\diner4.scr", material, 200);
	if (!n)
		BR_ERROR0("Failed to load materials.");

	for (i=0;i<n;i++)
	{
		if (material[i]->ka==0)
		{
			value=BR_SCALAR(0.098039);
			material[i]->ka=BrScalarToUFraction(value);
		}
		if (material[i]->kd==0)
		{
			value=BR_SCALAR(0.698039);
			material[i]->kd=BrScalarToUFraction(value);
		}

		if (material[i]->colour==0)
		{
			material[i]->colour=BR_COLOUR_RGB(178,178,178);
		}		

	}

	BrMaterialAddMany(material, n);

	mat = BrMaterialFind("window pane");
	if (mat!=NULL)
	{
		mat->colour = BR_COLOUR_RGB(35,35,35);
		mat->extra_prim = blend_tokens;
		BrMaterialUpdate(mat, BR_MATU_ALL);
	}


}

void
LoadModel()
{
	br_model       *model[400];
	int             n,i;

	Editor_OverlayDebug("Loading models");

	n = BrModelLoadMany("d:\\bloodsqd\\chars\\nathan\\nathan.dat", model, 400);
	if (!n)
		BR_ERROR0("Failed to load any models");

	BrModelAddMany(model, n);

	n = BrModelLoadMany("d:\\bloodsqd\\chars\\morphed\\morphed.dat", model, 400);
	if (!n)
		BR_ERROR0("Failed to load any models");

	BrModelAddMany(model, n);


	n = BrModelLoadMany("d:\\bloodsqd\\backgrnd\\psx\\diner4.dat", model, 400);
	for (i=0;i<n;i++)
	{
		model[i]->flags=0;
	}
	if (!n)
		BR_ERROR0("Failed to load any models");

	BrModelAddMany(model, n);

}

br_actor  *LoadActors()
{
	br_actor       *root;

	Editor_OverlayDebug("Loading actors");
	root = BrActorLoad("d:\\bloodsqd\\chars\\nathan\\nathan.act");
	if (root == NULL) {
		BR_ERROR0("Failed to load actor file.");
	}
	return root;
}

br_actor  *LoadActors2()
{
	br_actor       *root;

	root = BrActorLoad("d:\\bloodsqd\\chars\\morphed\\morphed.act");
	if (root == NULL) {
		BR_ERROR0("Failed to load actor file.");
	}
	return root;
}


static int levelloadedwithbodge;
static char lastlevel3dsname[256];

extern br_error BrDemo_HandleSavedFile( char * /*filepath*/ );

void LoadLevel(char *path)
{
	FILE *fp;
	int i;
	char line[256];
	br_light *thislight;
	int ival;
	float fval;

	fp  = fopen(path,"r");

	fgets(line,256,fp);
	fgets(line,256,fp);
	fgets(line,256,fp);
	fgets(line,256,fp);

	fgets(line,256,fp);
	sscanf(line,"      hierarchy = %d",&levelloadedwithbodge);
	fgets(line,256,fp);
	sscanf(line,"      add3dsfile = \"%s\"\n",&lastlevel3dsname);
	lastlevel3dsname[strlen(lastlevel3dsname)-1] = 0;

	hierarchybodge = levelloadedwithbodge;
	Entity_SendMessageToAll(ENTITY_MESSAGE_INSTANCE_CLOSEDOWN);
	Entity_SendMessageToAll(ENTITY_MESSAGE_SYSTEM_CLOSEDOWN);
	BrDemo_HandleSavedFile(lastlevel3dsname);
	hierarchybodge = 0;
	Entity_SendMessageToAll(ENTITY_MESSAGE_SYSTEM_STARTUP);
	Entity_SendMessageToAll(ENTITY_MESSAGE_INSTANCE_STARTUP);
	editor_editmode=EDITMODE_GAME;
	Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GAME]);

	for (i=0;i<maxwlights;i++)
	{
		int flags;

		flags=Editor_MenuGetFlags(lightsmenu,i);
		fgets(line,256,fp);
		if (!strncmp(line+6,"LightDisable",12) && (flags & E_MENU_I_TICKED))
		{
			flags &= ~E_MENU_I_TICKED;
			BrLightDisable(wlight[i]);
			Editor_MenuSetFlags(lightsmenu,i,flags);
		}

		if (!strncmp(line+6,"LightEnable",11) && !(flags & E_MENU_I_TICKED))
		{
			flags |= E_MENU_I_TICKED;
			BrLightEnable(wlight[i]);
			Editor_MenuSetFlags(lightsmenu,i,flags);
		}

		thislight = (br_light *) wlight[i]->type_data;
		fgets(line,256,fp);
		sscanf(line,"      type = %d\n",&ival);
		thislight->type = ival;
		fgets(line,256,fp);
		sscanf(line,"      attenuation_c = %f\n",&fval);
		thislight->attenuation_c = BR_SCALAR(fval);
		fgets(line,256,fp);
		sscanf(line,"      attenuation_l = %f\n",&fval);
		thislight->attenuation_l = BR_SCALAR(fval);
		fgets(line,256,fp);
		sscanf(line,"      attenuation_q = %f\n",&fval);
		thislight->attenuation_q = BR_SCALAR(fval);

		fgets(line,256,fp);
		sscanf(line,"      cone_inner = %f\n",&fval);
		thislight->cone_inner = BrScalarToAngle(BR_SCALAR(fval));
		fgets(line,256,fp);
		sscanf(line,"      cone_outer = %f\n",&fval);
		thislight->cone_outer = BrScalarToAngle(BR_SCALAR(fval));

	}

	fclose(fp);
}


void SaveLevel(char *path)
{
	FILE *fp;
	int i;
	br_light *thislight;

	fp  = fopen(path,"w");

	fprintf(fp,"# Generated level definition file don't touch!\n");
	fprintf(fp,"{\n");
	fprintf(fp,"   3DSADD\n");
	fprintf(fp,"   {\n");
	fprintf(fp,"      hierarchy = %d\n",levelloadedwithbodge);
	fprintf(fp,"      add3dsfile = \"%s\"\n",lastlevel3dsname);

	for (i=0;i<maxwlights;i++)
	{
		int flags;

		flags=Editor_MenuGetFlags(lightsmenu,i);
		if (flags & E_MENU_I_TICKED )
		{
			fprintf(fp,"      LightEnable\n");
		}
		else
		{
			fprintf(fp,"      LightDisable\n");
		}

		thislight = (br_light *) wlight[i]->type_data;
		fprintf(fp,"      type = %d\n",thislight->type);
		fprintf(fp,"      attenuation_c = %f\n",BrScalarToFloat(thislight->attenuation_c));
		fprintf(fp,"      attenuation_l = %f\n",BrScalarToFloat(thislight->attenuation_l));
		fprintf(fp,"      attenuation_q = %f\n",BrScalarToFloat(thislight->attenuation_q));

		fprintf(fp,"      cone_inner = %f\n",BrScalarToFloat(BrAngleToScalar(thislight->cone_inner)));
		fprintf(fp,"      cone_outer = %f\n",BrScalarToFloat(BrAngleToScalar(thislight->cone_outer)));

	}


	fprintf(fp,"   }\n");
	fprintf(fp,"}\n\n");

	fclose(fp);	
}

 
void
LoadVUE(char *file_name, br_actor * root)
{
	FILE           *file;
	int             f = -1, i, firstflag=0,bodgeoff=0;
	char            buff[1024];
	char            name[80];
	float           v[4][3];
	struct ani_transform *t;
	struct ani_frame *p_f = multiframes[loadedanimations];
	static int numtloaded=0;

	t= multitransforms+numtloaded;	

	multitotal_frames[loadedanimations]=0;
	file = fopen(file_name, "r");

	while (!feof(file)) {
		fgets(buff, 1024, file);

		/* Is it a frame specification line? */

		if (sscanf(buff, "frame %d", &i) > 0) {
			if (firstflag==0)
			{
				firstflag=1;
				bodgeoff=i;
			}
			i=i-bodgeoff;
			if (f > 0)
				p_f[f].ntransforms = t - p_f[f].transforms;
			f = i;
			p_f[f].transforms = t;
		}
		/* Or a transform specification? */

		if (sscanf(buff,
		 "transform \"%[^\"]\" %f %f %f %f %f %f %f %f %f %f %f %f",
				name,
				&v[0][0], &v[0][1], &v[0][2],
				&v[1][0], &v[1][1], &v[1][2],
				&v[2][0], &v[2][1], &v[2][2],
				&v[3][0], &v[3][1], &v[3][2]) > 0
			) {
			int             k, l;

			/* Found a transform so convert it to scalars */

			for (k = 0; k < 4; k++)
				for (l = 0; l < 3; l++)
					t->mat.m[k][l] = BrFloatToScalar(v[k][l]);

			t->actor = Editor_SearchTreeNew(root, name);

			if (t->actor != NULL)
				t++;

			numtloaded++;
			if (numtloaded>=MAXTRANSFORMS)
			{
				BR_ERROR0("Maximum transforms reached!!");
				fclose(file);
				PostQuitMessage(0);
				return;
			}
		}
	}

	fclose(file);

	if (f > 0)
		p_f[f].ntransforms = t - p_f[f].transforms;

	multitotal_frames[loadedanimations] = f + 1;

	loadedanimations++;
}


#if CHOICE_MAIN

extern float previous_gametimer;

br_error BrDemo_Render_Loop()
{

	int i;
	static int current_frame = 0;
	static int frame_delta = 1;
	static int flagtoeditmode = 0;
	int menuid;
	br_light *thislight;

	mouse_xd=mouse_x; mouse_yd=mouse_y;
	DOSMouseRead(&mouse_x,&mouse_y,&mouse_buttons);
	menuid=Editor_HandleMouse(mouse_x,mouse_y,mouse_buttons);
	if (menuid != E_MENU_ERROR )
	{
		mouse_buttons=0;
	}
	mouse_xd=mouse_x-mouse_xd; mouse_yd=mouse_y-mouse_yd;
	if ( !back_screen )
		return BRE_OK ;

//	Editor_HandleEditorStates(mouse_x,mouse_y,mouse_buttons);

	// Step backwards and forward, run backwards and forward and stop.
	
	if (editor_editmode == EDITMODE_GAME)
	{
		Engine_RunGameLoop();
		if (DOSKeyTest(SC_E, 0, 0))
		{
			editor_editmode = EDITMODE_GENERIC;
			Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GENERIC]);
			Entity_SendMessageToAll(ENTITY_MESSAGE_PREFRAME);
			previous_gametimer = -1.0F;
		}

	}

	if (editor_editmode == EDITMODE_GENERIC)
	{
		if (DOSKeyTest(SC_C, 0, 0))
		{
		   BrMatrix34Identity(&sceneactor->t.t.mat);
		   BrMatrix34PreRotateX(&sceneactor->t.t.mat, BR_ANGLE_DEG(-90.0));
//		   BrMatrix34PreRotateY(&sceneactor->t.t.mat, BR_ANGLE_DEG(0.0));
//		   BrMatrix34PreRotateZ(&sceneactor->t.t.mat, BR_ANGLE_DEG(0.0));
//		   BrMatrix34PostTranslate(&rootactor->t.t.mat, BR_SCALAR(20.0), BR_SCALAR(0.0), BR_SCALAR(30.0));
		}

		if (DOSKeyTest(SC_X, 0, REPT_FIRST_DOWN))
		{
			editor_editmode=EDITMODE_GAME;
			Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GAME]);
		}

		if (DOSKeyTest(SC_M, 0, REPT_FIRST_DOWN))
		{
			current_frame++;
		}
	
		if (DOSKeyTest(SC_P, 0, REPT_FIRST_DOWN))
		{
			current_frame--;
		}

		if (DOSKeyTest(SC_T, 0, REPT_FIRST_DOWN))
		  currentgroup--;
	
		if (DOSKeyTest(SC_Y, 0, REPT_FIRST_DOWN))
		  currentgroup++;

		if (DOSKeyTest(SC_L, 0, REPT_FIRST_DOWN))
		  scenerot=!scenerot;

		if (currentgroup>=loadedanimations)
			currentgroup=0;

		if (currentgroup<0)
			currentgroup=loadedanimations-1;

		if (DOSKeyTest(SC_R, 0, 0))
		  frame_delta = -1;
	
		if (DOSKeyTest(SC_F, 0, 0))
		  frame_delta = 1;
	
		if (DOSKeyTest(SC_S, 0, 0))
		  frame_delta = 0;

		if (DOSKeyTest(SC_Z, 0, REPT_FIRST_DOWN))
		  fillcolour = !fillcolour;

	}

	if (editor_editmode == EDITMODE_LIGHTS )
	{
		if (DOSKeyTest(SC_E, 0, REPT_FIRST_DOWN))
		{
		  currentwlight++;
			if (currentwlight>=maxwlights)
				currentwlight=0;
		}

		if (DOSKeyTest(SC_W, 0, REPT_FIRST_DOWN))
		{
		  currentwlight--;
			if (currentwlight<0)
				currentwlight=maxwlights-1;
		}

		if (DOSKeyTest(SC_T, 0, REPT_FIRST_DOWN))
		{
			ToggleALightKeyb();
		}

		if (DOSKeyTest(SC_A, 0, REPT_FIRST_DOWN))
		{
			AllLightsOn();
		}

		if (DOSKeyTest(SC_S, 0, REPT_FIRST_DOWN))
		{
			AllLightsOff();
		}

		if (DOSKeyTest(SC_D, 0, REPT_FIRST_DOWN))
		{
			AllLightsInvert();
		}

		thislight=NULL;
		if (currentwlight<maxwlights)
		{
			thislight=(br_light *) wlight[currentwlight]->type_data;
			if (DOSKeyTest(SC_P, 0, REPT_FIRST_DOWN))
			{
				thislight->attenuation_q=BR_SUB(thislight->attenuation_q,BR_SCALAR(0.1));
			}
			if (DOSKeyTest(SC_L, 0, REPT_FIRST_DOWN))
			{
				thislight->attenuation_q=BR_ADD(thislight->attenuation_q,BR_SCALAR(0.1));
			}

			if (DOSKeyTest(SC_O, 0, REPT_FIRST_DOWN))
			{
				thislight->attenuation_l=BR_SUB(thislight->attenuation_l,BR_SCALAR(0.1));
			}
			if (DOSKeyTest(SC_K, 0, REPT_FIRST_DOWN))
			{
				thislight->attenuation_l=BR_ADD(thislight->attenuation_l,BR_SCALAR(0.1));
			}

			if (DOSKeyTest(SC_I, 0, REPT_FIRST_DOWN))
			{
				thislight->attenuation_c=BR_SUB(thislight->attenuation_c,BR_SCALAR(0.1));
			}
			if (DOSKeyTest(SC_J, 0, REPT_FIRST_DOWN))
			{
				thislight->attenuation_c=BR_ADD(thislight->attenuation_c,BR_SCALAR(0.1));
			}


			if (DOSKeyTest(SC_Z, 0, REPT_FIRST_DOWN))
			{
				thislight->cone_outer=BrScalarToAngle(BR_SUB(BrAngleToScalar(thislight->cone_outer),BrAngleToScalar(BR_ANGLE_DEG(1))));
			}
			if (DOSKeyTest(SC_X, 0, REPT_FIRST_DOWN))
			{
				thislight->cone_outer=BrScalarToAngle(BR_ADD(BrAngleToScalar(thislight->cone_outer),BrAngleToScalar(BR_ANGLE_DEG(1))));
			}

			if (DOSKeyTest(SC_C, 0, REPT_FIRST_DOWN))
			{
				thislight->cone_inner=BrScalarToAngle(BR_SUB(BrAngleToScalar(thislight->cone_inner),BrAngleToScalar(BR_ANGLE_DEG(1))));
			}
			if (DOSKeyTest(SC_V, 0, REPT_FIRST_DOWN))
			{
				thislight->cone_inner=BrScalarToAngle(BR_ADD(BrAngleToScalar(thislight->cone_inner),BrAngleToScalar(BR_ANGLE_DEG(1))));
			}

		}

	}

	// Store current root actor transform.
	//BrTransformToTransform(&store_root_transform, &(actors->t));

	// Play VUE file by loading transforms into actors.
		
//#if NOPEEPS
/* TODO: Must put this into a playvue() function */
	if (multitotal_frames[currentgroup] != 0)
	{
		// Clamp frame number to valid range.

		if (current_frame < 0)
			current_frame = multitotal_frames[currentgroup] - 1;
	  
		if (current_frame >= multitotal_frames[currentgroup])
			current_frame = 0;


		// Apply animation to world.
		for (i = 0; i < multiframes[currentgroup][current_frame].ntransforms; i++)
			multiframes[currentgroup][current_frame].transforms[i].actor->t.t.mat =
				multiframes[currentgroup][current_frame].transforms[i].mat;

		// Move to next frame.
		current_frame += frame_delta;
	}
//#endif	

	// Apply animation to level.

#if 0
	for (i = 0; i < multiframes[3][current_lframe].ntransforms; i++)
		multiframes[3][current_lframe].transforms[i].actor->t.t.mat =
			multiframes[3][current_lframe].transforms[i].mat;
#endif

	// Bodgey way to make the second 'Ape' display properly

#if 0
	for (i = 0; i < multiframes[3][1].ntransforms; i++)
		multiframes[3][1].transforms[i].actor->t.t.mat =
			multiframes[3][1].transforms[i].mat;
#endif

	current_lframe++;
	if (current_lframe>=41)
	{
		current_lframe=0;
	}

	// Restore current world transform.
	//BrTransformToTransform(&(actors->t), &store_root_transform);

	// Render.

	if (fillcolour)
	{
		BrPixelmapFill(back_screen, 4+4*32+4*32*32 );
	}
	else
	{
		BrPixelmapFill(back_screen, 0 );
	}
	BrPixelmapFill(depth_buffer, 0xffffffff);
#ifdef DOIT_ZS
	BrZsSceneRender(world, camera, back_screen);
#endif
#ifdef DOIT_ZB
	switch (editor_editmode)
	{
		case EDITMODE_GAME:
			Entity_SendMessageToAll(ENTITY_MESSAGE_PREFRAME);
			game_rootactor->render_style = BR_RSTYLE_DEFAULT;
			game_worldactor->render_style = BR_RSTYLE_NONE;

			BrZbSceneRender(world, blokecam, back_screen, depth_buffer);

			game_rootactor->render_style = BR_RSTYLE_NONE;
			game_worldactor->render_style = BR_RSTYLE_DEFAULT;
			BrZbSceneRender(world, blokecam, back_screen, depth_buffer);

			game_rootactor->render_style = BR_RSTYLE_DEFAULT;
			game_worldactor->render_style = BR_RSTYLE_DEFAULT;

			Entity_SendMessageToAll(ENTITY_MESSAGE_MIDFRAME);
			for (i=0;i<overlay_total;i++)
			{
				Overlay_DisplayOverlay(back_screen,depth_buffer,overlay_array[i]);
			}
			Entity_SendMessageToAll(ENTITY_MESSAGE_AFTERFRAME);
			break;
		case EDITMODE_GENERIC:
		case EDITMODE_LIGHTS:
			game_rootactor->render_style = BR_RSTYLE_DEFAULT;
			game_worldactor->render_style = BR_RSTYLE_NONE;

			BrZbSceneRender(world, viewcamera, back_screen, depth_buffer);

			game_rootactor->render_style = BR_RSTYLE_NONE;
			game_worldactor->render_style = BR_RSTYLE_DEFAULT;
			BrZbSceneRender(world, viewcamera, back_screen, depth_buffer);

			game_rootactor->render_style = BR_RSTYLE_DEFAULT;
			game_worldactor->render_style = BR_RSTYLE_DEFAULT;
			break;
		case EDITMODE_ANIMATION:
			BrZbSceneRender(anim_world, anim_camera1, anim_subpixel1, depth_buffer);
			BrZbSceneRender(anim_world, anim_camera2, anim_subpixel2, depth_buffer);
			BrPixelmapLine(back_screen,-back_screen->width/2,0,back_screen->width/2,0,BR_COLOUR_RGB(255,255,255));
			BrPixelmapLine(back_screen,0,-back_screen->height/2,0,back_screen->height/2,BR_COLOUR_RGB(255,255,255));
			break;
	}

#endif

	Editor_HandleEditorStates(mouse_x,mouse_y,mouse_buttons);

	if (editor_editmode == EDITMODE_LIGHTS)
	{
		BrPixelmapTextF(back_screen,32-320,4-180+8,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
						"Light %d out of %d lights",currentwlight+1,maxwlights);

		if (thislight != NULL)
		{
			char *typename,*active;
			char extrainfo[256];
			int flags;
			flags = Editor_MenuGetFlags(lightsmenu,currentwlight) & E_MENU_I_TICKED;
			if (flags)
				active="On";
			else
				active="Off";
			sprintf(extrainfo,"attenuation_c %f",BrScalarToFloat(thislight->attenuation_c));
			BrPixelmapTextF(back_screen,32-320+192,4-180+8+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
							extrainfo);
			sprintf(extrainfo,"attenuation_l %f",BrScalarToFloat(thislight->attenuation_l));
			BrPixelmapTextF(back_screen,32-320+192,4-180+8+10+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
							extrainfo);
			sprintf(extrainfo,"attenuation_q %f",BrScalarToFloat(thislight->attenuation_q));
			BrPixelmapTextF(back_screen,32-320+192,4-180+8+10+10+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
							extrainfo);
			sprintf(extrainfo,"RGB colour %d:%d:%d",BR_RED(thislight->colour),BR_GRN(thislight->colour),BR_BLU(thislight->colour));
			BrPixelmapTextF(back_screen,32-320+384,4-180+8+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
							extrainfo);

			switch (thislight->type)
			{
				case BR_LIGHT_DIRECT:
					typename="Direct light";
					break;
				case BR_LIGHT_POINT:
					typename="Point light";
					break;
				case BR_LIGHT_SPOT:
					typename="Spot light";
					sprintf(extrainfo,"outercone %f degs",BrScalarToFloat(BrAngleToDegree(thislight->cone_outer)));
					BrPixelmapTextF(back_screen,32-320,4-180+8+10+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
									extrainfo);
					sprintf(extrainfo,"innercone %f degs",BrScalarToFloat(BrAngleToDegree(thislight->cone_inner)));
					BrPixelmapTextF(back_screen,32-320,4-180+8+10+10+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
									extrainfo);
					break;
			}
			BrPixelmapTextF(back_screen,32-320,4-180+8+10,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
							"Type: %s %s",typename,active);
		}

	}

	if (editor_editmode == EDITMODE_GENERIC)
	{
		if (scenerot)
		{
			BrPixelmapTextF(back_screen,32-320,4-180+16,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
						"Moving scene model");
		}
		else
		{
			BrPixelmapTextF(back_screen,32-320,4-180+16,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
						"Moving camera model");
		}
	}

	if (editor_editmode == EDITMODE_ANIMATION)
	{
		BrPixelmapTextF(back_screen,320-96,-240+9,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
					"Animation editor");
		BrPixelmapTextF(anim_subpixel1,-anim_subpixel1->width/2+2,-anim_subpixel1->height/2+2,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
					"Top view");
		BrPixelmapTextF(anim_subpixel2,-anim_subpixel2->width/2+2,-anim_subpixel2->height/2+2,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
					"Free view");
	}

//	BrPixelmapTextF(back_screen,-back_screen->width/2+2,-back_screen->height/2+2,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,
//		"timer %d",DOSClockRead());
	if (editor_editmode != EDITMODE_GAME)
	{
		Editor_DrawMenus(back_screen);	
		Editor_DrawMouse(back_screen,65535,mouse_x,mouse_y);
	}
	Editor_HandleConsole();
	BrPixelmapDoubleBuffer(screen, back_screen);
      
	
	if (editor_editmode == EDITMODE_GAME)
	{
		if (DOSKeyTest(SC_S, 0, REPT_FIRST_DOWN))
		{
			char bufft[256];
			i = back_screen->type;
			back_screen->type = BR_PMT_RGB_565;
			sprintf(bufft,"d:\\cult\\screens\\s%3.3d.pix",screensaven);
			BrPixelmapSave(bufft,back_screen);
			screensaven++;
			back_screen->type = i;
		}
	}    
	// Mouse controls.

	if (scenerot)
	{
	    if ( Control2(world, sceneactor, rootactor) )
		   return BRE_FAIL ;
	}
	else
	{
	    if ( Control(world, camera, rootactor) )
		   return BRE_FAIL ;
	}


  	return(BRE_OK);
}
   

br_error BrDemo_ShutDown()
{
   // Close down

   BrPixelmapFree(depth_buffer);
   BrPixelmapFree(back_screen);

   depth_buffer = NULL ;
   back_screen = NULL ;

#ifdef DOIT_ZS
   BrZsEnd();
#endif
#ifdef DOIT_ZB
   BrZbEnd();
#endif
   return(BRE_OK);
}

/* This decides what screen modes to let BRender show on the menu */

br_error BrDemo_ValidateScreenMode(br_outfcty_desc *desc)
{
	if (desc->width==640 && desc->height==480 && ( desc->pmbits==16 || desc->pmbits==15))
	{
		return BRE_OK;
	}
	return BRE_FAIL;
}
   
void *primpool;
br_order_table *otable,*primary_order_table;

/* Some call backs that decide what the menus should do! */
int my_MenuCallback_Main(int menuid,int entry_id,int message)
{
	char levelfilepath[256];

	switch(message)
	{	
		case E_MENU_M_SELECTED:
			switch(entry_id)
			{
				case 2:
					Editor_CloseAllMenus();
					if (BrDemo_AnyFileRequest( "Load level file", 1 ,"Level File (*.LEV)\0*.LEV\0Any File (*.*)\0*.*\0", levelfilepath, "*.LEV") != NULL)
					{
						LoadLevel(levelfilepath);
					}
					break;
				case 3:
					Editor_CloseAllMenus();
					if (BrDemo_AnyFileRequest( "Save level file", 0 ,"Level File (*.LEV)\0*.LEV\0Any File (*.*)\0*.*\0", levelfilepath, "*.LEV") != NULL)
					{
						SaveLevel(levelfilepath);
					}
					break;
				case 6:
					if ( Editor_MenuGetFlags(menuid,entry_id) & E_MENU_I_TICKED )
						Editor_SetAllBilinearNot();
					else
						Editor_SetAllBilinear();
					LinkList_Create();
					break;
				case 16:
					editor_editmode=EDITMODE_GAME;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GAME]);
					break;

			}
			break;

	}

	return 0;
}


int my_MenuCallback_Cameras(int menuid,int entry_id,int message)
{
	br_actor *camera;

	switch(message)
	{	
		case E_MENU_M_SELECTED:
			viewcamera = wcameras[entry_id];

			camera = viewcamera;

			((br_camera *) camera->type_data)->type = BR_CAMERA_PERSPECTIVE;
			((br_camera *) camera->type_data)->field_of_view = BR_ANGLE_DEG(55.0);
			((br_camera *) camera->type_data)->hither_z = BR_SCALAR(2.0);
			((br_camera *) camera->type_data)->yon_z = BR_SCALAR(20000.0);
			((br_camera *) camera->type_data)->aspect = BR_SCALAR(1.6);
			camera->t.type = BR_TRANSFORM_MATRIX34;

			break;
	}

	return 0;
}


extern void bunchofspiders(void);

static char vuefilepath[256];
int my_MenuCallback_New(int menuid,int entry_id,int message)
{

	switch(message)
	{	
		case E_MENU_M_SELECTED:
			switch(entry_id)
			{
				case 0:
					hierarchybodge=0;
					levelloadedwithbodge = 0;
					Editor_CloseAllMenus();
					Entity_SendMessageToAll(ENTITY_MESSAGE_INSTANCE_CLOSEDOWN);
					Entity_SendMessageToAll(ENTITY_MESSAGE_SYSTEM_CLOSEDOWN);
					BrDemo_HandleNewFile();
					Entity_SendMessageToAll(ENTITY_MESSAGE_SYSTEM_STARTUP);
					Entity_SendMessageToAll(ENTITY_MESSAGE_INSTANCE_STARTUP);
					editor_editmode=EDITMODE_GAME;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GAME]);
					break;
				case 1:
					hierarchybodge=1;
					levelloadedwithbodge = 1;
					Editor_CloseAllMenus();
					Entity_SendMessageToAll(ENTITY_MESSAGE_INSTANCE_CLOSEDOWN);
					Entity_SendMessageToAll(ENTITY_MESSAGE_SYSTEM_CLOSEDOWN);
					BrDemo_HandleNewFile();
					hierarchybodge=0;
					Entity_SendMessageToAll(ENTITY_MESSAGE_SYSTEM_STARTUP);
					Entity_SendMessageToAll(ENTITY_MESSAGE_INSTANCE_STARTUP);
					break;
				case 3:
					Editor_CloseAllMenus();
					if (BrDemo_AnyFileRequest( "Import VUE file", 1 ,"VUE File (*.VUE)\0*.VUE\0Any File (*.*)\0*.*\0", vuefilepath, "*.VUE") != NULL)
					{
						LoadVUE(vuefilepath, sceneactor);
					}
					break;
				case 4:
					Editor_CloseAllMenus();
					bunchofspiders();
					break;
			}
			break;

	}

	return 0;
}


int my_MenuCallback_Edit(int menuid,int entry_id,int message)
{

	switch(message)
	{	
		case E_MENU_M_SELECTED:
			switch(entry_id)
			{
				case 0:
					Editor_CloseAllMenus();
					editor_editmode=EDITMODE_LIGHTS;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_LIGHTS]);
					break;

				case 1:
					Editor_CloseAllMenus();
					editor_editmode=EDITMODE_ANIMATION;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_ANIMATION]);
					break;

				case 2:
					Editor_CloseAllMenus();
					editor_editmode=EDITMODE_ENTITY;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_ENTITY]);
					break;

			}
			break;

	}

	return 0;
}


static int lastlight;

void ToggleALightKeyb(void)
{
	int flags;

	if (currentwlight>=0 && currentwlight<maxwlights)
	{
		flags=Editor_MenuGetFlags(lightsmenu,currentwlight);
		if (flags & E_MENU_I_TICKED )
		{
			flags &= ~E_MENU_I_TICKED;
			BrLightDisable(wlight[currentwlight]);
		}
		else
		{
			flags |= E_MENU_I_TICKED;
			BrLightEnable(wlight[currentwlight]);
		}
		Editor_MenuSetFlags(lightsmenu,currentwlight,flags);
	}
}


int my_MenuCallback_LightEdit(int menuid,int entry_id,int message)
{
	int flags;

	switch(message)
	{	
		case E_MENU_M_OPENSUBMENU:
			lastlight = entry_id;
			break;
		case E_MENU_M_SELECTED:
			flags=Editor_MenuGetFlags(menuid,entry_id);
			if (entry_id>=0 && entry_id<maxwlights)
			{
				if (flags & E_MENU_I_TICKED )
				{
					BrLightEnable(wlight[entry_id]);
				}
				else
				{
					BrLightDisable(wlight[entry_id]);
				}
			}
			switch(entry_id)
			{
				case 32:
					Editor_CloseAllMenus();
					editor_editmode=EDITMODE_GENERIC;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GENERIC]);
					break;

			}
			break;
	}

	return 0;
}


int my_MenuCallback_LightParams(int menuid,int entry_id,int message)
{

	switch(message)
	{	
		case E_MENU_M_SELECTED:
//			Set the current edited light here!!!
//			printf("gfgfgfd\n");
			currentwlight=lastlight;
			break;
	}

	return 0;
}


int my_MenuCallback_AnimationEdit(int menuid,int entry_id,int message)
{

	switch(message)
	{	
		case E_MENU_M_SELECTED:
			switch(entry_id)
			{
				case 5:
					Editor_CloseAllMenus();
					if (BrDemo_AnyFileRequest( "Import VUE file", 1 ,"VUE File (*.VUE)\0*.VUE\0Any File (*.*)\0*.*\0", vuefilepath, "*.VUE") != NULL)
					{
						LoadVUE(vuefilepath, sceneactor);
					}
					break;

				case 32:
					Editor_CloseAllMenus();
					editor_editmode=EDITMODE_GENERIC;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GENERIC]);
					break;

			}
			break;
	}
	return 0;
}


int my_MenuCallback_EntityEdit(int menuid,int entry_id,int message)
{

	switch(message)
	{	
		case E_MENU_M_SELECTED:
			switch(entry_id)
			{
				case 5:
					Editor_CloseAllMenus();
					if (BrDemo_AnyFileRequest( "Add VUE animation file", 1 ,"VUE File (*.VUE)\0*.VUE\0Any File (*.*)\0*.*\0", vuefilepath, "*.VUE") != NULL)
					{
						LoadVUE(vuefilepath, sceneactor);
					}
					break;

				case 32:
					Editor_CloseAllMenus();
					editor_editmode=EDITMODE_GENERIC;
					Editor_SetMenuBaseId(editmodes_menuid[EDITMODE_GENERIC]);
					break;

			}
			break;
	}
	return 0;
}


static void SetupMenus(void)
{
	int base,menuid,temp,temp2;
	int i;

	editmodes_menuid[EDITMODE_GAME]=E_MENU_ERROR;

	base=menuid=Editor_CreateMenu();
	Editor_MenuSetTitle(menuid,"Main menu");
	Editor_MenuAttachEntry(menuid,0,"Info",E_MENU_I_SUBMENU);
	Editor_MenuAttachEntry(menuid,1,"New",E_MENU_I_SUBMENU);
	Editor_MenuAttachEntry(menuid,2,"Load...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,3,"Save...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,4,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,5,"Edit",E_MENU_I_SUBMENU);
	Editor_MenuAttachEntry(menuid,6,"PSX emulation",E_MENU_I_TICKABLE);
	Editor_MenuAttachEntry(menuid,7,"Cameras",E_MENU_I_SUBMENU);
	Editor_MenuAttachEntry(menuid,15,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,16,"Exit to game",E_MENU_I_NONE);
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_Main);
	editmodes_menuid[EDITMODE_GENERIC]=menuid;
	Editor_SetMenuBaseId(E_MENU_ERROR);

	camerasmenu=menuid=Editor_CreateMenu();
	Editor_MenuAttachSubMenu(base,7,menuid);
	Editor_MenuSetTitle(menuid,"Cameras");
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_Cameras);

	menuid=Editor_CreateMenu();
	Editor_MenuAttachSubMenu(base,1,menuid);
	Editor_MenuSetTitle(menuid,"New");
	Editor_MenuAttachEntry(menuid,0,"Level and exit to game...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,1,"Level...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,2,"Location...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,3,"Animation...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,4,"Bunch of Nasties!",E_MENU_I_NONE);
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_New);

	menuid=Editor_CreateMenu();
	Editor_MenuAttachSubMenu(base,0,menuid);
	Editor_MenuSetTitle(menuid,"Info");
	Editor_MenuAttachEntry(menuid,0,"Cult Game/Editor",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,1,"Written by Martin Piper",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,2,"V1.01 14 July 1997",E_MENU_I_NO_SELECT);

	temp=menuid=Editor_CreateMenu();
	Editor_MenuAttachSubMenu(base,5,menuid);
	Editor_MenuSetTitle(menuid,"Edit");
	Editor_MenuAttachEntry(menuid,0,"Lights",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,1,"Animations",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,2,"Entity",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,3,"Level",E_MENU_I_NONE);
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_Edit);


	lightsmenu=temp2=menuid=Editor_CreateMenu();
	Editor_MenuAttachSubMenu(temp,0,menuid);
	Editor_MenuSetTitle(menuid,"Light edit mode");
	Editor_MenuAttachEntry(menuid,31,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,32,"Exit",E_MENU_I_NONE);
	editmodes_menuid[EDITMODE_LIGHTS]=menuid;
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_LightEdit);

	menuid=Editor_CreateMenu();
	for (i=0;i<31;i++)
	{
		Editor_MenuAttachSubMenu(temp2,i,menuid);
	}
	Editor_MenuSetTitle(menuid,"Light parameters");
	Editor_MenuAttachEntry(menuid,0,"Parameters",E_MENU_I_NONE);
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_LightParams);


	menuid=Editor_CreateMenu();
	Editor_MenuSetTitle(menuid,"Animation edit mode");
	Editor_MenuAttachEntry(menuid,0,"New",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,1,"Load...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,2,"Save...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,3,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,4,"Import 3DS...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,5,"Import VUE...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,31,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,32,"Exit",E_MENU_I_NONE);
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_AnimationEdit);
	editmodes_menuid[EDITMODE_ANIMATION]=menuid;

	menuid=Editor_CreateMenu();
	Editor_MenuSetTitle(menuid,"Entity edit mode");
	Editor_MenuAttachEntry(menuid,0,"New",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,1,"Load...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,2,"Save...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,3,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,4,"Import 3DS...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,5,"Add VUE animation...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,31,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,32,"Exit",E_MENU_I_NONE);
	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_EntityEdit);
	editmodes_menuid[EDITMODE_ENTITY]=menuid;

	menuid=Editor_CreateMenu();
	Editor_MenuSetTitle(menuid,"Level edit mode");
	Editor_MenuAttachEntry(menuid,0,"New",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,1,"Load...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,2,"Save...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,3,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,4,"Insert 3DS...",E_MENU_I_NONE);
	Editor_MenuAttachEntry(menuid,5,"Add VUE animation...",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,31,"",E_MENU_I_NO_SELECT);
	Editor_MenuAttachEntry(menuid,32,"Exit",E_MENU_I_NONE);
//	Editor_MenuAttachCallBack(menuid,&my_MenuCallback_EntityEdit);
	editmodes_menuid[EDITMODE_LEVEL]=menuid;
}

br_error BrDemo_InitApp(int argc, char **argv)
{
   int mytemp,i;
   br_error r ;
   br_actor *copy;
	br_actor *wibble;
	br_model *mwibble=NULL;
	br_pixelmap *temppix;
//	int sampleid;

   r = BrDemo_Allocate_Pixelmaps( "Cult V1.01 + Editor",
	                              &engine_screen, &engine_back, 
	                              &engine_depth, &palette, 
								  "winstd.pal" );
   if ( r != BRE_OK )
      return r ;

	Init_ResourceList();
	/* Stops compiler complaining */
	i=0;
	/* Setup screen coords */
	screen = engine_screen;
	back_screen = engine_back;
	depth_buffer = engine_depth;

	anim_subpixel1=BrPixelmapAllocateSub(back_screen,0,0,320,240);
	anim_subpixel1->origin_x = anim_subpixel1->width/2;
	anim_subpixel1->origin_y = anim_subpixel1->height/2;

	anim_subpixel2=BrPixelmapAllocateSub(back_screen,320,240,320,240);
	anim_subpixel2->origin_x = anim_subpixel2->width/2;
	anim_subpixel2->origin_y = anim_subpixel2->height/2;

   screen->origin_x = screen->width/2;
   screen->origin_y = screen->height/2;
   back_screen->origin_x = back_screen->width/2;
   back_screen->origin_y = back_screen->height/2;

	copy_screen=BrPixelmapAllocate(back_screen->type,640,480,NULL,BR_PMAF_NORMAL);

#ifdef DOIT_ZS
   primpool=BrMemAllocate(768*1024,BR_MEMORY_APPLICATION);
   BrZsBegin(back_screen->type, primpool,768*1024);
#endif
#ifdef DOIT_ZB
   BrZbBegin(back_screen->type, depth_buffer->type);
#endif

	if ( (con_overlay = BrPixelmapLoad("d:\\cult\\data\\maps\\screens\\backscr.pix")) == NULL)
	{
		return BRE_FAIL;
	}
	BrMapAdd(con_overlay);

	Editor_OverlayDebug("Cult V1.01 + Editor");
	Editor_OverlayDebug("===================");
	Editor_OverlayDebug("");
	Editor_OverlayDebug("Init screens");
	Editor_OverlayDebug("Init sound");
	Editor_OverlayDebug("Init worlds");
	Editor_HandleConsole();
	BrPixelmapDoubleBuffer(screen, back_screen);

	temppix=BrPixelmapLoad("p:\\cult\\interfac\\compass2.pix");
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 8;
	overlay_array[overlay_total]->ypos = 480-80-8;
	overlay_total++;
	temppix=BrPixelmapLoad("p:\\cult\\interfac\\pillow.pix");
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 8+64;
	overlay_array[overlay_total]->ypos = 480-80-8;
	overlay_total++;

	temppix=BrFmtTGALoad("p:\\cult\\interfac\\energy.tga",0);
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 640-72-8-32-16;
	overlay_array[overlay_total]->ypos = 8;
	overlay_total++;

	temppix=BrFmtTGALoad("p:\\cult\\interfac\\karma.tga",0);
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320-16;
	overlay_array[overlay_total]->ypos = 8;
	overlay_total++;

	temppix=BrFmtTGALoad("p:\\cult\\interfac\\gun.tga",0);
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+96-16;
	overlay_array[overlay_total]->ypos = -4;
	overlay_total++;

	temppix=BrFmtTGALoad("p:\\cult\\interfac\\hex.tga",0);
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+128;
	overlay_array[overlay_total]->ypos = 480-32-8-32;
	overlay_total++;

	temppix=BrFmtTGALoad("p:\\cult\\interfac\\9.tga",0);
	BrMapAdd(temppix);
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+96+64-16;
	overlay_array[overlay_total]->ypos = 8+8;
	overlay_total++;
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+96+64+16-16;
	overlay_array[overlay_total]->ypos = 8+8;
	overlay_total++;
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+96+64+16+16-16;
	overlay_array[overlay_total]->ypos = 8+8;
	overlay_total++;
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+32-16;
	overlay_array[overlay_total]->ypos = 8+8;
	overlay_total++;
	overlay_array[overlay_total] = Overlay_Init(temppix);
	overlay_array[overlay_total]->xpos = 320+32+16-16;
	overlay_array[overlay_total]->ypos = 8+8;
	overlay_total++;

/* FIXME: This seems to only work for this sample, humm. */
//	sampleid=LoadSample("d:\\cult\\data\\music\\cultmix.wav");
//	PlaySample(sampleid,255);

//	BrPixelmapTextF(back_screen,-120,-4,BR_COLOUR_RGB(255,255,255),BrFontProp7x9,"Loading...");
//	BrPixelmapDoubleBuffer(screen, back_screen);

	Editor_SetupEditorEnvironment();
	SetupMenus();

   if (multitransforms==NULL)
   {
      mytemp=sizeof(struct ani_transform)*MAXTRANSFORMS;
      multitransforms=BrMemAllocate(mytemp,BR_MEMORY_APPLICATION);
   }

   // Create world from VUE file.

   world = BrActorAllocate(BR_ACTOR_NONE, NULL);
   anim_world = BrActorAllocate(BR_ACTOR_NONE, NULL);

// Tends to make all models dissapear, dunno why. ;-)
	copy = BrActorAdd(world,(wibble=BrActorAllocate(BR_ACTOR_NONE,NULL)));
//	copy->render_style = BR_RSTYLE_EDGES;

#ifdef DOIT_ZS
   BrZsActorOrderTableSet(world,
             BrZsOrderTableAllocate(1023, BR_ORDER_TABLE_NEW_BOUNDS |
                                    BR_ORDER_TABLE_SORT_NEAR, BR_SORT_MAX));

   primary_order_table = BrZsOrderTableAllocate(4048, BR_ORDER_TABLE_NEW_BOUNDS | BR_ORDER_TABLE_SORT_NEAR, BR_SORT_MIN);
   BrZsOrderTablePrimaryEnable(primary_order_table);
#endif

   LoadShadeTable(back_screen->type);
#if NOPEEPS
   LoadTexture();
   LoadMaterial();
   LoadModel();
   actors = LoadActors();
   actors2 = LoadActors2();
#endif
   rootactor = BrActorAllocate(BR_ACTOR_NONE, NULL);
//   BrMatrix34RotateX(&rootactor->t.t.mat, BR_ANGLE_DEG(0.0));
//   BrMatrix34PostRotateY(&rootactor->t.t.mat, BR_ANGLE_DEG(23.0));
#if NOPEEPS
   BrActorAdd(rootactor, actors2);
#endif
   BrActorAdd(world, rootactor);

#if NOPEEPS
   rootactor = BrActorAllocate(BR_ACTOR_NONE, NULL);
   BrMatrix34PreRotateX(&rootactor->t.t.mat, BR_ANGLE_DEG(0.0));
   BrMatrix34PostTranslate(&rootactor->t.t.mat, BR_SCALAR(20.0), BR_SCALAR(0.0), BR_SCALAR(30.0));
   BrActorAdd(rootactor, actors);
   BrActorAdd(world, rootactor);
#endif

//  backactor=BrActorLoad("d:\\bloodsqd\\backgrnd\\psx\\diner4.act");
//	UpdateWLightList(backactor);

   copy = BrActorAllocate(BR_ACTOR_NONE, NULL);
   BrMatrix34Identity(&copy->t.t.mat);
   BrMatrix34PreRotateX(&copy->t.t.mat, BR_ANGLE_DEG(-90.0));
//   BrActorAdd(copy,backactor);
   BrActorAdd(world,copy);
	sceneactor=copy;

	//Editor_OverlayDebug("Loading VUE animations");

   //LoadVUE("d:\\bloodsqd\\chars\\nathan\\nathan.vue", actors);
   //LoadVUE("d:\\bloodsqd\\rawfiles\\simjump.vue", actors);
   //LoadVUE("d:\\bloodsqd\\chars\\morphed\\morphed.vue", actors);
   //LoadVUE("d:\\bloodsqd\\backgrnd\\level1.vue", backactor);

   //LoadVUE("d:\\bloodsqd\\chars\\morphed\\morphed.vue", actors2);

 
   light = BrActorAllocate(BR_ACTOR_LIGHT, NULL);
   light->identifier = "baselight";
   ((br_light *) light->type_data)->type = BR_LIGHT_POINT;
   ((br_light *) light->type_data)->attenuation_c = BR_SCALAR(0.5);
   ((br_light *) light->type_data)->colour = BR_COLOUR_RGB(255, 255, 255);
   BrActorAdd(world, light);
//   BrLightEnable(light);

#if 1
   light = BrActorAllocate(BR_ACTOR_LIGHT, NULL);
   ((br_light *) light->type_data)->type = BR_LIGHT_POINT;
   ((br_light *) light->type_data)->attenuation_c = BR_SCALAR(0.5);
   ((br_light *) light->type_data)->colour = BR_COLOUR_RGB(255, 255, 255);
   BrActorAdd(anim_world, light);
//   BrLightEnable(light);
#endif


   camera = BrActorAllocate(BR_ACTOR_CAMERA, NULL);
	viewcamera = camera;
   camera->identifier = "editcamera";
   BrMatrix34Identity(&camera->t.t.mat);
   ((br_camera *) camera->type_data)->type = BR_CAMERA_PERSPECTIVE;
   ((br_camera *) camera->type_data)->field_of_view = BR_ANGLE_DEG(55.0);
   ((br_camera *) camera->type_data)->hither_z = BR_SCALAR(2.0);
   ((br_camera *) camera->type_data)->yon_z = BR_SCALAR(20000.0);
   ((br_camera *) camera->type_data)->aspect = BR_SCALAR(1.6);
   camera->t.type = BR_TRANSFORM_MATRIX34;
   // Shift camera as required by size of model.
   BrMatrix34Translate(&camera->t.t.mat, BR_SCALAR(0.0), BR_SCALAR(6.0), BR_SCALAR(100.0));
   BrActorAdd(world, camera);

   blokecam = BrActorAllocate(BR_ACTOR_CAMERA, NULL);
   blokecam->identifier = "blokecam";
   BrMatrix34Identity(&blokecam->t.t.mat);
   ((br_camera *) blokecam->type_data)->type = BR_CAMERA_PERSPECTIVE;
   ((br_camera *) blokecam->type_data)->field_of_view = BR_ANGLE_DEG(55.0);
   ((br_camera *) blokecam->type_data)->hither_z = BR_SCALAR(2.0);
   ((br_camera *) blokecam->type_data)->yon_z = BR_SCALAR(20000.0);
   ((br_camera *) blokecam->type_data)->aspect = BR_SCALAR(1.6);
   blokecam->t.type = BR_TRANSFORM_MATRIX34;
	// Shift camera as required by size of model.
	BrMatrix34Translate(&blokecam->t.t.mat, BR_SCALAR(0.0), BR_SCALAR(6.0), BR_SCALAR(100.0));
	BrActorAdd(world, blokecam);


	/* First hack test camera, named, funnily enough, camera1 */
   anim_camera1 = BrActorAllocate(BR_ACTOR_CAMERA, NULL);
   anim_camera1->identifier = "anim_camera1";
   ((br_camera *) anim_camera1->type_data)->type = BR_CAMERA_PERSPECTIVE;
   ((br_camera *) anim_camera1->type_data)->field_of_view = BR_ANGLE_DEG(55.0);
   ((br_camera *) anim_camera1->type_data)->hither_z = BR_SCALAR(2.0);
   ((br_camera *) anim_camera1->type_data)->yon_z = BR_SCALAR(20000.0);
   ((br_camera *) anim_camera1->type_data)->aspect = BR_SCALAR(1.6);
   anim_camera1->t.type = BR_TRANSFORM_MATRIX34;
   BrMatrix34Translate(&anim_camera1->t.t.mat, BR_SCALAR(0.0), BR_SCALAR(0.0), BR_SCALAR(50.0));
   BrActorAdd(anim_world, anim_camera1);

	/* Second hack test camera, named, funnily enough, anim_camera2 */
   anim_camera2 = BrActorAllocate(BR_ACTOR_CAMERA, NULL);
   anim_camera2->identifier = "anim_camera2";
   ((br_camera *) anim_camera2->type_data)->type = BR_CAMERA_PERSPECTIVE;
   ((br_camera *) anim_camera2->type_data)->field_of_view = BR_ANGLE_DEG(55.0);
   ((br_camera *) anim_camera2->type_data)->hither_z = BR_SCALAR(2.0);
   ((br_camera *) anim_camera2->type_data)->yon_z = BR_SCALAR(20000.0);
   ((br_camera *) anim_camera2->type_data)->aspect = BR_SCALAR(1.6);
   anim_camera2->t.type = BR_TRANSFORM_MATRIX34;
   BrMatrix34Translate(&anim_camera2->t.t.mat, BR_SCALAR(0.0), BR_SCALAR(0.0), BR_SCALAR(100.0));
   BrActorAdd(anim_world, anim_camera2);


//   BrMatrix34Copy(&light->t.t.mat, &camera->t.t.mat);

//	BODGEBrDemo_HandleNewFile("P:\\CULT\\MARTINP\\CHURCH\\final.3ds");

#if 0
	mwibble=Editor_ImportCFM("d:\\revme\\p911.cfm");
	if (mwibble!=NULL)
	{
		wibble->model=mwibble;
	}
#endif

	Engine_StartupGame(world);

	Editor_SetAllBilinear();

//	StopAllSamples();
//	FreeSample(sampleid);
	e_console_flags=0;

	return BRE_OK ;

}

#endif

// User controls. 

int Control(br_actor *world, br_actor *observer, br_actor *target)
{
   /*ControlObject(target);*/
   ControlObject(observer);
   
   if(DOSKeyTest(SC_Q,0,REPT_FIRST_DOWN))
      return 1;

   return 0;
}

int Control2(br_actor *world, br_actor *observer, br_actor *target)
{
   /*ControlObject(target);*/
   ControlObject2(observer);
   
   if(DOSKeyTest(SC_Q,0,REPT_FIRST_DOWN))
      return 1;

   return 0;
}


// Read the mouse to control an actor's translation and rotation.

void ControlObject(br_actor *target)
{
   br_matrix34 mat_target, mat_roll;
   br_scalar tx,ty,tz;

   // Mouse controls
   
   if ( ( mouse_buttons & BR_MSM_BUTTONL ) &&
       ( mouse_buttons & BR_MSM_BUTTONR ) )
   {
      // Drag object around in x/y plane

      tx = BR_MUL(BR_SCALAR(mouse_xd),BR_SCALAR(MSCALE * 50.0));
      tz = BR_MUL(BR_SCALAR(mouse_yd),BR_SCALAR(MSCALE * 50.0));

      BrMatrix34PostTranslate(&target->t.t.mat,tx,BR_SCALAR(0.0),tz);
      
   } 
   else if( mouse_buttons & BR_MSM_BUTTONL ) 
   {
      // Move object along z axis

      tx =  BR_MUL(BR_SCALAR(mouse_xd),BR_SCALAR(MSCALE * 50.0));
      ty = -BR_MUL(BR_SCALAR(mouse_yd),BR_SCALAR(MSCALE * 50.0));

      BrMatrix34PostTranslate(&target->t.t.mat,tx,ty,BR_SCALAR(0.0));
   } 
   else if ( mouse_buttons & BR_MSM_BUTTONR ) 
   {
      // Rotate object via rolling ball interface

      BrMatrix34RollingBall(&mat_roll,mouse_xd,0, ROLLING_BALL_SENSITIVITY );

      // Only modify the top 3x3

      BrMatrix34Copy(&mat_target, &target->t.t.mat);
      Matrix33Mul(&target->t.t.mat, &mat_target, &mat_roll);

   }

//   BrMatrix34Copy(&light->t.t.mat, &camera->t.t.mat);

}

void ControlObject2(br_actor *target)
{
   br_matrix34 mat_target, mat_roll;
   br_scalar tx,ty,tz;

   // Mouse controls
   
   if ( ( mouse_buttons & BR_MSM_BUTTONL ) &&
       ( mouse_buttons & BR_MSM_BUTTONR ) )
   {
      // Drag object around in x/y plane

      tx = BR_MUL(BR_SCALAR(mouse_xd),BR_SCALAR(MSCALE * 50.0));
      tz = BR_MUL(BR_SCALAR(mouse_yd),BR_SCALAR(MSCALE * 50.0));

      BrMatrix34PostTranslate(&target->t.t.mat,tx,BR_SCALAR(0.0),tz);
      
   } 
   else if( mouse_buttons & BR_MSM_BUTTONL ) 
   {
      // Move object along z axis

      tx =  BR_MUL(BR_SCALAR(mouse_xd),BR_SCALAR(MSCALE * 50.0));
      ty = -BR_MUL(BR_SCALAR(mouse_yd),BR_SCALAR(MSCALE * 50.0));

      BrMatrix34PostTranslate(&target->t.t.mat,tx,ty,BR_SCALAR(0.0));
   } 
   else if ( mouse_buttons & BR_MSM_BUTTONR ) 
   {
      // Rotate object via rolling ball interface

      BrMatrix34RollingBall(&mat_roll,mouse_xd,mouse_yd, ROLLING_BALL_SENSITIVITY );

      // Only modify the top 3x3

      BrMatrix34Copy(&mat_target, &target->t.t.mat);
      Matrix33Mul(&target->t.t.mat, &mat_target, &mat_roll);

   }

//   BrMatrix34Copy(&light->t.t.mat, &camera->t.t.mat);

}


// Screen resize function.

#if CHOICE_MAIN

br_error BrDemo_OnResize()
{
	BrDemo_Refresh_Pointers( &screen_buffer, &back_screen, &depth_buffer );
   
	return BRE_OK ;
}

#endif


// Matrix multiply for rotation only.

#define A(x,y) A->m[x][y]
#define B(x,y) B->m[x][y]
#define C(x,y) C->m[x][y]

void Matrix33Mul(br_matrix34 *A, br_matrix34 *B, br_matrix34 *C)
{
   A(0,0) = BR_MAC3(B(0,0),C(0,0), B(0,1),C(1,0), B(0,2),C(2,0));
   A(0,1) = BR_MAC3(B(0,0),C(0,1), B(0,1),C(1,1), B(0,2),C(2,1));
   A(0,2) = BR_MAC3(B(0,0),C(0,2), B(0,1),C(1,2), B(0,2),C(2,2));

   A(1,0) = BR_MAC3(B(1,0),C(0,0), B(1,1),C(1,0), B(1,2),C(2,0));
   A(1,1) = BR_MAC3(B(1,0),C(0,1), B(1,1),C(1,1), B(1,2),C(2,1));
   A(1,2) = BR_MAC3(B(1,0),C(0,2), B(1,1),C(1,2), B(1,2),C(2,2));

   A(2,0) = BR_MAC3(B(2,0),C(0,0), B(2,1),C(1,0), B(2,2),C(2,0));
   A(2,1) = BR_MAC3(B(2,0),C(0,1), B(2,1),C(1,1), B(2,2),C(2,1));
   A(2,2) = BR_MAC3(B(2,0),C(0,2), B(2,1),C(1,2), B(2,2),C(2,2));
}

void BrDemo_AboutToQuit()
{
	ShutdownSound();
}

br_error CloseDownScene(br_fmt_results *results)
{

	game_rootactor=NULL;
	if (results==NULL)
		return BRE_OK;

	AllLightsOff();
	BrActorRemove(results->actors[0]);

}

br_error StartupScene(br_fmt_results *results,char *basepath,char *basename)
{
	int i;
	br_material **material;
	br_scalar value;
	br_pixelmap *pixtemp;
	char temp[256];
	char pixmappath[256];
	char pixmappath2[256];
	char pixmapname[256];
	void *fh;
	int allpix=0;
	br_pixelmap *allpixelmap[2048];

	viewcamera = camera;
	if (results==NULL)
		return BRE_OK;

	strcpy(lastlevel3dsname,basepath);
	strcat(lastlevel3dsname,"\\");
	strcat(lastlevel3dsname,basename);
	strcat(lastlevel3dsname,".3ds");

	Editor_OverlayDebug("Starting up scene");
	if (results->nmaterials>0)
		BrFmtScriptMaterialSaveMany("d:\\cult\\data\\mat.scp",results->materials,(br_uint_16) results->nmaterials);
	AllLightsOffActor(results->actors[0]);
	BrActorSaveMany("d:\\cult\\data\\bits.act",results->actors,(br_uint_16) results->nactors);
	BrWriteModeSet(BR_FS_MODE_TEXT);
	BrActorSaveMany("d:\\cult\\data\\act.txt",results->actors,(br_uint_16) results->nactors);
	BrWriteModeSet(BR_FS_MODE_BINARY);
	BrModelRemoveMany(results->models,(br_uint_16) results->nmodels);
	BrModelSaveMany("d:\\cult\\data\\bits.dat",results->models,(br_uint_16) results->nmodels);
	if (results->nmaterials>0)
		BrMaterialRemoveMany(results->materials,(br_uint_16) results->nmaterials);
//	BrMapRemoveMany(results->pixelmaps,results->npixelmaps);

// http://hem1.passagen.se/carebear/

	sprintf(pixmappath,"%s\\%s.pix",basepath,basename);
	if (results->npixelmaps>0)
	{
	fh = BrFileOpenRead(pixmappath,0,NULL,NULL);
	if ( fh != NULL)
	{
		sprintf(temp,"      Loading all texturemaps in one block");
		Editor_OverlayDebug(temp);
		allpix=1;
		BrFileClose(fh);
		i=BrPixelmapLoadMany(pixmappath,allpixelmap,2048);
		BrMapAddMany(allpixelmap,i);
	}
	else
	{
	for (i=0;i<(int) results->npixelmaps;i++)
	{
		pixtemp=results->pixelmaps[i];
		if (pixtemp == NULL)
		{
			printf("erkness happened!!!\n");
			exit(0xdead);
		}

		strcpy(pixmappath,basepath);
		strcat(pixmappath,"\\");
		strcat(pixmappath,pixtemp->identifier);
//		strcat(pixmappath,".gif");
		strcat(pixmappath,".tga");

		strcpy(pixmappath2,basepath);
		strcat(pixmappath2,"\\");
		strcat(pixmappath2,pixtemp->identifier);
		strcat(pixmappath2,".pix");

		strcpy(pixmapname,pixtemp->identifier);
		BrMapRemove(pixtemp);
		BrPixelmapFree(pixtemp);

		pixtemp=NULL;
		fh = BrFileOpenRead(pixmappath2,0,NULL,NULL);
		if (fh != NULL)
		{
//			sprintf(temp,"      Loading texturemap %d called '%s'",i+1,pixmappath);
//			Editor_OverlayDebug(temp);
 			BrFileClose(fh);
			pixtemp=BrPixelmapLoad(pixmappath2);
		}
		else
		{
			fh = BrFileOpenRead(pixmappath,0,NULL,NULL);
			if (fh != NULL)
			{
//				sprintf(temp,"      Loading texturemap %d called '%s'",i+1,pixmappath);
//				Editor_OverlayDebug(temp);
 				BrFileClose(fh);
//				pixtemp=BrFmtGIFLoad(pixmappath,0);
				pixtemp=BrFmtTGALoad(pixmappath,0);
			}
		}
		if (pixtemp==NULL)
		{
			sprintf(temp,"      *** Failed to find texturemap %d called '%s'",i+1,pixmappath);
			Editor_OverlayDebug(temp);
//			pixtemp=BrPixelmapAllocate(BR_PMT_INDEX_8,1,1,NULL,BR_PMAF_NORMAL);
//			pixtemp->map=BrPixelmapAllocate(BR_PMT_RGBX_888,1,256,NULL,BR_PMAF_NORMAL);
			pixtemp=BrPixelmapLoad("d:\\cult\\data\\maps\\blank.pix");
		}
		pixtemp->identifier=BrMemStrDup(pixmapname);
		results->pixelmaps[i]=pixtemp;
	}
	BrMapAddMany(results->pixelmaps,results->npixelmaps);
	}
	}

	if (results->nmaterials>0)
	{
	BrFmtScriptMaterialLoadMany("d:\\cult\\data\\mat.scp",results->materials,(br_uint_16) results->nmaterials);

	material=results->materials;
	for (i=0;i<(int) results->nmaterials;i++)
	{
		if (material[i]->ka==0)
		{
			value=BR_SCALAR(0.098039);
			material[i]->ka=BrScalarToUFraction(value);
		}
		if (material[i]->kd==0)
		{
			value=BR_SCALAR(0.698039);
			material[i]->kd=BrScalarToUFraction(value);
		}

		if (material[i]->colour==0)
		{
			material[i]->colour=BR_COLOUR_RGB(178,178,178);
		}		

	}

	BrMaterialAddMany(results->materials,results->nmaterials);
	}

	results->nmodels=BrModelLoadMany("d:\\cult\\data\\bits.dat",results->models,(br_uint_16) results->nmodels);

	for (i=0;i<(int) results->nmodels;i++)
	{
		results->models[i]->flags |= BR_MODF_KEEP_ORIGINAL;
	}

	BrModelAddMany(results->models,(br_uint_16) results->nmodels);

	BrActorLoadMany("d:\\cult\\data\\bits.act",results->actors,(br_uint_16) results->nactors);

	switch (editor_editmode)
	{
		case EDITMODE_GAME:
		case EDITMODE_GENERIC:
		case EDITMODE_LIGHTS:
			BrActorAdd(sceneactor,results->actors[0]);
			game_rootactor=sceneactor;
			break;
		case EDITMODE_ANIMATION:
			BrActorAdd(anim_world,results->actors[0]);
			break;
	}

	Collision_MeshUpBaseWorld(world,results->actors[0]);

//	UpdateWLightList(results->actors[0]);
	UpdateWLightList(results);

	if (results->nmaterials>0)
		BrFmtScriptMaterialSaveMany("d:\\cult\\data\\matafter.scp",results->materials,(br_uint_16) results->nmaterials);
	if (results->npixelmaps>0)
	{
		BrPixelmapSaveMany("d:\\cult\\data\\pix.pix",results->pixelmaps,(br_uint_16) results->npixelmaps);
	}

	Editor_OverlayDebug("Scene startup OK");
}

static BR_CALLBACK sendthetext(char *string)
{
	Editor_OverlayDebug(string);

	return 0;
}


static char main3dsfilepath[256];
br_error BrDemo_HandleNewFile( void )
{
	char *bit;
	br_fmt_options fmt_options;
	br_3ds_options options;
	char buff[256];

	if (BrDemo_AnyFileRequest( "Import 3DS file", 1 ,"3DS File (*.3DS)\0*.3DS\0Any File (*.*)\0*.*\0", main3dsfilepath, "*.3DS") == NULL)
		return BRE_OK;

	CloseDownScene(results);

	e_console_flags=2;
	sprintf(buff,"Loading level '%s'",main3dsfilepath);
	Editor_OverlayDebug(buff);
	fmt_options.convert_flags=BR_FMT_CONVERT_ALL;

	/* This option works with Vanessas stuff */
	options.flags=//BR_3DS_FLAT_HIERARCHY |
					BR_3DS_SET_PERSPECTIVE |

//					BR_3DS_CORRECT_AXES |
					BR_3DS_APPLY_MESH_MATRIX |
					BR_3DS_APPLY_PIVOT |
					0;

	if (hierarchybodge == 0)
	{
#if 1
	/* This option works with Owens stuff */
	options.flags=BR_3DS_FLAT_HIERARCHY |
					BR_3DS_SET_PERSPECTIVE |
//					BR_3DS_CORRECT_AXES |
					BR_3DS_APPLY_MESH_MATRIX |
//					BR_3DS_APPLY_PIVOT |
					0;
#endif
	}

	options.report = sendthetext;
					

	results=MBrFmt3DSLoad(main3dsfilepath,&fmt_options,&options);
	Editor_OverlayDebug("Level load complete");

	bit=strrchr(main3dsfilepath,'.');
	if (bit!=NULL)
		bit[0]=0;	

	bit=strrchr(main3dsfilepath,'\\');
	if (bit!=NULL)
		bit[0]=0;	

	StartupScene(results,main3dsfilepath,bit+1);

	Editor_SetAllBilinear();
	AllLightsOn();

	e_console_flags=0;

	return BRE_OK;
}

int main_loaduplevel( void )
{
	char *bit;
	br_fmt_options fmt_options;
	br_3ds_options options;
	char buff[256];

	CloseDownScene(results);

	sprintf(main3dsfilepath,"p:\\cult\\level1\\soodiner.3ds");
	sprintf(main3dsfilepath,"p:\\cult\\veryt\\boxlev.3ds");

	sprintf(buff,"Loading level '%s'",main3dsfilepath);
	Editor_OverlayDebug(buff);
	fmt_options.convert_flags=BR_FMT_CONVERT_ALL;

	options.flags=//BR_3DS_FLAT_HIERARCHY |
					BR_3DS_SET_PERSPECTIVE |
//					BR_3DS_CORRECT_AXES |
					BR_3DS_APPLY_MESH_MATRIX |
					BR_3DS_APPLY_PIVOT |
					0;

	options.flags=BR_3DS_FLAT_HIERARCHY |
					BR_3DS_SET_PERSPECTIVE |
//					BR_3DS_CORRECT_AXES |
					BR_3DS_APPLY_MESH_MATRIX |
//					BR_3DS_APPLY_PIVOT |
					0;

	options.report = sendthetext;
					

	results=MBrFmt3DSLoad(main3dsfilepath,&fmt_options,&options);
	Editor_OverlayDebug("Level load complete");

	bit=strrchr(main3dsfilepath,'.');
	if (bit!=NULL)
		bit[0]=0;	

	bit=strrchr(main3dsfilepath,'\\');
	if (bit!=NULL)
		bit[0]=0;

	StartupScene(results,main3dsfilepath,bit+1);

	Editor_SetAllBilinear();
	AllLightsOn();

	return BRE_OK;
}


br_error BrDemo_HandleSavedFile( char *filepath )
{
	char *bit;
	br_fmt_options fmt_options;
	br_3ds_options options;
	char buff[256];

	strcpy(main3dsfilepath,filepath);
	CloseDownScene(results);

	e_console_flags=2;
	sprintf(buff,"Loading level '%s'",main3dsfilepath);
	Editor_OverlayDebug(buff);
	fmt_options.convert_flags=BR_FMT_CONVERT_ALL;

	/* This option works with Vanessas stuff */
	options.flags=//BR_3DS_FLAT_HIERARCHY |
					BR_3DS_SET_PERSPECTIVE |

//					BR_3DS_CORRECT_AXES |
					BR_3DS_APPLY_MESH_MATRIX |
					BR_3DS_APPLY_PIVOT |
					0;

	if (hierarchybodge == 0)
	{
#if 1
	/* This option works with Owens stuff */
	options.flags=BR_3DS_FLAT_HIERARCHY |
					BR_3DS_SET_PERSPECTIVE |
//					BR_3DS_CORRECT_AXES |
					BR_3DS_APPLY_MESH_MATRIX |
//					BR_3DS_APPLY_PIVOT |
					0;
#endif
	}

	options.report = sendthetext;
					

	results=MBrFmt3DSLoad(main3dsfilepath,&fmt_options,&options);
	Editor_OverlayDebug("Level load complete");

	bit=strrchr(main3dsfilepath,'.');
	if (bit!=NULL)
		bit[0]=0;	

	bit=strrchr(main3dsfilepath,'\\');
	if (bit!=NULL)
		bit[0]=0;	

	StartupScene(results,main3dsfilepath,bit+1);

	Editor_SetAllBilinear();
	AllLightsOn();

	e_console_flags=0;

	return BRE_OK;
}
