
--
-- Copyright (C) 2019  <fastrgv@gmail.com>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You may read the full text of the GNU General Public License
-- at <http://www.gnu.org/licenses/>.
--


----------------------------------------------------------------
with interfaces;
with interfaces.c;


with matutils;  use matutils;
with gametypes;  use gametypes;

with ada.directories;
with ada.characters.handling;
with ada.numerics; 
with text_io; use text_io;
with utex;

with gl;  use gl;


with cubemapobj;
with rectobj;
with pictobj;
with avatarolay;

with gl, gl.binding, gl.pointers;
with glu, glu.binding, glu.pointers;
with glext, glext.binding, glext.pointers;

with system;
with Interfaces.C;
use  type interfaces.c.unsigned;
with Interfaces.C.Pointers;
with interfaces.c.strings;

with pngloader;
with shader;

with snd4ada_hpp; --use snd4ada_hpp;



package body gameutils is

	use pngloader;
	use shader;




--procedure initializeNewMazes... see line 2414


function fmod( numer, denom : float ) return float is
	k : integer := integer(numer/denom);
begin
	return numer - float(k)*denom;
end fmod;


function odd( i: integer ) return boolean is
begin
	return ( i mod 2 = 1 );
end odd;



function min( x,y: float ) return float is
begin
	if x<y then return x;
	else return y; end if;
end min;

	function mini(i,j: integer) return integer is
	begin
		if i<j then return i;
		else return j; end if;
	end mini;


	procedure myassert( 
		condition : boolean;  
		flag: integer:=0;
		msg: string := ""
		) is
	begin
	  if condition=false then
			put("ASSERTION Failed!  ");
			if flag /= 0 then
				put( "@ " & integer'image(flag) &" : " );
			end if;
			put_line(msg);
			new_line;
			raise program_error;
	  end if;
	end myassert;




function max( x,y : float ) return float is
begin
	if y>x then return y;
	else return x; end if;
end;

function sqr( x:float ) return float is
begin
	return x*x;
end;

function dotprod( x,y,z, a,b,c : float ) return float is
begin
	return x*a + y*b + z*c;
end;









function hordistance( x1,y1, x2,y2 : float ) return float is
	arg: float := sqr(x2-x1) + sqr(y2-y1);
begin
	if arg>0.0 then
		return safeSqrt( arg );
	else
		return 0.0;
	end if;
end hordistance;

function signum( x : float ) return float is
begin
	if x>0.0 then
		return +1.0;
	elsif x<0.0 then
		return -1.0;
	else
		return 0.0;
	end if;
end signum;






	use interfaces.c;
	use interfaces.c.strings;
	use glext;
	use glext.pointers;
	use glext.binding;
	use gl;
	use gl.binding;
	use gl.pointers;




procedure InitSDL( name:string; hiDpi: boolean := false  ) is

	use system;

	profile, compflag,
	ires, jerror, error : glint;
	bresult : SDL_bool;

	linked : aliased SDL_version;

	psampl : aliased glint;

begin



	-- MacOSX:  If there is jerkiness on your Retina 
	-- display, use low dpi, which still looks pretty
	-- good, albeit with some noticable aliasing.

	if hidpi then
		put_line("HiDpi flag is ON");
		contextFlags := 
			SDL_WINDOW_SHOWN or SDL_WINDOW_OPENGL or 
			SDL_WINDOW_FULLSCREEN_DESKTOP or SDL_WINDOW_ALLOW_HIGHDPI;
	else
		contextFlags := 
			SDL_WINDOW_SHOWN or SDL_WINDOW_OPENGL or 
			SDL_WINDOW_FULLSCREEN_DESKTOP;
	end if;




	-- Careful!  Only initialize what we use (otherwise exe won't run):
	error := SDL_Init( SDL_INIT_TIMER or SDL_INIT_VIDEO ); -- video=>events too
	myassert( error = 0, 1000 );


	--get screen size:
	should_be_zero := SDL_GetCurrentDisplayMode(0, current'access);
	myassert( should_be_zero = 0, 577 );

	winwidth:=current.w;
	winheight:=current.h;



	jerror := SDL_Init(
		SDL_INIT_GAMECONTROLLER or
		SDL_INIT_JOYSTICK );

	joystik:=false;
	gamepad:=false;
	if  jerror = 0  and then SDL_NumJoysticks>=1  then

		if SDL_IsGameController(0)=sdl_true then --gamepad
			gamepad:=true; joystik:=false;
			ctrl := SDL_GameControllerOpen(0);
			jsa := SDL_GameControllerGetJoystick(ctrl);

			ires := SDL_GameControllerEventState(SDL_QUERY); -- ignore

			SDL_GameControllerUpdate;

			-- If the gamepad analog btn is down
			-- then this grabs the left HAT btn;
			-- otherwise this grabs the left stick:
			axis_rx := SDL_JoystickGetAxis(jsa, 0);
			axis_ry := SDL_JoystickGetAxis(jsa, 1); --move forw/back

			-- this grabs the right stick (look dir):
			axis_lx := SDL_JoystickGetAxis(jsa, 2);
			axis_ly := SDL_JoystickGetAxis(jsa, 3);

		else --joystick

			gamepad:=false; joystik:=true;
			jsa := SDL_JoystickOpen(0);

			put_line("#axes="& glint'image(sdl_joysticknumaxes(jsa)) );
			put_line("#btns="& glint'image(sdl_joysticknumbuttons(jsa)) );
			ires := SDL_JoystickEventState(SDL_QUERY); -- ignore
			SDL_JoystickUpdate;
			axis_lx := SDL_JoystickGetAxis(jsa, 0);
			axis_ly := SDL_JoystickGetAxis(jsa, 1);

		end if;

	end if;

	if gamepad then
		put_line("...gamePad detected...initialized");
	elsif joystik then
		put_line("...joyStick detected...initialized");
	else
		put_line("...no game controller detected...");
	end if;


-------------------------------------------------------------------------
	put_line("We compiled against SDL version "
		&gluint'image(sdl_major_version)&"."
		&gluint'image(sdl_minor_version)&"."
		&gluint'image(sdl_patchlevel) );


---------- begin 14feb15 insert ------------------------------------------------
	SDL_GetVersion( linked'access );
	put_line("We   linked against SDL version "
		&Uint8'image(linked.major)&"."
		&Uint8'image(linked.minor)&"."
		&Uint8'image(linked.patch) );
---------- end 14feb15 insert --------------------------------------------------

	bresult := SDL_SetHint( SDL_HINT_RENDER_VSYNC, sdl_one );
	myassert( bresult = SDL_TRUE, 1001 );
	bresult := SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, sdl_one );
	myassert( bresult = SDL_TRUE, 1002 );




	--// Turn on double buffering.
	error := SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	myassert( error = 0, 1003 );
	error := SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	myassert( error = 0, 1004 );
	error := SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
	myassert( error = 0, 1005 );





	error := SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	myassert( error = 0, 1006 );
	error := SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
	myassert( error = 0, 1007 );




	error := SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, 
											SDL_GL_CONTEXT_PROFILE_CORE );
	myassert( error = 0, 1008 );

	-- Note that OSX currently requires the forward_compatible flag!
	error := SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, 
											SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG );
	myassert( error = 0, 1009 );

	-- note: the opening window predetermined multisampling support:
	if okmultisamp then
		-- the next line is known to cause failure, so would
		-- be erroneous on an Intel Skylake 520, for example.
		error := SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
		myassert( error = 0, 1010 );

		put_line("MultSampling is supported");

	else

		put_line("MultSampling is NOT supported");

	end if;



	mainWindow := SDL_CreateWindow( new_string(name) , 
			SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
			current.w, current.h, contextFlags);

-- NOW, we can begin to test for GLerrors ##############################

	mainGLContext := SDL_GL_CreateContext(mainWindow);

	error := SDL_GL_MakeCurrent( mainWindow, mainGLContext );
	myassert( error = 0, 1010 );


---------------------------------------------------------------------
	error := SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES,psampl'access);
	myassert( error = 0 ,1013 );
	put_line("psampl="&glint'image(psampl));   -- 4
---------------------------------------------------------------------

	glgetintegerv(gl_major_version, major'address);
	glgetintegerv(gl_minor_version, minor'address);
	put_line("ogl-version-query:"&glint'image(major)&":"&glint'image(minor));


	glGetIntegerv(GL_CONTEXT_PROFILE_MASK, profile'address);
	if( profile = GL_CONTEXT_CORE_PROFILE_BIT ) then
		put_line("ogl-query:  Core Profile");
	end if;


	-- OSX currently requires the forward_compatible flag!
	glGetIntegerv(GL_CONTEXT_FLAGS, compflag'address);
	if( compflag = GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT ) then
		put_line("ogl-query:  Forward-Compatible bit is set");
	end if;



--minimal error test
if gl_no_error /= glGetError then
	put_line(" GLerror in gameutils.InitSDL");
end if;



end InitSDL;













package myfloat_io is new text_io.float_io(float);

package mygint_io is new text_io.integer_io(glint);


--we skip blank lines and comments beginning with "#":
function is_blank2( line : string; len:integer ) return boolean is
	ch: character;
begin

	if( len < 1 ) then return true; end if;

	ch:=line( line'first );

	if ch='#' then return true;
	elsif ch = ' ' then	return true;

	--4jul18 added safeguard to handle DOS-format files:
	elsif ada.characters.handling.is_line_terminator(ch) then return true;

	end if;

	return false;

end is_blank2;






procedure GetInt( Rcd:string;
						Bgn:in out natural;
						Int: in out glint ) is
begin
mygint_io.get( From => Rcd(Bgn..Rcd'last),
					Item => Int,
					Last => Bgn);
Bgn:=Bgn+1;
end GetInt;



procedure getNbInt(tfile:file_type; rcd: in out string; k: in out glint) is
	len,bgn: natural:=1;
begin
	while not end_of_file(tfile) loop
		get_line(tfile, rcd, len);
		if not is_blank2(rcd,len) then exit; end if;
	end loop;
	bgn:=rcd'first;
	GetInt(rcd,bgn,k);
end getNbInt;


procedure GetFlt( Rcd:string;
					  Bgn:in out natural;
					  Flt: in out float ) is
nd: positive;
begin
myfloat_io.get( From => Rcd(Bgn..Rcd'last),
					 Item => Flt,
					 Last => nd);
Bgn := nd+1;
end GetFlt;


procedure getNbFlt(tfile:file_type; rcd: in out string; t: in out float) is
	len,bgn: natural:=1;
begin
	while not end_of_file(tfile) loop
		get_line(tfile, rcd, len);
		if not is_blank2(rcd,len) then exit; end if;
	end loop;
	bgn:=rcd'first;
	GetFlt(rcd,bgn,t);
end getNbFlt;










procedure first_prep(HiRes: boolean:=false) is -- main program setup
	rcd : string(1..80);
begin

	oldstateexists:=false;
	if ada.directories.Exists(statefile) then
		oldstateexists:=true;
	end if;

	--First, Initialize all Sounds:

	snd4ada_hpp.initSnds;

------- addendum 15dec17 begin ---------------------------------------

	evilBugs := snd4ada_hpp.initLoop( --16nov19
		--Interfaces.C.Strings.New_String("data/evilBugsLoop.ogg"),70);
		--Interfaces.C.Strings.New_String("data/evilCrunchingCockroaches.ogg"),50);
		--2nd: nice alternative
		--3rd: combination:
		Interfaces.C.Strings.New_String("data/evilRoaches.ogg"),90);


	wind1 := snd4ada_hpp.initLoop( --1dec18
		Interfaces.C.Strings.New_String("data/wind.ogg"),20);


	ceph8 := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/ceph.ogg"),50);

	dama8 := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/Dama-May.ogg"),50);


	tmpl4 := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/westfold.ogg"),60);

------- addendum 15dec17 end ---------------------------------------


	water := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/lake-water.ogg"),50);

	misr := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/misrlu.ogg"),90);

	turk := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/turkish.ogg"),90);

	hiss := snd4ada_hpp.initLoop(
		Interfaces.C.Strings.New_String("data/hiss-beat.wav"),99);

------- now for transient sounds ==================================

	fanfare := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/fanfare.wav"),50);

	stone := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/concrete.ogg"),99);

	down := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/putdown.wav"),50);

	up := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/pickup.wav"),50);

	die := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/dragondie.wav"),99);

	eat := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/eaten.wav"),99);

	roar := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/roar.wav"),80);

	won := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/won.wav"),80);

	medusascream := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/medusa.wav"),99);

	girlyscream := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/girly_scream.wav"),99);

	monsterscream := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/monster.wav"),99);

	womanscream := snd4ada_hpp.initSnd(
		Interfaces.C.Strings.New_String("data/woman_scream.wav"),99);


	if 
		dama8<0 or ceph8<0 or tmpl4<0 or
		water<0 or misr<0 or turk<0 or hiss<0 or
		fanfare<0 or stone<0 or down<0 or up<0 or
		die<0 or eat<0 or roar<0 or won<0 or 
		medusascream<0 or girlyscream<0 or 
		monsterscream<0 or womanscream<0
	then
		put_line("snd4ada_hpp.initSnds ERROR");
		raise program_error;
	end if;



------- begin SDL prep ---------------------------------------------------------


	InitSDL("AdaVenture",HiRes);



	if ada.directories.Exists(cfgfile) then 
	-- these take precedence over defaults

		put_line("game-controller settings file found");
		text_io.open(tfile, in_file, cfgfile);

		getNbInt(tfile,rcd,gshtl); 
		getNbInt(tfile,rcd,gshtr); 
		getNbInt(tfile,rcd,gjmp); 
		getNbFlt(tfile,rcd,Lsens); 
		getNbFlt(tfile,rcd,Rsens); 

------- end gamepad;  begin joystik --------------------

		getNbInt(tfile,rcd,jbak); 
		getNbInt(tfile,rcd,jfor); 
		getNbInt(tfile,rcd,jshtl); 
		getNbInt(tfile,rcd,jshtr); 
		getNbInt(tfile,rcd,jjmp); 
		getNbFlt(tfile,rcd,Jsens); 

		text_io.close(tfile);

	else

		put(cfgfile & " file not found...");
		put_line("Using default game controller settings");
		gshtl:=4; --shoot left
		gshtr:=5; --shoot right
		gjmp :=1; --jump

		jbak :=0; --moveback
		jfor :=1; --forward
		jshtl:=2; --shoot left
		jshtr:=3; --shoot right
		jjmp :=7; --jump

	end if;


	if joystik then --we actually use only Lsens or Rsens
		Lsens:=Jsens;
		Rsens:=Jsens; -- Jsens is not used
	end if;








	emptyGLerrorQueue; --avoid misleading messages in utex

	utex.inittext2d(
		"data/sansw.png", integer(winwidth),integer(winheight));
	put_line( "Window: wid-X-hit :" 
		& interfaces.c.int'image(winwidth)&" X "
		& interfaces.c.int'image(winheight) );

	cursor := SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
	SDL_SetCursor(cursor);
	error := SDL_SetRelativeMouseMode(SDL_TRUE);
	myassert( error = 0, 1016 );

	SDL_GL_GetDrawableSize( mainWindow, Fwid'access, Fhit'access );
	glViewport(0,0,Fwid,Fhit);

	put_line( "Drawable: Fwid-X-Fhit : "
		&interfaces.c.int'image(Fwid)&" X "
		& interfaces.c.int'image(Fhit) );

	key_map := sdl_getkeyboardstate(numkeys'access);
	--put_line("...numkeys=" & interfaces.c.int'image(numkeys) ); -- 512
	--myassert( keyrange'last <= numkeys, 1017 );




	glgenvertexarrays(1, vertexarrayid'address );
	glbindvertexarray(vertexarrayid);

	-- from the literature it seems I might not have to
	-- call this explicitly because the first texture
	-- unit is the active texture unit, by default.
	-- And I have no multi-texturing needs yet,
	-- like a tarnish on top of an existing texture.
	glactivetexture(gl_texture0); -- moved here 5nov14 (outside main loop)

	glgenbuffers(1, vertbuff'address);
	glgenbuffers(1, normbuff'address);
	glgenbuffers(1, rgbbuff'address);
	glgenbuffers(1, uvbuff'address);
	glgenbuffers(1, elembuff'address);




	glenable(gl_depth_test);
	gldepthfunc( gl_lequal );
	glenable( gl_cull_face );



	-- reduces aliasing:
	glEnable(GL_MULTISAMPLE); -- default setting anyway


	--minimal error test
	if gl_no_error /= glGetError then
		put_line(" GLerror in gameutils.first_prep");
	end if;


	level:=0;


end first_prep;









--calculate the radian measure of the solid angle between two vectors
function angl( x1,y1,z1, x2,y2,z2 : float ) return float is
	l1 : constant float := x1*x1+y1*y1+z1*z1;
	l2 : constant float := x2*x2+y2*y2+z2*z2;
	len1, len2 : float;
	dot12, cosang : float;
begin
	if l1<0.0001 then len1:=0.01;
	else len1:=safeSqrt(l1); end if;

	if l2<0.0001 then len2:=0.01;
	else len2:=safeSqrt(l2); end if;

	dot12:=x1*x2+y1*y2+z1*z2;
	cosang := dot12/len1/len2;

	-- safeguard added 8jan18:
	if cosang>1.0 then cosang:=1.0;
	elsif cosang<-1.0 then cosang:=-1.0; end if;

	return fmath.arccos(cosang);
end angl;







--circular angle is reset to lie between -pi..+pi
function mindifangl( angle: float ) return float is
	angl: float := angle;
begin

	while angl > +onepi loop
		angl:=angl-twopi;
	end loop;

	while angl < -onepi loop
		angl:=angl+twopi;
	end loop;

	return angl;

end mindifangl;


-- choose camera angle closest to avatar-look-dir:
function branchnear( angAva, angCam : float ) return float is
begin 
	return angAva+mindifangl(angCam-angAva);
end branchnear;


--gradually slew choriang [camera] toward avatar's look-direction:
procedure slewToAvLook is -- use horiang to set cam-look, choriang
	ahoriang : float; -- look angle towards avatar
	ghoriang : float; -- ideal goal camera angle
	atan,dang: float;
begin

	if abs(xme-xcam)+abs(zme-zcam) < 0.001 then
		ahoriang:=horiang;
	else
		atan := fmath.arctan(xme-xcam,zme-zcam);
		ahoriang := branchnear(horiang,atan); --new
	end if;

	dang := mindifangl(horiang-ahoriang);
	ghoriang := ahoriang + 0.15*dang;
	-- reset camera goal to turn slightly [25%] toward horiang
	-- where horiang = avatar's walking direction

	dang := mindifangl(ghoriang-choriang);
	choriang := choriang + 0.02*dang;
	-- move 5% towards camera goal

	cxlook := fmath.cos(vertang)*fmath.sin(choriang);
	cylook := fmath.sin(vertang);
	czlook := fmath.cos(vertang)*fmath.cos(choriang);

exception -- added 8jan18

	when ada.numerics.argument_error =>

		new_line;
		put("slewToAvLook:  xme="&float'image(xme));
		put("slewToAvLook:  zme="&float'image(zme));
		new_line;

		put("slewToAvLook:  xcam="&float'image(xcam));
		put("slewToAvLook:  zcam="&float'image(zcam));
		new_line;

		put("slewToAvLook:  xme-xcam="&float'image(xme-xcam));
		put("slewToAvLook:  zme-zcam="&float'image(zme-zcam));
		new_line;

		raise;

end slewToAvLook;




--gradually slew choriang [camera] to look toward avatar
procedure slewToAv is -- uses me-look=horiang to set cam-look=choriang
	ahoriang : float; -- look angle towards avatar
	dang: float;
begin

	if abs(xme-xcam)+abs(zme-zcam) < 0.001 then
		ahoriang:=horiang;
	else
		ahoriang := branchnear(horiang,fmath.arctan(xme-xcam,zme-zcam));
	end if;

	dang := mindifangl(ahoriang-choriang);
	choriang := choriang + 0.02*dang; --move 2% toward goal

	cxlook := fmath.cos(vertang)*fmath.sin(choriang);
	cylook := fmath.sin(vertang);
	czlook := fmath.cos(vertang)*fmath.cos(choriang);


exception -- added 8jan18

	when ada.numerics.argument_error =>

		new_line;
		put("s2av:  xme="&float'image(xme));
		put("s2av:  zme="&float'image(zme));
		new_line;

		put("s2av:  xcam="&float'image(xcam));
		put("s2av:  zcam="&float'image(zcam));
		new_line;

		put("s2av:  xme-xcam="&float'image(xme-xcam));
		put("s2av:  zme-zcam="&float'image(zme-zcam));
		new_line;

		raise;

end slewToAv; --not used, but might want to sometime.





procedure updateCamera( init: boolean := false )  is
	ixmx, kxl,kxh,kyl,kyh,kzl,kzh, tt: float;
	ixgoal,iygoal,izgoal,xc,yc,zc,ff: float;

	-- camera  buffer  distance:  bigger than the
	-- offset of wall textures from room bounds,
	-- yet smaller than margin:
	buf: constant float := 0.05; 

	sfrac: constant float := 0.005; --Slowest slew
	mfrac: constant float := 0.01; --medium
	hfrac: constant float := 0.03; --high
	ffrac: constant float := 0.15; --Fastest slew
	-- % towards goal each update (5-10-15 seems ok)


	--note:  we must prevent KO in between *cam, *me
	okcam: boolean := true;
	nc : constant integer := 5;
	c: integer;
	-- # cuts of segment between "me" and "camera"

	hoffsetu, voffsetu: float; -- h=0.8, v=0.1

	amazed: constant boolean := (scene>=5 and scene<=9);

	zooming: boolean;

begin


	zooming:=false;
	if camdist/=ocamdist then 
		zooming:=true; 
		ocamdist:=camdist;
	end if;



	-- 1st, check camera versus scene bounds:

	-- set interior X-bounds
	if scene=4 then
		ixmx:=ixmax/3.0;
	else
		ixmx:=ixmax;
	end if;


	--adjust per zoom setting
	voffsetu:=camdist*voffset;
	hoffsetu:=camdist*hoffset;
	if amazed then voffsetu:=camdist*voffset*4.0; end if;


	-- initialize ideal camera position:
	tt:=1.0;
	ixcam:=xme - tt*hoffsetu*xlook;
	izcam:=zme - tt*hoffsetu*zlook;
	iycam:=yme + tt*voffsetu;


	--if interior then adjust ideal until within room bounds:
	if scene=2 then -- (x,z) in [-10..0, -10..0]

		loop
			ixcam:=xme - tt*hoffsetu*xlook;
			izcam:=zme - tt*hoffsetu*zlook;
			iycam:=yme + tt*voffsetu;
			exit when 
				(iycam<iymax-buf) and 
				(abs(ixcam-x2c)<x2r-buf) and 
				(abs(izcam-z2c)<z2r-buf);
			tt:=tt*0.9;
		end loop;

	elsif interior then -- inside some maze/lab

		loop
			ixcam:=xme - tt*hoffsetu*xlook;
			izcam:=zme - tt*hoffsetu*zlook;
			iycam:=yme + tt*voffsetu;
			exit when 
				(iycam<iymax-buf) and 
				(abs(ixcam)<ixmx-buf) and 
				(abs(izcam)<izmax-buf);
			tt:=tt*0.9;
			exit when tt<0.01; 
			--this happens when going thru maze and we
			--transition between 5 & 6.
		end loop;

	end if;

	ixgoal:=ixcam;
	iygoal:=iycam;
	izgoal:=izcam;

	-- adjust ideal camera position versus ko zones:
	c:=0;
	while okcam loop

		ff:=float(c)/float(nc); --move from avatar towards ideal
		xc:= xme*(1.0-ff) + ixgoal*ff;
		yc:= yme*(1.0-ff) + iygoal*ff;
		zc:= zme*(1.0-ff) + izgoal*ff;

		okcam:=true;
		for i in 1..nko loop -- check all KOs that apply
		if scene=koscene(i) and i/=kgate then --this KO applies here
			kxl:=xc-(koxlo(i)-buf);
			kxh:=(koxhi(i)+buf)-xc;
			kyl:=yc-(koylo(i)-buf);
			kyh:=(koyhi(i)+buf)-yc;
			kzl:=zc-(kozlo(i)-buf);
			kzh:=(kozhi(i)+buf)-zc;
			if (kxl*kxh>0.0) and (kyl*kyh>0.0) and (kzl*kzh>0.0) then 
				okcam:=false;
			end if; --intrusion into ko
		end if;
		end loop; --for i

		if okcam then -- this standoff is valid
			ixcam:=xc; iycam:=yc; izcam:=zc;
		end if;

		c:=c+1;
		exit when c>nc;

	end loop; --while not okcam




	if init or not thirdPerson then
		xcam:=ixcam; ycam:=iycam; zcam:=izcam;
		-- need these initialized in case user 
		-- switches to 3rd person before moving,
		-- but also when entering new room...
	end if;

	cylook := fmath.sin(vertang);
	cxlook := fmath.cos(vertang)*fmath.sin(choriang);
	czlook := fmath.cos(vertang)*fmath.cos(choriang);



if lazyCam then

	--if direction=0 then
	if direction=0 and not zooming then
		slewToAv; --per AG

	elsif direction<0 then --moving backward

		if scene=2 or scene=4 then --temple or castle...loose camera
			-- sfrac=0.005
			xcam := (1.0-sfrac)*xcam + sfrac*ixcam;
			zcam := (1.0-sfrac)*zcam + sfrac*izcam;
			ycam := (1.0-sfrac)*ycam + sfrac*iycam; 
			slewToAv;

		elsif interior then --mazes...tightly follow thru maze

			-- sfrac=0.005 Ok now with hiview
			xcam := (1.0-sfrac)*xcam + sfrac*ixcam;
			zcam := (1.0-sfrac)*zcam + sfrac*izcam;
			ycam := (1.0-sfrac)*ycam + sfrac*iycam; 

			slewToAv;

		else --exterior...fairly loose
			-- mfrac=0.01
			xcam := (1.0-mfrac)*xcam + mfrac*ixcam;
			zcam := (1.0-mfrac)*zcam + mfrac*izcam;
			ycam := (1.0-mfrac)*ycam + mfrac*iycam; 
			slewToAv;

		end if;

	--elsif direction>0 then 
	elsif direction>0 or zooming then 
	--fairly tight camera, particularly in mazes

		-- was using 0.08 but
		-- hfrac=0.03 good, looser Ok with hiview
		xcam := (1.0-hfrac)*xcam + hfrac*ixcam;
		zcam := (1.0-hfrac)*zcam + hfrac*izcam;
		ycam := (1.0-hfrac)*ycam + hfrac*iycam; 
		slewToAvLook;
		--slewToAv; --27jan18

	end if;

else -- not lazyCam

	--if direction=0 then --not moving
	if direction=0 and not zooming then --neither moving nor zooming
		slewToAv; --per AG
	else --moving or zooming
		-- previous, good, method, forw+back:
		-- ffrac=0.15
		xcam := (1.0-ffrac)*xcam + ffrac*ixcam;
		zcam := (1.0-ffrac)*zcam + ffrac*izcam;
		ycam := (1.0-ffrac)*ycam + ffrac*iycam; 
		slewToAvLook;
	end if;

end if; -- not lazyCam




end updateCamera;








-- this assumes mm=ID, (xme,yme,zme)=virtual pos within skybox
-- [ actual pos versus skybox is always (0,0,0) ]
procedure updateMVPs( et, wid,hit : float; upd8: boolean := false ) is
	xlk,ylk,zlk, xrt,yrt,zrt,
	xpos,ypos,zpos, xup,yup,zup : float;
	degtilt: constant float := -60.0; -- -45.0;
	pang, padeg, px,py,pz: float;
begin

	if thirdPerson then
		xpos:=xcam; ypos:=ycam; zpos:=zcam;
	else -- firstPerson
		xpos:=xme; ypos:=yme; zpos:=zme;
		choriang:=horiang;
		cxlook := fmath.cos(vertang)*fmath.sin(choriang);
		cylook := fmath.sin(vertang);
		czlook := fmath.cos(vertang)*fmath.cos(choriang);
	end if;

	-- Look Vector
	xlk:=xpos+cxlook;
	ylk:=ypos+cylook;
	zlk:=zpos+czlook;

	-- Right unit-Direction
	xrt:= fmath.sin(choriang-halfpi);
	yrt:= 0.0;
	zrt:= fmath.cos(choriang-halfpi);

	-- calculate UP unit-Direction
	cross( xrt,yrt,zrt, cxlook,cylook,czlook, xup,yup,zup );

	perspective(pm, 45.0, wid/hit,  0.1, 100.0);

	-- note:  in this app we have mm=id 
	--        so modelview = mv = mm*vm = vm = viewmatrix

	lookat(mv, 0.0,0.0,0.0, cxlook,cylook,czlook, xup,yup,zup ); 
	--ViewMat (pos within skybox)

	lookat(imv, xpos,ypos,zpos, xlk,ylk,zlk, xup,yup,zup ); 
	--ViewMat (pos within landscape)

	mmvp:=mv;
	imvp:=imv;
	matXmat(mmvp,pm); -- used for skybox only
	matXmat(imvp,pm); -- used everywhere else


	--myInvTransp(mm,nm3);
	-- For a given modelmatrix (MM: mat44), 
	-- we can get a normalMatrix (NM: mat33) by:
	-- myInvTransp(MM,NM)
	-- However, in this app, MM=ID => NM=ID


	if upd8 then
	-- begin update Jupiter:

		-- position
		pang:=et*twopi*0.025;
		px:=1.0*fmath.sin(pang);
		pz:=1.0*fmath.cos(pang);
		py:=20.0;

		-- spinAngle
		--padeg := -et*twopi*2.5;
		padeg := -et*twopi*rad2deg*0.1; -- 10sec/rev
	----------------------------------------------------
		jupit.setpos(px,py,pz);

		satmm:=identity;
		translate(satmm, -px,-py,-pz); --first, move to origin

	-- begin rotations

		--spin on polar axis:
		degRotate(satmm, padeg, 0.0,1.0,0.0); -- Y=polar-axis

		--axis-tilt:
		degRotate(satmm, degtilt, 1.0, 0.0, 0.0);

	-- end rotations

		translate(satmm, px,py,pz); --now, move back

		satmv:=satmm;
		matXmat(satmv,mv);
		satmvp:=satmv;
		matXmat(satmvp,pm);
	---------------------------------------------

	end if; -- if upd8


end updateMVPs;












procedure updategamestate is
	gateang,
	cupang, swordang, wkeyang,bkeyang,gkeyang: float := 1.0;
	minonear: boolean;

	wang,dxz,dy,dx,dz,d2gate,
	xluk,yluk,zluk, xmi,ymi,zmi: float;

	-- (xmin9..xmax9, zmin9..zmax9) = secret chalice room
	x9ok : constant boolean := (xmin9<xme) and (xme<xmax9);
	z9ok : constant boolean := (zmin9<zme) and (zme<zmax9);
begin

	if scene=9 and x9ok and z9ok and not play9 then
		snd4ada_hpp.playLoop(tmpl4);
		play9:=true;
	end if;

	if thirdPerson then
		xluk:=cxlook;
		yluk:=cylook;
		zluk:=czlook;
		xmi:=xcam;
		ymi:=ycam;
		zmi:=zcam;
	else
		xluk:=xlook;
		yluk:=ylook;
		zluk:=zlook;
		xmi:=xme;
		ymi:=yme;
		zmi:=zme;
	end if;

	if scene=8 then
		minonear:=(abs(xme)<5.0) and (abs(zme+1.0)<4.0);
		if minonear and not minosent then
			minorun:=true;
			dragonstart:=float(sdl_getticks)/1000.0;
			minosent:=true;
--put_line("minorun:=true");
		end if;

	elsif scene=1 then

		gatenear:=(abs(xme-xgzm)<neargate*1.5) and (abs(zme-zgzm)<neargate*1.5);

		if wkeyheld and gatenear and not opengate then liftgate(gzmk); end if;

		opengate := opengate or (wkeyheld and gatenear);

------- now deal with opening maze

		mazenear :=
			(abs(xme-xmaze)<neargate*1.8) and (abs(zme-zmaze)<neargate*1.8);
		if gkeyheld and mazenear and not openmaze then liftmaze; end if;
		openmaze := openmaze or (gkeyheld and mazenear);



	elsif scene=6 then

		lionnear :=
			(abs(xme-xlion)<neargate*1.8) and (abs(zme-zlion)<neargate*1.8);

		if bkeyheld and lionnear and not openlion then liftlion; end if;

		openlion := openlion or (bkeyheld and lionnear);


	elsif scene=7 then

		labnear :=
			(
				(abs(xme-xlab)<neargate*1.8)  --"H", sh7 (xlab~10)
					--or (abs(xme+xlab)<neargate*1.8) "G", sg7 (defunct)
			)
			
			and (abs(zme-zlab)<neargate*1.8); -- zlab~7

		if bkeyheld and labnear and not openlab then slidelab; end if;

		openlab := openlab or (bkeyheld and labnear);


	end if;





	if not chaliceheld then
		cupang := angl(xluk,yluk,zluk, 
			float(xchalice)-xmi,
			float(ychalice)-ymi,
			float(zchalice)-zmi);
	end if;

	if not wkeyheld then
		wkeyang := angl(xluk,yluk,zluk, xwkey-xmi,  ywkey-ymi, zwkey-zmi);
	end if;

	if not bkeyheld then
		bkeyang := angl(xluk,yluk,zluk, xbkey-xmi,  ybkey-ymi, zbkey-zmi);
	end if;

	if not gkeyheld then
		gkeyang := angl(xluk,yluk,zluk, xgkey-xmi,  ygkey-ymi, zgkey-zmi);
	end if;

	if not swordheld then
		swordang :=angl(xluk,yluk,zluk, xsword-xmi,ysword-ymi,zsword-zmi);
	end if;


	if not gateheld then
		gateang :=angl(xluk,yluk,zluk, xgate-xmi,ygate-ymi,zgate-zmi);
		dx := xgate-xme;
		dz := zgate-zme;
		d2gate := safeSqrt(dx*dx+dz*dz);
	end if;



	wkeyseen := ( -- used in bat test
		not wkeyheld
		and (abs(xme-xwkey)<nearkey*2.0)
		and (abs(zme-zwkey)<nearkey*2.0) 
		and (wkeyang<thirdpi) );

	bkeyseen := ( -- used in bat test
		not bkeyheld
		and (abs(xme-xbkey)<nearkey*2.0)
		and (abs(zme-zbkey)<nearkey*2.0) 
		and (bkeyang<thirdpi) );


	gkeynear := (
		not gkeyheld
		and (sgkey=scene)
		and (abs(xme-xgkey)<nearkey)
		and (abs(zme-zgkey)<nearkey) 
		and (gkeyang<thirdpi) );

	bkeynear := (
		not bkeyheld
		and (sbkey=scene)
		and (not bathasbkey)
		and (abs(xme-xbkey)<nearkey)
		and (abs(zme-zbkey)<nearkey) 
		and (bkeyang<thirdpi) );

	wkeynear := (
		not wkeyheld
		and (swkey=scene)
		and (not bathaswkey)
		and (abs(xme-xwkey)<nearkey)
		and (abs(zme-zwkey)<nearkey) 
		and (wkeyang<thirdpi) );

	swordnear := (
		not swordheld
		and (ssword=scene)
		and (abs(xme-xsword)<nearsword)
		and (abs(zme-zsword)<nearsword) 
		and (swordang<thirdpi) );



	chalicenear := (
		not chaliceheld
		and (schalice=scene)
		and (not bathaschalice)
		and (abs(xme-float(xchalice))<nearchalice)
		and (abs(zme-float(zchalice))<nearchalice) 
		and (cupang<thirdpi) );

	pedestalnear := -- pedestal is @ (x,z)=(0,0)
		(   (abs(xme-float(xped))<nearpedestal) 
		and (abs(zme-float(zped))<nearpedestal) 
		and (scene=2)
		and (abs(yluk)<0.5) ); -- looking near horizontal


	pgatenear := ( -- Portable Bridge/Gate
		not gateheld
		and (sgate=scene)
		and (d2gate<nearpgate)
		and ( (d2gate>toonearpgate) or (kgate=0) )
		and (gateang<thirdpi/2.0) );


	if gateheld then

		insertable:=0;
		for i in 1..nko loop
		if scene=koscene(i) then --this KO applies here

	-- this strategy for placing gateway thru wall requires 
	-- being close enough AND looking toward wall:
			if mazewall(i) then

				dx:=0.5*(koxlo(i)+koxhi(i))-xme;
				dy:=0.5*(koylo(i)+koyhi(i))-yme;
				dz:=0.5*(kozlo(i)+kozhi(i))-zme;
				dxz := safeSqrt( dx*dx+dz*dz );

				wang :=angl(xluk,yluk,zluk, dx,dy,dz);

				if 
					(wang<thirdpi/2.0)
					and
					(dxz<mazeThreshold)
				then
					insertable:=i;
				end if;

			end if;

		end if;
		end loop;

	end if; --gateheld


end updategamestate;




procedure liftgate( n: integer ) is
  -- n is to be removed from sequential list
  -- so we simply make it non-effectual
  -- then redefine gate, KO
begin
	myassert( n <= nko, 987 );
	myassert( (n=gxpk) or (n=gxmk) or (n=gzpk) or (n=gzmk), 986 );


	lifttime := float(sdl_getticks)/1000.0;

	gatewait:=true;
	snd4ada_hpp.playSnd(stone); --concrete

	if n=gxpk then
		xpup:=true;
	elsif n=gxmk then
		xmup:=true;
	elsif n=gzpk then
		zpup:=true;
	elsif n=gzmk then
		zmup:=true;
	end if;

end liftgate;







procedure slidelab is
begin

	labtime := float(sdl_getticks)/1000.0;

	labwait:=true;
	snd4ada_hpp.playSnd(stone); --concrete

	labopening:=true;

end slidelab;





procedure liftlion is
begin

	liontime := float(sdl_getticks)/1000.0;

	lionwait:=true;
	snd4ada_hpp.playSnd(stone); --concrete

	liongoingup:=true;

end liftlion;






procedure liftmaze is
begin

	mazetime := float(sdl_getticks)/1000.0;

	mazewait:=true;
	snd4ada_hpp.playSnd(stone); --concrete

	mazegoingup:=true;

end liftmaze;














--NOTICE:  typically, dt<<0.1 second  (between iterations of main loop)
--         but when it is that big, it's probably because foldtime is stale
procedure moveforward( currenttime: float ) is
	dt : float := currenttime-foldtime;
	lagfac : constant float := 1.0;

	yyme, yhalf,
	kxl,kxh,kyl,kyh,kzl,kzh,
	okxl,okxh, okzl, okzh: float;
	ixmx: float;
begin


if scene=4 then
	ixmx:=ixmax/3.0;
else
	ixmx:=ixmax;
end if;

if 
	not gatewait
	and not labwait
	and not lionwait
	and not mazewait
	--and not batwait
then

	foldtime:=currenttime;
	oxme:=xme;
	oyme:=yme;
	ozme:=zme;

	xme:=xme+dt*speed*xlook;
	zme:=zme+dt*speed*zlook;
	direction:=1;

	-- Velocity Direction
	veldir := fmath.arctan(xlook,zlook);

	-- set yme appropriately:
	if scene=2 then
		yme := aheight;
	elsif not interior then
		yme := aheight + land_alt(xme,zme);
	else
		yme := -iymax+aheight;
	end if;




if scene=2 then -- (x,z) in [-10..0, -10..0]

	if (xme>-margin) then xme:=-margin; end if;
	if (xme<-10.0+margin) then xme:=-10.0+margin; end if;
	if (zme>-margin) then zme:=-margin; end if;
	if (zme<-10.0+margin) then zme:=-10.0+margin; end if;

elsif interior then

	-- limit pos to be within walls:
	if (xme>+ixmx-margin) then xme:=+ixmx-margin; end if;
	if (xme<-ixmx+margin) then xme:=-ixmx+margin; end if;
	if (zme>+izmax-margin) then zme:=+izmax-margin; end if;
	if (zme<-izmax+margin) then zme:=-izmax+margin; end if;

else --exterior scene

	-- limit pos to be within user bounds:
	if (xme>+xmaxu-margin) then xme:=+xmaxu-margin; end if;
	if (xme<-xmaxu+margin) then xme:=-xmaxu+margin; end if;
	if (zme>+zmaxu-margin) then zme:=+zmaxu-margin; end if;
	if (zme<-zmaxu+margin) then zme:=-zmaxu+margin; end if;

end if;


	-- set yhalf appropriately:
	if scene=2 then
		yyme:=aheight;
		yhalf:=yyme-aheight/2.0;
	elsif scene=1 then
		yyme:=aheight;
		yhalf:=yyme-aheight/2.0;
	else
		yyme:=-iymax+aheight;
		yhalf:=yyme-aheight/2.0;
	end if;





	-- further, limit pos to avoid ko zones:
	for i in 1..nko loop
	if scene=koscene(i) and i/=kgate then --this KO applies here

		kxl:=xme-koxlo(i)+margin;
		kxh:=koxhi(i)+margin-xme;

		kyl:=yhalf-koylo(i);
		kyh:=koyhi(i)-yhalf;

		kzl:=zme-kozlo(i)+margin;
		kzh:=kozhi(i)+margin-zme;


		if (kxl*kxh>0.0) and (kyl*kyh>0.0) and (kzl*kzh>0.0) then 
		--intrusion into ko

			okxl:=oxme-koxlo(i)+margin;
			okxh:=koxhi(i)+margin-oxme;
			okzl:=ozme-kozlo(i)+margin;
			okzh:=kozhi(i)+margin-ozme;

			if      ( (okxl*okxh>0.0) and (okzl*okzh<=0.0) ) then
				zme:=ozme;
			elsif ( (okzl*okzh>0.0) and (okxl*okxh<=0.0) ) then
				xme:=oxme;
			end if;

		end if; --intrusion into ko

	end if;
	end loop; --for i

	updategamestate;

end if;

end moveforward;




-- not yet able to back thru a stargate
procedure movebackward( currenttime: float ) is
	dt : float := currenttime-boldtime;
	yyme, yhalf, kxl,kxh,kyl,kyh,kzl,kzh,
	ixmx, okxl,okxh, okzl, okzh: float;
begin

if scene=4 then
	ixmx:=ixmax/3.0;
else
	ixmx:=ixmax;
end if;

if 
	not gatewait
	and not labwait
	and not lionwait
	and not mazewait
	--and not batwait
then


	boldtime:=currenttime;


	oxme:=xme;
	oyme:=yme;
	ozme:=zme;


	xme:=xme-dt*speed*xlook;
	zme:=zme-dt*speed*zlook;
	direction:=-1;

	-- Velocity Direction
	veldir := fmath.arctan(-xlook,-zlook);

	-- set yme appropriately:
	if scene=2 then
		yme := aheight;
	elsif not interior then
		yme := aheight + land_alt(xme,zme);
	else
		yme := -iymax+aheight;
	end if;




if scene=2 then -- (x,z) in [-10..0, -10..0]

	if (xme>-margin) then xme:=-margin; end if;
	if (xme<-10.0+margin) then xme:=-10.0+margin; end if;
	if (zme>-margin) then zme:=-margin; end if;
	if (zme<-10.0+margin) then zme:=-10.0+margin; end if;

elsif interior then

	-- limit pos to be within walls:
	if (xme>+ixmx-margin) then xme:=+ixmx-margin; end if;
	if (xme<-ixmx+margin) then xme:=-ixmx+margin; end if;
	if (zme>+izmax-margin) then zme:=+izmax-margin; end if;
	if (zme<-izmax+margin) then zme:=-izmax+margin; end if;

else --exterior scene

	-- limit pos to be within user bounds:
	if (xme>+xmaxu-margin) then xme:=+xmaxu-margin; end if;
	if (xme<-xmaxu+margin) then xme:=-xmaxu+margin; end if;
	if (zme>+zmaxu-margin) then zme:=+zmaxu-margin; end if;
	if (zme<-zmaxu+margin) then zme:=-zmaxu+margin; end if;

end if;


	-- set yhalf appropriately:
	if scene=2 then
		yyme:=aheight;
		yhalf:=yyme-aheight/2.0;
	elsif scene=1 then
		yyme:=aheight;
		yhalf:=yyme-aheight/2.0;
	else
		yyme:=-iymax+aheight;
		yhalf:=yyme-aheight/2.0;
	end if;



	-- further, limit pos to avoid ko zones:
	for i in 1..nko loop
	if scene=koscene(i) and i/=kgate then -- this KO applies here


		kxl:=xme-koxlo(i)+margin;
		kxh:=koxhi(i)+margin-xme;

		kyl:=yhalf-koylo(i);
		kyh:=koyhi(i)-yhalf;

		kzl:=zme-kozlo(i)+margin;
		kzh:=kozhi(i)+margin-zme;


		if (kxl*kxh>0.0) and (kyl*kyh>0.0) and (kzl*kzh>0.0) then 
		--intrusion into ko

			okxl:=oxme-koxlo(i)+margin;
			okxh:=koxhi(i)+margin-oxme;
			okzl:=ozme-kozlo(i)+margin;
			okzh:=kozhi(i)+margin-ozme;

			if      ( (okxl*okxh>=0.0) and (okzl*okzh<0.0) ) then
				zme:=ozme;
			elsif ( (okzl*okzh>=0.0) and (okxl*okxh<0.0) ) then
				xme:=oxme;
			end if;

		end if; -- KO intrusion
	end if;
	end loop; --for i

	updategamestate;

end if;

end movebackward;

















procedure handle_gc_look( gcx,gcy:sint16 ) is
-- to update look direction using left game controller stick
	ux : float := float(gcx)/float(32768);
	uy : float := float(gcy)/float(32768);
begin


	if abs(ux)<0.15 then 
		ux:=0.0;
	else
		ux:=ux-0.15*signum(ux);
	end if;

	if abs(uy)<0.15 then 
		uy:=0.0; 
	else
		uy:=uy-0.15*signum(uy);
	end if;


	horiAng := horiAng - 0.04 * ux * Lsens;
	vertAng := vertAng + 0.02 * uy * Lsens;
	--slewToAvLook;
	slewToAv; --27jan18

	xlook := fmath.cos(vertAng)*fmath.sin(horiAng);
	zlook := fmath.cos(vertAng)*fmath.cos(horiAng);
	ylook := fmath.sin(vertAng);


	updategamestate;

end handle_gc_look;






procedure handle_gc_move( nowtime: float; gcx,gcy:sint16 ) is
-- to update move direction using right game controller stick
	ux : float := Rsens*float(gcx)/float(32768);
	uy : float := Rsens*float(gcy)/float(32768);
begin

	if    uy < -0.05 then
		moveforward(nowTime);

	elsif uy > +0.05 then
		movebackward(nowTime);

	end if;

	handle_gc_look(gcx,0); -- turns left/right

end handle_gc_move;











































oldMdTime : float := 0.0;

procedure handle_mouse_move( nowTime : float ) is

-- to update look direction
-- also handles touch pad...

	mousedx, mousedy : aliased interfaces.c.int;
	mouseBtnState : Uint32;
	dt : float := nowTime-oldMdTime;
begin

	mouseBtnState := SDL_GetRelativeMouseState(mousedx'access, mousedy'access);

	oldMdTime:=nowTime;

	if( dt<0.1 ) then
		horiAng := horiAng - 0.001 * float(mousedx);
		vertAng := vertAng - 0.001 * float(mousedy);
		--slewToAvLook;
		slewToAv; --27jan18
	end if;

	xlook := fmath.cos(vertAng)*fmath.sin(horiAng);
	ylook := fmath.sin(vertAng);
	zlook := fmath.cos(vertAng)*fmath.cos(horiAng);


	updategamestate;

end handle_mouse_move;














------------------ end game specific code -----------------------------


function bitmatch( x, y : integer ) return boolean is
	result : boolean := false;
	a : integer := x;
	b : integer := y;
begin
	for i in 1..32 loop
		if ( odd(a) and odd(b) ) then result:=true; end if;
		a:=a/2;
		b:=b/2;
	end loop;
	return result;
end;



procedure output( a : mat44 ) is
begin
	for row in 1..4 loop
	for col in 1..4 loop
		put( float'image( a(row,col) ) &" ");
	end loop;
	new_line;
	end loop;
	new_line;
end;



------- begin addendum 5jan15 -------------------------------------------------






procedure zeroBtns is
begin
	btn_pic1:=0;
	btn_pic2:=0;
	btn_for:=0;
	btn_bak:=0;
end zeroBtns;






-- note that xmax,ymax,zmax = (20,20,20):
function land_alt( x,z : float ) return float is
	cycx: constant float := x*twopi/xmax;
	cycz: constant float := z*twopi/zmax;
	amp : constant float := ymax/50.0; --0.4
	alt, hdist : float;
begin


	alt := -0.1 + amp*( fmath.sin(cycx)+fmath.sin(cycz) )/2.0;

	-- special provision @ castle gate (x,y,z)=(-5,0,-10)
	hdist:=safeSqrt( sqr(-5.0-xme) + sqr(-10.0-zme) );

	-- want floor-level=zero @ doorway
	if hdist<5.0 then
		alt := alt*(hdist/5.0);
	end if;

	return alt;
end land_alt;


procedure sendBat is
begin
-- NOTE:  only need to define (xbat,ybat,zbat) if KEY
--			...chalice destination coded elsewhere.
	batfly:=true;
	batstart:=float(sdl_getticks)/1000.0;
	-- ensure margin<1.0:
	if interior then
		xbat:=0.0;        -- @center
		ybat:=iymax-0.1;  -- @top

		if scene=5 then
			zbat:=-izmax+1.0; 
			-- try drop near doorway (or southroom maze6)
		elsif scene=7 then --grabs cup
			--zbat:=0.0;
			null;
		else -- unhandled
			zbat:=0.0;
		end if;

	else -- far reaches of exterior:

		if chaliceheld then --exitting maze7; bat takes chalice
			--xbat:=+xmaxu-1.0; ybat:=ymax-1.0; zbat:=-zmaxu+1.0;
			null;
		else -- bat takes white key
			xbat:=-xmaxu+1.0; ybat:=ymax-1.0; zbat:=-zmaxu+1.0;
		end if;

	end if;
end sendBat;

-- fly bat in a linear trajectory starting and ending
-- at a randomly chosen, but pickable (x,z) location
-- make the chalice/key-pickup sound, then disappear...
-- but key only if lying on ground and not being held.
-- In case of chalice (scene=7,1), bat grabs it anyway.
procedure drawbat( et: float ) is
	v4, vcc : vec4;
	xt,yt,zt, rtgt,dot, yt0,yt1 : float;
	mindot : constant float := fmath.cos(fourthpi);
	s : integer;
	nx: constant float := 2.0; -- #transitions per second
	i: integer;
	ets, xkey,ykey,zkey: float;
	rng : float;
	xx,yy,zz,xluk,yluk,zluk: float;
begin

	--addendum 2mar18
	if thirdPerson then
		xx:=xcam; yy:=ycam; zz:=zcam;
		xluk:=cxlook; yluk:=cylook; zluk:=czlook;
	else -- firstPerson
		xx:=xme; yy:=yme; zz:=zme;
		xluk:=xlook; yluk:=ylook; zluk:=zlook;
	end if;


if not bat9sent then

	if scene=1 then
		xkey:=xwkey; ykey:=ywkey; zkey:=zwkey;
		ets:=et;
	elsif scene=5 then
		xkey:=xbkey; ykey:=ybkey; zkey:=zbkey;
		ets:=et*8.0;
	end if;

end if;

	myassert( et>=-1.01, 985 );
	myassert( et<=+1.01, 984 );
	-- et in (-1..1)

	i := integer( batduration * et * nx );
	if odd(i) then
		s:=bat1;
	else
		s:=bat2;
	end if;

if 
	bat9sent -- scene=1 final grab of chalice
or
	scene=7 
then 

-- cup-bat flys more like dragon...right at you
-- and grabs chalice out of your hand...

	rng := abs(et)*10.0;
	if rng<0.5 then rng:=0.5; end if;
	--if bat9sent then
	if scene=1 then
		yt0 := yme + abs(et)*(ymax-yme);
	else
		yt0 := yme + abs(et)*(iymax-yme);
	end if;

	-- this trajectory approaches from exact [dynamic] look direction:
	xt :=xx+rng*xluk;
	yt1:=yy+rng*yluk;
	zt :=zz+rng*zluk;

	-- this trajectory mixes the two:
	yt:= abs(et)*yt0 + (1.0-abs(et))*yt1;

	rtgt := safeSqrt( sqr(xt-xx) + sqr(yt-yy) + sqr(zt-zz) );
	if rtgt<0.5 then rtgt:=0.5; end if;

	v4 := (xt,yt,zt,1.0);
	matXvec( imvp, v4, vcc );

	utex.print1a(s,
		vcc(1),vcc(2),
		vcc(3),vcc(4), 600, rtgt);

else -- more typical key-bat flight:
	xt:=xkey+abs(ets)*(xbat-xkey);
	yt:=ykey+abs(ets)*(ybat-ykey);
	zt:=zkey+abs(ets)*(zbat-zkey);

	rtgt := safeSqrt( sqr(xt-xx) + sqr(yt-yy) + sqr(zt-zz) );
	dot := (xt-xx)*xluk + (yt-yy)*yluk + (zt-zz)*zluk;
	v4 := (xt,yt,zt,1.0);
	matXvec( imvp, v4, vcc );

	if (dot/rtgt > mindot) then
		utex.print1a(s,
			vcc(1),vcc(2),
			vcc(3),vcc(4), 600, rtgt);
	end if;

end if;


end drawbat;







procedure drawspider( et: float ) is
	v4, vcc : vec4;
	xt,yt,zt, rtgt,dot : float;
	mindot : constant float := fmath.cos(fourthpi);
	ym: constant float := htobj;
	yx: constant float := iymax-htobj;
	yc: constant float := 0.5*(yx+ym);
	yr: constant float := 0.5*(yx-ym);
	xx,yy,zz,xluk,yluk,zluk: float;
begin

if scene=2 then

	--addendum 2mar18
	if thirdPerson then
		xx:=xcam; yy:=ycam; zz:=zcam;
		xluk:=cxlook; yluk:=cylook; zluk:=czlook;
	else -- firstPerson
		xx:=xme; yy:=yme; zz:=zme;
		xluk:=xlook; yluk:=ylook; zluk:=zlook;
	end if;


	tt := fmath.sin(et*0.1); -- in [-1..1]

	xt:=-9.95;
	zt:=-0.05;
	yt:=yc+tt*yr;

	rtgt := safeSqrt( sqr(xt-xx) + sqr(yt-yy) + sqr(zt-zz) );
	dot := (xt-xx)*xluk + (yt-yy)*yluk + (zt-zz)*zluk;
	v4 := (xt,yt,zt,1.0);
	matXvec( imvp, v4, vcc );

	if (dot/rtgt > mindot) then
		utex.print1a(spider,
			vcc(1),vcc(2),
			vcc(3),vcc(4), 100, rtgt);
	end if;

end if;

end drawspider;























--ydra : float; --only used for next 2 procs

-- 7sep16 revision:  Once the dragon is seen,
-- you cannot turn away...he approaces from
-- whatever your look direction may be !!!
procedure drawBdragon( et: float ) is -- 0<et<1
	v4, vcc : vec4;
	yt0,
	xt1,yt1,zt1,
	xt,yt,zt : float;
	s : integer;
	rng : float := (1.0-et)*20.0;
	ydra,
	xx,yy,zz,xluk,yluk,zluk: float;

begin

	--addendum 2mar18
	if thirdPerson then
		xx:=xcam; yy:=ycam; zz:=zcam;
		xluk:=cxlook; yluk:=cylook; zluk:=czlook;
	else -- firstPerson
		xx:=xme; yy:=yme; zz:=zme;
		xluk:=xlook; yluk:=ylook; zluk:=zlook;
	end if;


	if interior then ydra:=iymax*0.5;
	else ydra:=ymax; end if;

	myassert( et>=-0.01, 983 );
	myassert( et<=+1.01, 982 );
	-- et in (0..1)

	if rng<0.3 then rng:=0.3; end if;
	if et>0.9 then
		s:=blakil;
	else
		s:=bladra;
	end if;



	-- this trajectory approaches from a fixed point (xdra,ydra,zdra) 
	-- above the horizon chosen at the initial look direction:
	--xt0:=xdra+et*(xx-xdra);
	yt0:=ydra+et*(yy-ydra);
	--zt0:=zdra+et*(zz-zdra);

	-- this trajectory approaches from exact [dynamic] look direction:
	xt1:=xx+rng*xluk;
	yt1:=yy+rng*yluk;
	zt1:=zz+rng*zluk;

	-- this trajectory mixes the two:
	yt:= et*yt1 + (1.0-et)*yt0;

	xt:=xt1;
	zt:=zt1;

	v4 := (xt,yt,zt,1.0);
	matXvec( imvp, v4, vcc );

	utex.print1a(s,
		vcc(1),vcc(2),
			vcc(3),vcc(4), 400, rng);

end drawBdragon;










-- 7sep16 revision:  Once the dragon is seen,
-- you cannot turn away...he approaces from
-- whatever your look direction may be !!!
procedure drawRdragon( et: float ) is -- 0<et<1
	v4, vcc : vec4;
	yt0,
	xt1,yt1,zt1,
	xt,yt,zt : float;

	s : integer;

	rng : float := (1.0-et)*5.0;
	ydra,
	xx,yy,zz,xluk,yluk,zluk: float;

begin

	--addendum 2mar18
	if thirdPerson then
		xx:=xcam; yy:=ycam; zz:=zcam;
		xluk:=cxlook; yluk:=cylook; zluk:=czlook;
	else -- firstPerson
		xx:=xme; yy:=yme; zz:=zme;
		xluk:=xlook; yluk:=ylook; zluk:=zlook;
	end if;


	if interior then ydra:=iymax*0.5;
	else ydra:=ymax; end if;

	myassert( et>=-0.01, 981 );
	myassert( et<=+1.01, 980 );
	-- et in (0..1)

	if rng<0.3 then rng:=0.3; end if;
	if et>0.9 then
		s:=redkil; --r2;
	else
		s:=reddra; --r1;
	end if;


	-- this trajectory approaches from a fixed point (xdra,ydra,zdra) 
	-- above the horizon chosen at the initial look direction:
	--xt0:=xdra+et*(xx-xdra);
	yt0:=ydra+et*(yy-ydra);
	--zt0:=zdra+et*(zz-zdra);

	-- this trajectory approaches from exact [dynamic] look direction:
	xt1:=xx+rng*xluk;
	yt1:=yy+rng*yluk;
	zt1:=zz+rng*zluk;

	-- this trajectory mixes the two:
	yt:= et*yt1 + (1.0-et)*yt0;

	xt:=xt1;
	zt:=zt1;

	v4 := (xt,yt,zt,1.0);
	matXvec( imvp, v4, vcc );

	utex.print1a(s,
		vcc(1),vcc(2),
			vcc(3),vcc(4), 400, rng);

end drawRdragon;













procedure drawMinotaur( et: float ) is -- 0<et<1
	v4, vcc : vec4;
	yt0,
	xt1,yt1,zt1,
	xt,yt,zt : float;
	rng : float := (1.0-et)*20.0;
	ydra,
	xx,yy,zz,xluk,yluk,zluk: float;

begin

	--addendum 2mar18
	if thirdPerson then
		xx:=xcam; yy:=ycam; zz:=zcam;
		xluk:=cxlook; yluk:=cylook; zluk:=czlook;
	else -- firstPerson
		xx:=xme; yy:=yme; zz:=zme;
		xluk:=xlook; yluk:=ylook; zluk:=zlook;
	end if;


	ydra:=iymax*0.5;

	myassert( et>=-0.01, 979 );
	myassert( et<=+1.01, 978 );
	-- et in (0..1)

	if rng<0.3 then rng:=0.3; end if;

	-- this trajectory approaches from a fixed point (xdra,ydra,zdra) 
	-- above the horizon chosen at the initial look direction:
	--xt0:=xdra+et*(xme-xdra);
	yt0:=ydra+et*(yy-ydra);

	-- this trajectory approaches from exact [dynamic] look direction:
	xt1:=xx+rng*xluk;
	yt1:=yy+rng*yluk;
	zt1:=zz+rng*zluk;

	-- this trajectory mixes the two:
	yt:= et*yt1 + (1.0-et)*yt0;

	xt:=xt1;
	zt:=zt1;

	v4 := (xt,yt,zt,1.0);
	matXvec( imvp, v4, vcc );

	utex.print1a(gnu,
		vcc(1),vcc(2),
			vcc(3),vcc(4), 500, rng);

end drawMinotaur;










procedure initializeNewMazes is
begin

	-- The maze interconnections in this game are complex.
	-- Begin by organizing the many doorways that
	-- transition within & between mazes.  This includes
	-- the ideal velocity direction required to pass thru,
	-- as well as the precise doorway locations, using
	-- coordinates PRIOR to traversal.
	-- The encoding string-keys come from "map.txt", a
	-- design document that can be found in ./mazeDesign/.
	-- The maze table is a structure using the "Tables"
	-- library of Dmitry Kazakov, that allows the
	-- association of a data record (x,z,dir) to a 
	-- given string-key.
	

	-- scene5 transitions:
	maze_table.add(mtab,"5c", (+10.0,+9.0,+halfpi));
	maze_table.add(mtab,"5y", (-10.0,+9.0,-halfpi));
	maze_table.add(mtab,"5d", (+10.0,+4.0,+halfpi));
	maze_table.add(mtab,"5z", (-10.0,+4.0,-halfpi));
	maze_table.add(mtab,"5e", (+10.0,+2.0,+halfpi));
	maze_table.add(mtab,"5v", (-10.0,+2.0,-halfpi));
	maze_table.add(mtab,"5f", (+10.0,+0.0,+halfpi));
	maze_table.add(mtab,"5w", (-10.0,+0.0,-halfpi));
	maze_table.add(mtab,"5g", (+10.0,-2.0,+halfpi));
	maze_table.add(mtab,"5x", (-10.0,-2.0,-halfpi));
	maze_table.add(mtab,"5ex", (0.0,-10.0,+onepi));

	-- scene6 transitions:
	maze_table.add(mtab,"6al", (+10.0,+9.0,+halfpi));
	maze_table.add(mtab,"6c", (-10.0,+9.0,-halfpi));
	maze_table.add(mtab,"6bl", (+10.0,+4.0,+halfpi));
	maze_table.add(mtab,"6d", (-10.0,+4.0,-halfpi));
	maze_table.add(mtab,"6v", (+10.0,+2.0,+halfpi));
	maze_table.add(mtab,"6e", (-10.0,+2.0,-halfpi));
	maze_table.add(mtab,"6w", (+10.0,+0.0,+halfpi));
	maze_table.add(mtab,"6f", (-10.0,+0.0,-halfpi));
	maze_table.add(mtab,"6x", (+10.0,-2.0,+halfpi));
	maze_table.add(mtab,"6g", (-10.0,-2.0,-halfpi));
	maze_table.add(mtab,"6y", (+10.0,-4.0,+halfpi));
	maze_table.add(mtab,"6ar", (-10.0,-4.0,-halfpi));
	maze_table.add(mtab,"6z", (+10.0,-9.0,+halfpi));
	maze_table.add(mtab,"6br", (-10.0,-9.0,-halfpi));
	maze_table.add(mtab,"6ex", (+0.0,+10.0, 0.0));


	-- scene7 transitions:
	maze_table.add(mtab,"7al", (-10.0,-9.0,-halfpi));
	maze_table.add(mtab,"7dr", (+10.0,-9.0,+halfpi));
	maze_table.add(mtab,"7bl", (-10.0,-7.0,-halfpi));
	maze_table.add(mtab,"7er", (+10.0,-7.0,+halfpi));
	maze_table.add(mtab,"7cl", (-10.0,-4.0,-halfpi));
	maze_table.add(mtab,"7fr", (+10.0,-4.0,+halfpi));
	maze_table.add(mtab,"7dl", (-10.0,-2.0,-halfpi));
	maze_table.add(mtab,"7ar", (+10.0,-2.0,+halfpi));
	maze_table.add(mtab,"7el", (-10.0, 0.0,-halfpi));
	maze_table.add(mtab,"7br", (+10.0, 0.0,+halfpi));
	maze_table.add(mtab,"7fl", (-10.0,+3.0,-halfpi));
	maze_table.add(mtab,"7cr", (+10.0,+3.0,+halfpi));
	maze_table.add(mtab,"7h", (+10.0,+7.0,+halfpi));
	maze_table.add(mtab,"7ex", (0.0,-10.0,+onepi));


	-- scene8 transitions:
	maze_table.add(mtab,"8h", (-10.0,+7.0,-halfpi));
	maze_table.add(mtab,"8g", (+10.0,+7.0,+halfpi));


	-- scene9 transitions:
	maze_table.add(mtab,"9fl", (+8.0,-10.0,+onepi));
	maze_table.add(mtab,"9cr", (+6.0,+10.0, 0.0));
	maze_table.add(mtab,"9bl", (+5.0,-10.0,+onepi));
	maze_table.add(mtab,"9al", (+1.0,-10.0,+onepi));
	maze_table.add(mtab,"9fr", (-2.0,+10.0, 0.0));
	maze_table.add(mtab,"9cl", (-4.0,-10.0,+onepi));
	maze_table.add(mtab,"9br", (-5.0,+10.0, 0.0));
	maze_table.add(mtab,"9ar", (-9.0,+10.0, 0.0));
	maze_table.add(mtab,"9dt", (+10.0,-8.0,+halfpi));
	maze_table.add(mtab,"9et", (+10.0,-1.0,+halfpi));
	maze_table.add(mtab,"9db", (-10.0,-8.0,-halfpi));
	maze_table.add(mtab,"9eb", (-10.0,-1.0,-halfpi));
	maze_table.add(mtab,"9x",  (-10.0,+7.0, -halfpi));


	-- scene2 transitions:
	maze_table.add(mtab,"2e", (-5.0,-10.0, 0.0));
	maze_table.add(mtab,"2x", (-5.0,-10.0,+onepi));

	-- scene1 transitions:
	maze_table.add(mtab,"1e", (0.0,-10.0,+onepi));
	maze_table.add(mtab,"1x", (+7.0,+4.6, 0.0));

	-- scene4 transitions:
	maze_table.add(mtab,"4e", (0.0,+10.0, 0.0));
	maze_table.add(mtab,"4x", (0.0,-10.0,+onepi));


-- Now, we initialize the array that defines the mazes:

	for im in scenerng loop
	for row in -mrows..mrows loop
	for col in -mcols..mcols loop
		--passthru(im,row,col):=false;
		iswall(im,row,col):=false;
	end loop; --col
	end loop; --row
	end loop; --im



-- begin scene #9 =======================

	iswall(9,+10,-6):=true;
	iswall(9,+10,-2):=true;
	iswall(9,+10,+5):=true;

	iswall(9,+9,-6):=true;
	iswall(9,+9,-2):=true;
	iswall(9,+9,+5):=true;

	iswall(9,+8,-6):=true;
	iswall(9,+8,-4):=true;
	iswall(9,+8,-3):=true;
	iswall(9,+8,-2):=true;
	iswall(9,+8,-1):=true;
	iswall(9,+8, 0):=true;
	iswall(9,+8,+1):=true;
	iswall(9,+8,+2):=true;
	iswall(9,+8,+3):=true;
	iswall(9,+8,+5):=true;
	iswall(9,+8,+6):=true;
	iswall(9,+8,+7):=true;
	iswall(9,+8,+8):=true;

	iswall(9,+7,-6):=true;
	iswall(9,+7,-4):=true;
	iswall(9,+7,+3):=true;
	iswall(9,+7,+8):=true;

	iswall(9,+6,-10):=true;
	iswall(9,+6,-9):=true;
	iswall(9,+6,-8):=true;
	iswall(9,+6,-7):=true;
	iswall(9,+6,-6):=true;
	iswall(9,+6,-4):=true;
	iswall(9,+6,-3):=true;
	iswall(9,+6,-2):=true;
	iswall(9,+6,-1):=true;
	iswall(9,+6, 0):=true;
	iswall(9,+6,+1):=true;
	iswall(9,+6,+3):=true;
	iswall(9,+6,+6):=true;
	iswall(9,+6,+7):=true;
	iswall(9,+6,+8):=true;

	iswall(9,+5,+3):=true;
	iswall(9,+5,+6):=true;
	iswall(9,+5,+8):=true;
	iswall(9,+5,+10):=true;

	iswall(9,+4,-8):=true;
	iswall(9,+4,-7):=true;
	iswall(9,+4,-6):=true;
	iswall(9,+4,-5):=true;
	iswall(9,+4,-4):=true;
	iswall(9,+4,-3):=true;
	iswall(9,+4,-2):=true;
	iswall(9,+4, 0):=true;
	iswall(9,+4,+3):=true;
	iswall(9,+4,+6):=true;
	iswall(9,+4,+10):=true;

	iswall(9,+3,-8):=true;
	iswall(9,+3,-2):=true;
	iswall(9,+3, 0):=true;
	iswall(9,+3,+3):=true;
	iswall(9,+3,+6):=true;

	iswall(9,+2,-8):=true;
	iswall(9,+2,-2):=true;
	iswall(9,+2, 0):=true;
	iswall(9,+2,+3):=true;
	iswall(9,+2,+6):=true;
	iswall(9,+2,+8):=true;

	iswall(9,+1,-8):=true;
	iswall(9,+1,-2):=true;
	iswall(9,+1, 0):=true;
	iswall(9,+1,+1):=true;
	iswall(9,+1,+2):=true;
	iswall(9,+1,+3):=true;
	iswall(9,+1,+6):=true;
	iswall(9,+1,+8):=true;







	iswall(9,-0,-10):=true;
	iswall(9,-0,-9):=true;
	iswall(9,-0,-8):=true;
	iswall(9,-0,-6):=true;
	iswall(9,-0,-5):=true;
	iswall(9,-0,-4):=true;
	iswall(9,-0,-2):=true;
	iswall(9,-0,+2):=true;
	iswall(9,-0,+3):=true;
	iswall(9,-0,+4):=true;
	iswall(9,-0,+6):=true;
	iswall(9,-0,+8):=true;

	iswall(9,-1,-4):=true;
	iswall(9,-1,-2):=true;
	iswall(9,-1, 0):=true;
	iswall(9,-1,+2):=true;
	iswall(9,-1,+4):=true;
	iswall(9,-1,+6):=true;
	iswall(9,-1,+8):=true;

	iswall(9,-2,-4):=true;
	iswall(9,-2, 0):=true;
	iswall(9,-2,+2):=true;
	iswall(9,-2,+4):=true;
	iswall(9,-2,+6):=true;
	iswall(9,-2,+8):=true;

	iswall(9,-3,-8):=true;
	iswall(9,-3,-7):=true;
	iswall(9,-3,-6):=true;
	iswall(9,-3,-5):=true;
	iswall(9,-3,-4):=true;
	iswall(9,-3, 0):=true;
	iswall(9,-3,+2):=true;
	iswall(9,-3,+4):=true;
	iswall(9,-3,+8):=true;
	iswall(9,-3,+9):=true;
	iswall(9,-3,+10):=true;

	iswall(9,-4,-8):=true;
	iswall(9,-4,-4):=true;
	iswall(9,-4,-2):=true;
	iswall(9,-4,-1):=true;
	iswall(9,-4, 0):=true;
	iswall(9,-4,+4):=true;
	iswall(9,-4,+5):=true;
	iswall(9,-4,+6):=true;
	iswall(9,-4,+7):=true;
	iswall(9,-4,+8):=true;
	iswall(9,-4,+9):=true;
	iswall(9,-4,+10):=true;

	iswall(9,-5,-8):=true;
	iswall(9,-5,-4):=true;
	iswall(9,-5,-2):=true;
	iswall(9,-5,+4):=true; --2jan18

	iswall(9,-6,-10):=true;
	iswall(9,-6,-9):=true;
	iswall(9,-6,-8):=true;
	iswall(9,-6,-7):=true;
	iswall(9,-6,-6):=true;
	iswall(9,-6,-5):=true;
	iswall(9,-6,-4):=true;
	iswall(9,-6,-2):=true;
	iswall(9,-6, 0):=true;
	iswall(9,-6,+1):=true;
	iswall(9,-6,+2):=true;
	iswall(9,-6,+3):=true;
	iswall(9,-6,+4):=true;
	iswall(9,-6,+5):=true;
	iswall(9,-6,+8):=true;
	iswall(9,-6,+9):=true;
	iswall(9,-6,+10):=true;

	iswall(9,-7,-2):=true;
	iswall(9,-7, 0):=true;
	iswall(9,-7,+5):=true;
	iswall(9,-7,+8):=true;
	iswall(9,-7,+10):=true;

	iswall(9,-8,-7):=true;
	iswall(9,-8,-6):=true;
	iswall(9,-8,-5):=true;
	iswall(9,-8,-4):=true;
	iswall(9,-8,-3):=true;
	iswall(9,-8,-2):=true;
	iswall(9,-8, 0):=true;
	iswall(9,-8,+2):=true;
	iswall(9,-8,+3):=true;
	iswall(9,-8,+4):=true;
	iswall(9,-8,+5):=true;
	iswall(9,-8,+8):=true;
	iswall(9,-8,+9):=true;
	iswall(9,-8,+10):=true;

	iswall(9,-9,-7):=true;
	iswall(9,-9,-2):=true;
	iswall(9,-9, 0):=true;

	iswall(9,-10,-7):=true;
	iswall(9,-10,-2):=true;
	iswall(9,-10, 0):=true;



-- end of scene #9 ==============================



-- scene # 6 ========================================================
	-- topexit ------------

	--iswall(6,10,10):=true;
	--iswall(6,9,10):=true;
	--iswall(6,8,10):=true;
	--iswall(6,7,10):=true;
	--iswall(6,6,10):=true;
	--iswall(6,5,10):=true;
	--iswall(6,4,10):=true;
	--iswall(6,3,10):=true;

	iswall(6,5,10):=true;
	iswall(6,3,10):=true;

	iswall(6,5,9):=true;
	iswall(6,3,9):=true;

	iswall(6,10,8):=true;
	iswall(6,9,8):=true;
	iswall(6,8,8):=true;
	iswall(6,7,8):=true;
	iswall(6,5,8):=true;
	iswall(6,3,8):=true;

	iswall(6,10,7):=true;
	iswall(6,7,7):=true;
	iswall(6,5,7):=true;
	iswall(6,3,7):=true;
	iswall(6,2,7):=true;

	iswall(6,10,6):=true;
	iswall(6,7,6):=true;
	iswall(6,5,6):=true;

	iswall(6,10,5):=true;
	iswall(6,9,5):=true;
	iswall(6,8,5):=true;
	iswall(6,7,5):=true;
	iswall(6,6,5):=true;
	iswall(6,5,5):=true;
	iswall(6,4,5):=true;
	iswall(6,3,5):=true;
	iswall(6,2,5):=true; --passthru(6,2,5):=true; --symmetric pos
	iswall(6,1,5):=true;

	iswall(6,5,4):=true;
	iswall(6,1,4):=true;

	iswall(6,10,3):=true;
	iswall(6,9,3):=true;
	iswall(6,8,3):=true;
	iswall(6,7,3):=true;
	iswall(6,5,3):=true;
	iswall(6,3,3):=true;
	iswall(6,2,3):=true;
	iswall(6,1,3):=true;
-------------------------- repeat negating 1st coord:

	--iswall(6,-10,10):=true;
	--iswall(6,-9,10):=true;
	--iswall(6,-8,10):=true;
	--iswall(6,-7,10):=true;
	--iswall(6,-6,10):=true;
	--iswall(6,-5,10):=true;
	--iswall(6,-4,10):=true;
	--iswall(6,-3,10):=true;

	iswall(6,-5,10):=true;
	iswall(6,-3,10):=true;

	iswall(6,-5,9):=true;
	iswall(6,-3,9):=true;

	iswall(6,-10,8):=true;
	iswall(6,-9,8):=true;
	iswall(6,-8,8):=true;
	iswall(6,-7,8):=true;
	iswall(6,-5,8):=true;
	iswall(6,-3,8):=true;

	iswall(6,-10,7):=true;
	iswall(6,-7,7):=true;
	iswall(6,-5,7):=true;
	iswall(6,-3,7):=true;
	iswall(6,-2,7):=true;

	iswall(6,-10,6):=true;
	iswall(6,-7,6):=true;
	iswall(6,-5,6):=true;

	iswall(6,-10,5):=true;
	iswall(6,-9,5):=true;
	iswall(6,-8,5):=true;
	iswall(6,-7,5):=true;
	iswall(6,-6,5):=true;
	iswall(6,-5,5):=true;
	iswall(6,-4,5):=true;
	iswall(6,-3,5):=true;
	iswall(6,-2,5):=true;  --passthru(6,-2,5):=true; --original pos
	iswall(6,-1,5):=true;

	iswall(6,-5,4):=true;
	iswall(6,-1,4):=true;

	iswall(6,-10,3):=true;
	iswall(6,-9,3):=true;
	iswall(6,-8,3):=true;
	iswall(6,-7,3):=true;
	iswall(6,-5,3):=true;
	iswall(6,-3,3):=true;
	iswall(6,-2,3):=true;
	iswall(6,-1,3):=true;

--==========================================

	-- mid -------------------------------------

	iswall(6,10,3):=true;
	iswall(6,9,3):=true;
	iswall(6,8,3):=true;
	iswall(6,7,3):=true;
	iswall(6,5,3):=true;
	iswall(6,3,3):=true;
	iswall(6,2,3):=true;
	iswall(6,1,3):=true;

	iswall(6,5,2):=true;
	iswall(6,2,2):=true;
	iswall(6,1,2):=true;

	iswall(6,10,1):=true;
	iswall(6,9,1):=true;
	iswall(6,8,1):=true;
	iswall(6,7,1):=true;
	iswall(6,6,1):=true;
	iswall(6,5,1):=true;
	iswall(6,4,1):=true;
	iswall(6,2,1):=true;
	iswall(6,1,1):=true;

	iswall(6,4,0):=true;
	iswall(6,2,0):=true;
	iswall(6,1,0):=true;

	iswall(6,10,-1):=true;
	iswall(6,9,-1):=true;
	iswall(6,8,-1):=true;
	iswall(6,6,-1):=true;
	iswall(6,4,-1):=true;
	iswall(6,2,-1):=true;
	iswall(6,1,-1):=true;

	iswall(6,6,-2):=true;
	iswall(6,4,-2):=true;
	iswall(6,2,-2):=true;

	iswall(6,10,-3):=true;
	iswall(6,9,-3):=true;
	iswall(6,8,-3):=true;
	iswall(6,7,-3):=true;
	iswall(6,6,-3):=true;
	iswall(6,4,-3):=true;
	iswall(6,2,-3):=true;

-------------------------- repeat negating 1st coord:

	iswall(6,-10,3):=true;
	iswall(6,-9,3):=true;
	iswall(6,-8,3):=true;
	iswall(6,-7,3):=true;
	iswall(6,-5,3):=true;
	iswall(6,-3,3):=true;
	iswall(6,-2,3):=true;
	iswall(6,-1,3):=true;

	iswall(6,-5,2):=true;
	iswall(6,-2,2):=true;
	iswall(6,-1,2):=true;

	iswall(6,-10,1):=true;
	iswall(6,-9,1):=true;
	iswall(6,-8,1):=true;
	iswall(6,-7,1):=true;
	iswall(6,-6,1):=true;
	iswall(6,-5,1):=true;
	iswall(6,-4,1):=true;
	iswall(6,-2,1):=true;
	iswall(6,-1,1):=true;

	iswall(6,-4,0):=true;
	iswall(6,-2,0):=true;
	iswall(6,-1,0):=true;

	iswall(6,-10,-1):=true;
	iswall(6,-9,-1):=true;
	iswall(6,-8,-1):=true;
	iswall(6,-6,-1):=true;
	iswall(6,-4,-1):=true;
	iswall(6,-2,-1):=true;
	iswall(6,-1,-1):=true;

	iswall(6,-6,-2):=true;
	iswall(6,-4,-2):=true;
	iswall(6,-2,-2):=true;

	iswall(6,-10,-3):=true;
	iswall(6,-9,-3):=true;
	iswall(6,-8,-3):=true;
	iswall(6,-7,-3):=true;
	iswall(6,-6,-3):=true;
	iswall(6,-4,-3):=true;
	iswall(6,-2,-3):=true;



--==========================================

	-- bot -------------------------------------

	iswall(6,10,-3):=true;
	iswall(6,9,-3):=true;
	iswall(6,8,-3):=true;
	iswall(6,7,-3):=true;
	iswall(6,6,-3):=true;
	iswall(6,4,-3):=true;
	iswall(6,2,-3):=true;

	iswall(6,6,-4):=true;
	iswall(6,2,-4):=true;

	iswall(6,10,-5):=true;
	iswall(6,9,-5):=true;
	iswall(6,8,-5):=true;
	iswall(6,6,-5):=true;
	iswall(6,5,-5):=true;
	iswall(6,4,-5):=true;
	iswall(6,3,-5):=true;
	iswall(6,2,-5):=true;

	iswall(6,8,-6):=true;

	iswall(6,8,-7):=true;
	iswall(6,7,-7):=true;
	iswall(6,6,-7):=true;

	iswall(6,10,-8):=true;
	iswall(6,9,-8):=true;
	iswall(6,8,-8):=true;
	iswall(6,6,-8):=true;

	iswall(6,6,-9):=true;

	iswall(6,6,-10):=true;

	--iswall(6,10,-10):=true;
	--iswall(6,9,-10):=true;
	--iswall(6,8,-10):=true;
	--iswall(6,7,-10):=true;
	--iswall(6,6,-10):=true;
	--iswall(6,5,-10):=true;
	--iswall(6,4,-10):=true;
	--iswall(6,3,-10):=true;
	--iswall(6,2,-10):=true;
	--iswall(6,1,-10):=true;
	--iswall(6,0,-10):=true;

-------------------------- repeat negating 1st coord:

	iswall(6,-10,-3):=true;
	iswall(6,-9,-3):=true;
	iswall(6,-8,-3):=true;
	iswall(6,-7,-3):=true;
	iswall(6,-6,-3):=true;
	iswall(6,-4,-3):=true;
	iswall(6,-2,-3):=true;

	iswall(6,-6,-4):=true;
	iswall(6,-2,-4):=true;

	iswall(6,-10,-5):=true;
	iswall(6,-9,-5):=true;
	iswall(6,-8,-5):=true;
	iswall(6,-6,-5):=true;
	iswall(6,-5,-5):=true;
	iswall(6,-4,-5):=true;
	iswall(6,-3,-5):=true;
	iswall(6,-2,-5):=true;

	iswall(6,-8,-6):=true;

	iswall(6,-8,-7):=true;
	iswall(6,-7,-7):=true;
	iswall(6,-6,-7):=true;

	iswall(6,-10,-8):=true;
	iswall(6,-9,-8):=true;
	iswall(6,-8,-8):=true;
	iswall(6,-6,-8):=true;

	iswall(6,-6,-9):=true;

	iswall(6,-6,-10):=true;

--=========== done with scene #6;  begin scene #5 ================

-- midLR = maze entry @ bottom = Zmin


	iswall(5,10,-1):=true;
	iswall(5,9,-1):=true;
	iswall(5,8,-1):=true;
	iswall(5,7,-1):=true;
	iswall(5,6,-1):=true;

	iswall(5,4,-1):=true;
	iswall(5,3,-1):=true;
	iswall(5,2,-1):=true;
	iswall(5,1,-1):=true;
	iswall(5,0,-1):=true;

	iswall(5,6,0):=true;
	iswall(5,4,0):=true;

	iswall(5,10,1):=true;
	iswall(5,9,1):=true;
	iswall(5,8,1):=true;
	iswall(5,6,1):=true;
	iswall(5,4,1):=true;
	iswall(5,2,1):=true;
iswall(5,1,1):=true; --2jul19
	iswall(5,0,1):=true;

	iswall(5,6,2):=true;
	iswall(5,4,2):=true;
	iswall(5,2,2):=true;

	iswall(5,10,3):=true;
	iswall(5,9,3):=true;
	iswall(5,8,3):=true;
	iswall(5,7,3):=true;
	iswall(5,6,3):=true;
	iswall(5,4,3):=true;
	iswall(5,2,3):=true;
	iswall(5,0,3):=true;

-------------------------- repeat negating 1st coord:

	iswall(5,-10,-1):=true;
	iswall(5,-9,-1):=true;
	iswall(5,-8,-1):=true;
	iswall(5,-7,-1):=true;
	iswall(5,-6,-1):=true;

	iswall(5,-4,-1):=true;
	iswall(5,-3,-1):=true;
	iswall(5,-2,-1):=true;
	iswall(5,-1,-1):=true;

	iswall(5,-6,0):=true;
	iswall(5,-4,0):=true;

	iswall(5,-10,1):=true;
	iswall(5,-9,1):=true;
	iswall(5,-8,1):=true;
	iswall(5,-6,1):=true;
	iswall(5,-4,1):=true;
	iswall(5,-2,1):=true;
iswall(5,-1,1):=true; --2jul19

	iswall(5,-6,2):=true;
	iswall(5,-4,2):=true;
	iswall(5,-2,2):=true;

	iswall(5,-10,3):=true;
	iswall(5,-9,3):=true;
	iswall(5,-8,3):=true;
	iswall(5,-7,3):=true;
	iswall(5,-6,3):=true;
	iswall(5,-4,3):=true;
	iswall(5,-2,3):=true;



--==========================================

	-- botL-exitR -------------------------------------

	iswall(5,10,8):=true;
	iswall(5,9,8):=true;
	iswall(5,8,8):=true;
	iswall(5,7,8):=true;
	iswall(5,6,8):=true;
	iswall(5,5,8):=true;
	iswall(5,3,8):=true;
	iswall(5,2,8):=true;
	iswall(5,1,8):=true;
	iswall(5,0,8):=true;

	iswall(5,10,7):=true;
	iswall(5,8,7):=true;
	iswall(5,0,7):=true;

	iswall(5,10,6):=true;
	iswall(5,8,6):=true;
	iswall(5,6,6):=true;
	iswall(5,5,6):=true;
	iswall(5,4,6):=true;
	iswall(5,3,6):=true;
	iswall(5,2,6):=true;
	iswall(5,0,6):=true;

	iswall(5,10,5):=true;
	iswall(5,9,5):=true;
	iswall(5,8,5):=true;
	iswall(5,6,5):=true;
	iswall(5,2,5):=true;
	iswall(5,0,5):=true;

	iswall(5,6,4):=true;
	iswall(5,4,4):=true;
	iswall(5,2,4):=true;
	iswall(5,0,4):=true;


-------------------------- repeat negating 1st coord:


	iswall(5,-10,8):=true;
	iswall(5,-9,8):=true;
	iswall(5,-8,8):=true;
	iswall(5,-7,8):=true;
	iswall(5,-6,8):=true;
	iswall(5,-5,8):=true;
	iswall(5,-3,8):=true;
	iswall(5,-2,8):=true;
	iswall(5,-1,8):=true;

	iswall(5,-10,7):=true;
	iswall(5,-8,7):=true;

	iswall(5,-10,6):=true;
	iswall(5,-8,6):=true;
	iswall(5,-6,6):=true;
	iswall(5,-5,6):=true;
	iswall(5,-4,6):=true;
	iswall(5,-3,6):=true;
	iswall(5,-2,6):=true;

	iswall(5,-10,5):=true;
	iswall(5,-9,5):=true;
	iswall(5,-8,5):=true;
	iswall(5,-6,5):=true;
	iswall(5,-2,5):=true;

	iswall(5,-6,4):=true;
	iswall(5,-4,4):=true;
	iswall(5,-2,4):=true;








------------- begin maze #7 = orange maze to white castle -------------

----- warning:  x,z coords here are interchanged ------------

-- 1st define left half of scene7.txt:


	iswall(7,-10,-7):=true; -- z=-10, x=-7 => (-7,-10)
	iswall(7,-9,-7):=true; --(-7,-9)

	iswall(7,-8,-0):=true; --( 0,-8)
	iswall(7,-8,-1):=true; --(-1,-8)
	iswall(7,-8,-2):=true; --(-2,-8)
	iswall(7,-8,-3):=true;
	iswall(7,-8,-4):=true;
	iswall(7,-8,-7):=true;
	iswall(7,-8,-9):=true;
	iswall(7,-8,-10):=true;

	iswall(7,-7,0):=true;
	iswall(7,-7,-7):=true;

	iswall(7,-6,-0):=true;
	iswall(7,-6,-4):=true;
	iswall(7,-6,-5):=true;
	iswall(7,-6,-7):=true;
	iswall(7,-6,-8):=true;
	iswall(7,-6,-9):=true;
	iswall(7,-6,-10):=true;

	iswall(7,-5,-0):=true; --( 0,-5)
	iswall(7,-5,-4):=true; --(-4,-5)
	iswall(7,-5,-5):=true; --(-5,-5)
	iswall(7,-5,-7):=true;
	iswall(7,-5,-8):=true;
	iswall(7,-5,-9):=true;
	iswall(7,-5,-10):=true;

	iswall(7,-4,-0):=true; --( 0,-4)
	iswall(7,-4,-4):=true; --(-4,-4)
	iswall(7,-4,-5):=true; --(-5,-4)


	iswall(7,-3,-0):=true; --( 0,-3)
	iswall(7,-3,-2):=true; --(-2,-3)
	iswall(7,-3,-4):=true;
	iswall(7,-3,-5):=true;
	iswall(7,-3,-6):=true;
	iswall(7,-3,-7):=true;
	iswall(7,-3,-8):=true;
	iswall(7,-3,-9):=true;
	iswall(7,-3,-10):=true;

	iswall(7,-2,0):=true;
	iswall(7,-2,-2):=true;

	iswall(7,-1,-0):=true;
	iswall(7,-1,-2):=true;
	iswall(7,-1,-3):=true;
	iswall(7,-1,-4):=true;
	iswall(7,-1,-8):=true;
	iswall(7,-1,-9):=true;
	iswall(7,-1,-10):=true;

	iswall(7,0,-4):=true; --last of upper half

	iswall(7,1,0):=true;
	iswall(7,1,-1):=true;
	iswall(7,1,-2):=true;
	iswall(7,1,-4):=true;
	iswall(7,1,-6):=true;
	iswall(7,1,-7):=true;
	iswall(7,1,-8):=true;
	iswall(7,1,-9):=true;
	iswall(7,1,-10):=true;

	iswall(7,2,-2):=true;
	iswall(7,2,-4):=true;
	iswall(7,2,-6):=true;
	iswall(7,2,-7):=true;
	iswall(7,2,-8):=true;
	iswall(7,2,-9):=true;
	iswall(7,2,-10):=true;

	iswall(7,3,0):=true;
	iswall(7,3,-2):=true;
	iswall(7,3,-4):=true;
	iswall(7,3,-6):=true;

	iswall(7,4,0):=true;
	iswall(7,4,-2):=true;
	iswall(7,4,-4):=true;
	iswall(7,4,-6):=true;
	iswall(7,4,-8):=true;
	iswall(7,4,-9):=true;
	iswall(7,4,-10):=true;

	iswall(7,5,0):=true;
	iswall(7,5,-2):=true;
	iswall(7,5,-6):=true;
	iswall(7,5,-8):=true;
	iswall(7,5,-9):=true;
	iswall(7,5,-10):=true;


	iswall(7,6,0):=true;
	iswall(7,6,-2):=true;
	iswall(7,6,-3):=true;
	iswall(7,6,-4):=true;
	iswall(7,6,-5):=true;
	iswall(7,6,-6):=true;

	iswall(7,7,0):=true;

	iswall(7,8,0):=true;
	iswall(7,8,-2):=true;
	iswall(7,8,-3):=true;
	iswall(7,8,-4):=true;
iswall(7,8,-5):=true; --3jul19
	iswall(7,8,-6):=true;


	iswall(7,9,0):=true;
	iswall(7,9,-6):=true;

	iswall(7,10, 0):=true;
	iswall(7,10,-6):=true;


------ now, repeat maze#7 but negating 3rd coord ----------------------


	iswall(7,-10,7):=true;

	iswall(7,-9,7):=true;

	iswall(7,-8,1):=true;
	iswall(7,-8,2):=true;
	iswall(7,-8,3):=true;
	iswall(7,-8,4):=true;
	iswall(7,-8,7):=true;
	iswall(7,-8,9):=true;
	iswall(7,-8,10):=true;

	iswall(7,-7,7):=true;

	iswall(7,-6,4):=true;
	iswall(7,-6,5):=true;
	iswall(7,-6,7):=true;
	iswall(7,-6,8):=true;
	iswall(7,-6,9):=true;
	iswall(7,-6,10):=true;

	iswall(7,-5,4):=true;
	iswall(7,-5,5):=true;
	iswall(7,-5,7):=true;
	iswall(7,-5,8):=true;
	iswall(7,-5,9):=true;
	iswall(7,-5,10):=true;

	iswall(7,-4,4):=true;
	iswall(7,-4,5):=true;

	iswall(7,-3,2):=true;
	iswall(7,-3,4):=true;
	iswall(7,-3,5):=true;
	iswall(7,-3,6):=true;
	iswall(7,-3,7):=true;
	iswall(7,-3,8):=true;
	iswall(7,-3,9):=true;
	iswall(7,-3,10):=true;

	iswall(7,-2,2):=true;

	iswall(7,-1,2):=true;
	iswall(7,-1,3):=true;
	iswall(7,-1,4):=true;
	iswall(7,-1,8):=true;
	iswall(7,-1,9):=true;
	iswall(7,-1,10):=true;

	iswall(7,0,4):=true; --last of upper half

	iswall(7,1,1):=true;
	iswall(7,1,2):=true;
	iswall(7,1,4):=true;
	iswall(7,1,6):=true;
	iswall(7,1,7):=true;
	iswall(7,1,8):=true;
	iswall(7,1,9):=true;
	iswall(7,1,10):=true;

	iswall(7,2,2):=true;
	iswall(7,2,4):=true;
	iswall(7,2,6):=true;
	iswall(7,2,7):=true;
	iswall(7,2,8):=true;
	iswall(7,2,9):=true;
	iswall(7,2,10):=true;

	iswall(7,3,2):=true;
	iswall(7,3,4):=true;
	iswall(7,3,6):=true;

	iswall(7,4,2):=true;
	iswall(7,4,4):=true;
	iswall(7,4,6):=true;
	iswall(7,4,8):=true;
	iswall(7,4,9):=true;
	iswall(7,4,10):=true;

	iswall(7,5,2):=true;
	iswall(7,5,6):=true;
	iswall(7,5,8):=true;
	iswall(7,5,9):=true;
	iswall(7,5,10):=true;


	iswall(7,6,2):=true;
	iswall(7,6,3):=true;
	iswall(7,6,4):=true;
	iswall(7,6,5):=true;
	iswall(7,6,6):=true;


	iswall(7,8,2):=true;
	iswall(7,8,3):=true;
	iswall(7,8,4):=true;
iswall(7,8,5):=true; --3jul19
	iswall(7,8,6):=true;


	iswall(7,9,6):=true;

	iswall(7,10,6):=true;


-------- scene#7 transitions (letter,z,x) ------------------------
-- (-9,-10)  7A  (-2,+10)		dxme:=+(20+step)/-(20+step);
-- (-7,-10)  7B  ( 0,+10)
-- (-4,-10)  7C  (+3,+10)
-- (-2,-10)  7D  (-9,+10)
-- ( 0,-10)  7E  (-7,+10)
-- (+3,-10)  7F  (-4,+10)

-- entry @ (-10,0)
-- exit  @ (+7,-10) to room8 @ (7,+10)
-- exit  @ (+7,+10) to room8 @ (7,-10)
-------------------------------------------



------------ begin scene #8 labyrinth ---------------------------
--
-- entry @ (x,z)=(-10,7) & (+10,7)  minotaur@(0,-1)=center
-----------------------------------------------------------

-- note:  these x,z coords are NOT reversed

	-- -X wall:
	iswall(8,-8,7):=true;

	iswall(8,-8,-8):=true;
	iswall(8,-8,-7):=true;
	iswall(8,-8,-6):=true;
	iswall(8,-8,-5):=true;
	iswall(8,-8,-4):=true;
	iswall(8,-8,-3):=true;
	iswall(8,-8,-2):=true;
	iswall(8,-8,-1):=true; --passthru(8,-8,-1):=true;
	iswall(8,-8,0):=true;
	iswall(8,-8,1):=true;
	iswall(8,-8,2):=true;
	iswall(8,-8,3):=true;
	iswall(8,-8,4):=true;

	iswall(8,-6,-6):=true;
	iswall(8,-6,-5):=true;
	iswall(8,-6,-4):=true;
	iswall(8,-6,-3):=true;
	iswall(8,-6,-2):=true;
	iswall(8,-6,-1):=true;
	iswall(8,-6,0):=true;
	iswall(8,-6,1):=true;
	iswall(8,-6,2):=true;


	-- +X wall:
	iswall(8,6,-6):=true;
	iswall(8,6,-5):=true;
	iswall(8,6,-4):=true;
	iswall(8,6,-3):=true;
	iswall(8,6,-2):=true;
	iswall(8,6,-1):=true;
	iswall(8,6,0):=true;
	iswall(8,6,1):=true;
	iswall(8,6,2):=true;
	iswall(8,6,3):=true;
	iswall(8,6,4):=true;
	iswall(8,6,5):=true;
	iswall(8,6,6):=true;
	iswall(8,6,7):=true;
	iswall(8,6,8):=true;


	iswall(8,8,-8):=true;
	iswall(8,8,-7):=true;
	iswall(8,8,-6):=true;
	iswall(8,8,-5):=true;
	iswall(8,8,-4):=true;
	iswall(8,8,-3):=true;
	iswall(8,8,-2):=true;
	iswall(8,8,-1):=true;
	iswall(8,8,0):=true;
	iswall(8,8,1):=true;
	iswall(8,8,2):=true;
	iswall(8,8,3):=true;
	iswall(8,8,4):=true;
	iswall(8,8,5):=true;
	iswall(8,8,6):=true;
	iswall(8,8,7):=true;
	iswall(8,8,8):=true;
	iswall(8,8,9):=true;
	iswall(8,8,10):=true;

----- end vertical walls;  begin horizontal -------------

	iswall(8,-8,-8):=true;
	iswall(8,-7,-8):=true;
	iswall(8,-6,-8):=true;
	iswall(8,-5,-8):=true;
	iswall(8,-4,-8):=true;
	iswall(8,-3,-8):=true;
	iswall(8,-2,-8):=true;
	iswall(8,-1,-8):=true;
	iswall(8,0,-8):=true;
	iswall(8,1,-8):=true;
	iswall(8,2,-8):=true;
	iswall(8,3,-8):=true;
	iswall(8,4,-8):=true;
	iswall(8,5,-8):=true;
	iswall(8,6,-8):=true;
	iswall(8,7,-8):=true;
	iswall(8,8,-8):=true;

	iswall(8,-6,-6):=true;
	iswall(8,-5,-6):=true;
	iswall(8,-4,-6):=true;
	iswall(8,-3,-6):=true;
	iswall(8,-2,-6):=true;
	iswall(8,-1,-6):=true;
	iswall(8,0,-6):=true;
	iswall(8,1,-6):=true;
	iswall(8,2,-6):=true;
	iswall(8,3,-6):=true;
	iswall(8,4,-6):=true;
	iswall(8,5,-6):=true;
	iswall(8,6,-6):=true;


	iswall(8,-8,4):=true;
	iswall(8,-7,4):=true;
	iswall(8,-6,4):=true;
	iswall(8,-5,4):=true;
	iswall(8,-4,4):=true;
	iswall(8,-3,4):=true;
	iswall(8,-2,4):=true;
	iswall(8,-1,4):=true;
	iswall(8, 0,4):=true;
	iswall(8, 1,4):=true;
	iswall(8, 2,4):=true;
	iswall(8, 3,4):=true;
	iswall(8, 4,4):=true;


	iswall(8,-10,6):=true;
	iswall(8,-9,6):=true;
	iswall(8,-8,6):=true;
	iswall(8,-7,6):=true;
	iswall(8,-6,6):=true;
	iswall(8,-5,6):=true;
	iswall(8,-4,6):=true;
	iswall(8,-3,6):=true;
	iswall(8,-2,6):=true;
	iswall(8,-1,6):=true;
	iswall(8, 0,6):=true;
	iswall(8, 1,6):=true;
	iswall(8, 2,6):=true;
	iswall(8, 3,6):=true;
	iswall(8, 4,6):=true;
	iswall(8, 5,6):=true;
	iswall(8, 6,6):=true;


	iswall(8,-8,8):=true;
	iswall(8,-7,8):=true;
	iswall(8,-6,8):=true;
	iswall(8,-5,8):=true;
	iswall(8,-4,8):=true;
	iswall(8,-3,8):=true;
	iswall(8,-2,8):=true;
	iswall(8,-1,8):=true;
	iswall(8, 0,8):=true;
	iswall(8, 1,8):=true;
	iswall(8, 2,8):=true;
	iswall(8, 3,8):=true;
	iswall(8, 4,8):=true;
	iswall(8, 5,8):=true;
	iswall(8, 6,8):=true;

	iswall(8, 8,8):=true;
	iswall(8, 9,8):=true;
	iswall(8,10,8):=true;




end initializeNewMazes;

-- note transition table below

-- scene		no		so		ea									we

-- 	5		x		in		6Y(5,-10,9)->(6,+10,-4)		6C(5,10,9)->(6,-10,9)
-- 	5		x		in		6Z(5,-10,4)->(6,+10,-9)		6D(5,10,4)->(6,-10,4)

-- 	5		x		in		6V(5,-10,2)->(6,+10,2)		6E(5,+10,2)->(6,-10,2)
-- 	5		x		in		6W(5,-10,0)->(6,+10,0)		6F(5,+10,0)->(6,-10,0)
-- 	5		x		in		6X(5,-10,-2)->(6,+10,-2)	6G(5,+10,-2)->(6,-10,-2)



--		6		out	x		5C(6,-10,9)->(5,+10,9)		6A(6,+10,+9)->(6,-10,-4)
--		6		out	x		5D(6,-10,4)->(5,+10,4)		6B(6,+10,+4)->(6,-10,-9)

--		6		out	x		5E(6,-10,2)->(5,+10,2)		5V(6,+10,+2)->(5,-10,+2)
--		6		out	x		5F(6,-10,0)->(5,+10,0)		5W(6,+10,0)->(5,-10,0)
--		6		out	x		5G(6,-10,-2)->(5,+10,-2)	5X(6,+10,-2)->(5,-10,-2)

--		6		out	x		6A(6,-10,-4)->(6,+10,+9)	5Y(6,+10,-4)->(5,-10,+9)
--		6		out	x		6B(6,-10,-9)->(6,+10,+4)	5Z(6,+10,-9)->(5,-10,+4)

-- denote transition ID by (ea/we, initial-scene, letter):
--
-- {ea,we} + {5,6} + {a,b,c,d,e,f,g, v,w,x,y,z}
-- so ...
-----------------------------------------
-- ea5y: x+20, z-13
-- ea5z: x+20, z-13
-- ea5v: x+20
-- ea5w: x+20
-- ea5x: x+20
--
-- we5c: x-20
-- we5d: x-20
-- we5e: x-20
-- we5f: x-20
-- we5g: x-20
----------------------------------
-- ea6c: x+20
-- ea6d: x+20
-- ea6e: x+20
-- ea6f: x+20
-- ea6g: x+20
-- ea6a: x+20, z+13
-- ea6b: x+20, z+13
--
-- we6a: x-20, z-13
-- we6b: x-20, z-13
-- we6v: x-20
-- we6w: x-20
-- we6x: x-20
-- we6y: x-20, z+13
-- we6z: x-20, z+13








function snakehiss return boolean is
	tooclose : constant float := 1.0;
	dist : float;
begin

	if scene=7 then
	  dist:=sqr(x7snake-xme)+sqr(z7snake-zme);
	elsif scene=8 then
	  dist:=sqr(x8snake-xme)+sqr(z8snake-zme);
	elsif scene=6 then
	  dist:=sqr(x6snake-xme)+sqr(z6snake-zme);
	elsif scene=5 then
	  dist:=sqr(x5snake-xme)+sqr(z5snake-zme);
	else
		dist:=999.0;
	end if;

	if dist<4.0*tooclose*tooclose then
		return true;
	else
		return false;
	end if;

end snakehiss;




function nearsnake return boolean is
	tooclose : constant float := 1.0;
	dist : float;
begin

	if scene=7 then
	  dist:=sqr(x7snake-xme)+sqr(z7snake-zme);
	elsif scene=8 then
	  dist:=sqr(x8snake-xme)+sqr(z8snake-zme);
	elsif scene=6 then
	  dist:=sqr(x6snake-xme)+sqr(z6snake-zme);
	elsif scene=5 then
	  dist:=sqr(x5snake-xme)+sqr(z5snake-zme);
	else
		dist:=999.0;
	end if;

	if dist<tooclose*tooclose then
		return true;
	else
		return false;
	end if;

end nearsnake;



-- for when we have to draw objects in order from far to near
-- note that bubble sort is actually very efficient for short lists.
procedure sort( 
	f2n: in out sortarray;  -- output permutations
	ox,oz : limarray;       -- pos of each object
	lo, hi : integer;       -- bounds of sort
	eyex,eyez : float       -- xme, zme
	) is

	isave : integer;
	di, dj : float;
begin

	myassert( lo>=nsortrng'first, 977 );
	myassert( hi<=nsortrng'last, 976  );

	for i in lo..hi loop
		f2n(i):=i; -- initialize permutation
	end loop;

	for i in reverse lo..hi loop
		for j in 1..i loop

			di := sqr( ox( f2n(i) ) - eyex ) + sqr( oz( f2n(i) ) - eyez );
			dj := sqr( ox( f2n(j) ) - eyex ) + sqr( oz( f2n(j) ) - eyez );
			if( di > dj ) then -- swap i,j
				isave:=f2n(i);
				f2n(i):=f2n(j);
				f2n(j):=isave;
			end if;

		end loop; -- for j
	end loop; -- for i

end sort;














procedure emptyGLerrorQueue is
	use gl.binding;
begin
	while glGetError /= gl_no_error loop
		null;
	end loop;
end emptyGLerrorQueue;



function dumpGLerrorQueue(id: string) return integer is
	use gl.binding;
	errno: interfaces.c.unsigned;
	isAnError: boolean;
	ercount: integer := 0;
begin
	isAnError:=false;
	loop
		errno:=glGetError;
		exit when errno=gl_no_error;
		ercount:=ercount+1;
		isAnError:=true;
		put("GLerror=");
		put(interfaces.c.unsigned'image(errno));
		new_line;
	end loop;
	if isAnError then
		put_line("...@ id="&id);
	end if;
	return ercount;
end dumpGLerrorQueue;
--
-- 16#0#   =    0 = no_error
-- 16#500# = 1280 = invalid_enum
-- 16#501# = 1281 = invalid_value
-- 16#502# = 1282 = invalid_operation ?reusing uniformID?
-- 16#503# = 1283 = stack_overflow
-- 16#504# = 1284 = stack_underflow
-- 16#505# = 1285 = out_of_memory
--








-------------- begin generic crossing function ----------
oldcrossing: float := 0.0;

--function atThreshold(	
--	timenow, xx,zz, passdir: float; 
--	sene: integer ) return boolean is

function atThreshold(	
	timenow: float; 
	str: string;
	sene: integer ) return boolean is

	near: constant float := here;
	dist : float;
	dt : float := timenow - oldcrossing;
	dirOk: boolean := false;

	mazr: mazeRec;
	xx,zz,passdir: float;
begin


	mazr:=mtab.find(str);
	xx:=mazr.x;
	zz:=mazr.z;
	passdir:=mazr.dir;

--put("@threshold: (xme,zme)=("&float'image(xme)&","&float'image(zme));
--new_line;
--put("@threshold: (xx,zz)=("&float'image(xx)&","&float'image(zz));
--new_line;
--put(", scene="&integer'image(sene)&", dir="&float'image(passdir));
--new_line;

	-- check velocity direction
	if abs(mindifangl(veldir-passdir))<fourthpi then
		dirOk:=true;
	else
		dirOk:=false;
	end if;

	if dt>repassage then
		if (scene/=sene) then return false;
		else
			dist := safeSqrt( sqr(xx-xme) + sqr(zz-zme) );
			if dist<near and dirOk then
				oldcrossing:=timenow;
				return true;
			else
				return false;
			end if;
		end if;
	else
		return false;
	end if;

end atThreshold;



procedure showWhatIsHeld is
begin

		-- glyphs drawn @ screen center
			showingGlyph:=false;

		if gateheld then
			if insertable>0 then
				utex.print2d(gatner,0.5,0.5,50); -- "^" => gateway
			else
				utex.print2d(gatfar,0.5,0.5,50); -- "^" => gateway
			end if;
			showingGlyph:=true;

		elsif gkeyheld then --draw key
			utex.print2d(grekey,0.5,0.5,50); -- "^" => green key
			showingGlyph:=true;

		elsif wkeyheld then --draw key
			utex.print2d(whikey,0.5,0.5,50); -- "~" => white key
			showingGlyph:=true;

		elsif bkeyheld then --draw key
			utex.print2d(blakey,0.5,0.5,50); -- "|" => black key
			showingGlyph:=true;

		elsif swordheld then --draw sword
			utex.print2d(csword,0.5,0.5,120); -- "=" => sword
			showingGlyph:=true;

		elsif chaliceheld then --draw chalice
			utex.print2d(chalis,0.5,0.5,80); -- ";" => chalice
			showingGlyph:=true;
		end if;

		if 
			(pgatenear or gkeynear or bkeynear or 
			 wkeynear or swordnear or chalicenear)
			and not gatewait and not lionwait and not mazewait
		then
			utex.print2d(hand,0.5,0.4,80); -- "`" = hand
			showingHand:=true;
		else
			showingHand:=false;
		end if;


end showWhatIsHeld;





-- purple portal thru maze wall:
procedure insertgate( k: integer ) is
begin

	kgate:=k;
	rgate:=korow(k);
	cgate:=kocol(k);
	sgate:=koscene(k);

	xgate:=0.5*(koxhi(k)+koxlo(k));
	zgate:=0.5*(kozhi(k)+kozlo(k));
	ygate:=0.5*(koyhi(k)+koylo(k));

end insertgate;





procedure updateBull( --28may18
	mytime, xme,zme: float;
	xm,ym,zm,am: in out float;
	idir: out integer;
	collide: out boolean
	) is

	dt : float := mytime-bulltime;

	odx,odz, oxluk,ozluk,
	ndx,ndz,nam,dam,
	oam,oxm,oym,ozm,
	xluk,zluk,dx,dz,hdist: float;

	xtrip: constant float := -5.0;
	ztrip: constant float := +3.0;
	dtrip: constant float := 0.5;

	closeEnough: constant float := 0.7;

	arenaMinx: constant float := -5.0;
	arenaMinz: constant float := -5.0;
	arenaMaxx: constant float := +5.0;
	arenaMaxz: constant float := +3.0;

begin

	ym:=-iymax;

	collide:=false;
	if not minorun or minotaurdead then
		idir:=0;
	else
		idir:=1;
	end if;
	bulltime:=mytime;

	oam:=mindifangl(am);
	oxm:=xm;
	oym:=ym;
	ozm:=zm;

	oxluk:=fmath.sin(am);
	ozluk:=fmath.cos(am);
	odx:=dt*0.7*speed*oxluk;
	odz:=dt*0.7*speed*ozluk;

	dx:=xme-xm;
	dz:=zme-zm;
	hdist:=fmath.sqrt(dx*dx+dz*dz);
	xluk:=dx/hdist;
	zluk:=dz/hdist;
	nam:=mindifangl(fmath.arctan(xluk,zluk));

	dam := mindifangl(nam-oam);
	oam := nam-dam;

	ndx:=dt*0.7*speed*xluk;
	ndz:=dt*0.7*speed*zluk;

	dx:=0.98*odx+0.02*ndx; --gradually [2%] change
	dz:=0.98*odz+0.02*ndz; --direction toward
	am:=0.98*oam+0.02*nam; --avatar

	if idir>0 then
		xm:=xm+dx;
		zm:=zm+dz;


		if xm<arenaMinx then
			xm:=arenaMinx;
		elsif xm>arenaMaxx then
			xm:=arenaMaxx;
		end if;


		if zm<arenaMinz then
			zm:=arenaMinz;
		elsif zm>arenaMaxz then
			zm:=arenaMaxz;
		end if;


	end if;


	--distance between minotaur, avatar:
	hdist:= fmath.sqrt( sqr(xm-xme)+sqr(zm-zme) );

	-- test for stopping conditions
	if
		( hdist < closeEnough )
	then
		idir:=0;
		xm:=oxm;
		zm:=ozm;
		collide:=true;
	end if;


	if minotaurdead then
		idir:=0;
		xm:=oxm;
		zm:=ozm;
	end if;




end updateBull;





procedure drawBull( 
	mytime, xb,yb,zb,hang : float;
	idir: integer
	) is
	use glext.binding;
	use gl.binding;
begin

	glUseProgram(pidbull14);
	glUniformMatrix4fv(imvp14, 1, GL_FALSE, imvp(1,1)'address);
	glUniform1f(hang14, glfloat(hang));
	glUniform1i(idir14, glint(idir));

	glUniform1f(time14, glfloat(mytime));
	glUniform3f(icen14, 
		glfloat(xb),glfloat(yb),glfloat(zb) );
	glUniform1i(samp14, 0);

	glbindtexture(gl_texture_2d, bull_texid);

	avatarolay.draw(bull, vertbuff,uvbuff,elembuff);

end drawBull;



--------- begin new state I/O procs 30oct19 ----------------
procedure printstate is
begin

	put(float'image(xme));
	put(float'image(yme));
	put(float'image(zme));
	new_line;

end printstate;


procedure writeState is
	sfil: text_io.file_type;
begin
	text_io.create(
		file=>sfil,
		name=>statefile,
		mode=>text_io.out_file);

	if drawchalice then put(sfil,"T"); else put(sfil,"F"); end if;
	if chalicegone  then put(sfil,"T"); else put(sfil,"F"); end if;
	if gateheld then put(sfil,"T"); else put(sfil,"F"); end if;
	if bkeyheld then put(sfil,"T"); else put(sfil,"F"); end if;
	if gkeyheld then put(sfil,"T"); else put(sfil,"F"); end if;
	if wkeyheld then put(sfil,"T"); else put(sfil,"F"); end if;
	if swordheld then put(sfil,"T"); else put(sfil,"F"); end if;
	if chaliceheld then put(sfil,"T"); else put(sfil,"F"); end if;
	if bdragondead then put(sfil,"T"); else put(sfil,"F"); end if;
	if rdragondead then put(sfil,"T"); else put(sfil,"F"); end if;
	if minotaurdead then put(sfil,"T"); else put(sfil,"F"); end if;
	if labopen then put(sfil,"T"); else put(sfil,"F"); end if;
	if mazeopen then put(sfil,"T"); else put(sfil,"F"); end if;
	if lionopen then put(sfil,"T"); else put(sfil,"F"); end if;
	if gateopen then put(sfil,"T"); else put(sfil,"F"); end if;
	if interior then put(sfil,"T"); else put(sfil,"F"); end if;

	if bat1sent then put(sfil,"T"); else put(sfil,"F"); end if;
	if bat5sent then put(sfil,"T"); else put(sfil,"F"); end if;

	if bat7sent then put(sfil,"T"); else put(sfil,"F"); end if;
	if bat9sent then put(sfil,"T"); else put(sfil,"F"); end if;

	if play9 then put(sfil,"T"); else put(sfil,"F"); end if;

	new_line(sfil);


	put_line(sfil, integer'image(chapter));
	put_line(sfil, integer'image(scene));
	put_line(sfil, integer'image(schalice));
	put_line(sfil, integer'image(sbkey));
	put_line(sfil, integer'image(sgkey));
	put_line(sfil, integer'image(swkey));
	put_line(sfil, integer'image(ssword));
	put_line(sfil, integer'image(kgate));
	put_line(sfil, integer'image(sgate));
	put_line(sfil, integer'image(rgate));
	put_line(sfil, integer'image(cgate));

	put_line(sfil, integer'image(bsdra));
	put_line(sfil, integer'image(rsdra));

	--put_line(sfil, integer'image(gk1));
	--put_line(sfil, integer'image(gzmk));

-----------------------------------------------------
	put_line(sfil, float'image(xchalice));
	put_line(sfil, float'image(ychalice));
	put_line(sfil, float'image(zchalice));

	put_line(sfil, float'image(xme));
	put_line(sfil, float'image(yme));
	put_line(sfil, float'image(zme));

	put_line(sfil, float'image(xgate));
	put_line(sfil, float'image(ygate));
	put_line(sfil, float'image(zgate));

	put_line(sfil, float'image(xbkey));
	put_line(sfil, float'image(ybkey));
	put_line(sfil, float'image(zbkey));

	put_line(sfil, float'image(xgkey));
	put_line(sfil, float'image(ygkey));
	put_line(sfil, float'image(zgkey));

	put_line(sfil, float'image(xwkey));
	put_line(sfil, float'image(ywkey));
	put_line(sfil, float'image(zwkey));




	put_line(sfil, float'image(rxdra));
	put_line(sfil, float'image(rydra));
	put_line(sfil, float'image(rzdra));

	put_line(sfil, float'image(bxdra));
	put_line(sfil, float'image(bydra));
	put_line(sfil, float'image(bzdra));

	put_line(sfil, float'image(mxdra));
	put_line(sfil, float'image(mydra));
	put_line(sfil, float'image(mzdra));


	put_line(sfil, float'image(xsword));
	put_line(sfil, float'image(ysword));
	put_line(sfil, float'image(zsword));






	text_io.close(sfil);

	--printstate;

end writeState;

procedure readState is
	linestr: string(1..30);
	last: natural;
	bstr: string(1..21);
	fstate: float;
	istate: integer;
	sfil: text_io.file_type;
begin
	text_io.open(
		file=>sfil,
		name=>statefile,
		mode=>text_io.in_file);

	get_line(sfil, bstr, last); --boolean array
	skip_line(sfil);


	if bstr(1)='T'  then drawchalice:=true; else drawchalice:=false; end if;
	if bstr(2)='T'  then chalicegone:=true; else chalicegone:=false; end if;
	if bstr(3)='T'  then gateheld:=true; else gateheld:=false; end if;
	if bstr(4)='T'  then bkeyheld:=true; else bkeyheld:=false; end if;
	if bstr(5)='T'  then gkeyheld:=true; else gkeyheld:=false; end if;
	if bstr(6)='T'  then wkeyheld:=true; else wkeyheld:=false; end if;
	if bstr(7)='T'  then swordheld:=true; else swordheld:=false; end if;
	if bstr(8)='T'  then chaliceheld:=true; else chaliceheld:=false; end if;
	if bstr(9)='T'  then bdragondead:=true; else bdragondead:=false; end if;
	if bstr(10)='T' then rdragondead:=true; else rdragondead:=false; end if;
	if bstr(11)='T' then minotaurdead:=true; else minotaurdead:=false; end if;
	if bstr(12)='T' then labopen:=true; else labopen:=false; end if;
	if bstr(13)='T' then mazeopen:=true; else mazeopen:=false; end if;
	if bstr(14)='T' then lionopen:=true; else lionopen:=false; end if;
	if bstr(15)='T' then gateopen:=true; else gateopen:=false; end if;
	if bstr(16)='T' then interior:=true; else interior:=false; end if;

	if bstr(17)='T' then bat1sent:=true; else bat1sent:=false; end if;
	if bstr(18)='T' then bat5sent:=true; else bat5sent:=false; end if;

	if bstr(19)='T' then bat7sent:=true; else bat7sent:=false; end if;
	if bstr(20)='T' then bat9sent:=true; else bat9sent:=false; end if;

	if bstr(21)='T' then play9:=true; else play9:=false; end if;

--put("ok @ 4218");
--new_line;

	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	chapter:=istate;

	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	scene:=istate;

	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	schalice:=istate;


	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	sbkey:=istate;


	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	sgkey:=istate;


	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	swkey:=istate;


	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	ssword:=istate;


	get_line(sfil, linestr, last); --integer
	myint_io.get(linestr(1..last),istate,last);
	kgate:=istate;


	get_line(sfil, linestr, last); --integer (gate scene)
	myint_io.get(linestr(1..last),istate,last);
	sgate:=istate;


	get_line(sfil, linestr, last); --integer (gate row)
	myint_io.get(linestr(1..last),istate,last);
	rgate:=istate;


	get_line(sfil, linestr, last); --integer (gate col)
	myint_io.get(linestr(1..last),istate,last);
	cgate:=istate;


	get_line(sfil, linestr, last); --integer (gate col)
	myint_io.get(linestr(1..last),istate,last);
	bsdra:=istate;


	get_line(sfil, linestr, last); --integer (gate col)
	myint_io.get(linestr(1..last),istate,last);
	rsdra:=istate;



----------------------------------------------------------
	--chalice

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xchalice:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	ychalice:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zchalice:=fstate;

	--me

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xme:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	yme:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zme:=fstate;

	--gate

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xgate:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	ygate:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zgate:=fstate;

	--Bkey

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xbkey:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	ybkey:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zbkey:=fstate;


	--Gkey

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xgkey:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	ygkey:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zgkey:=fstate;

	--Wkey

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xwkey:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	ywkey:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zwkey:=fstate;



	--Rdra

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	rxdra:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	rydra:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	rzdra:=fstate;


	--Bdra

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	bxdra:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	bydra:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	bzdra:=fstate;



	--Mdra

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	mxdra:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	mydra:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	mzdra:=fstate;







	--sword
	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	xsword:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	ysword:=fstate;

	get_line(sfil, linestr, last); --float
	myfloat_io.get(linestr(1..last), fstate,last);
	zsword:=fstate;



-----------------------------------------------------------------
	text_io.close(sfil);

	--printstate;


end readState;

procedure setState is
begin

	if bdragondead then
				pictobj.setrect( 
					bdragon, 
					bxdra,bydra,bzdra,
					0.6, 0.0, 0.6, --xr,yr,zr
					j1,j2,j3,j4,j5,j6);
	end if;

	if rdragondead then
				pictobj.setrect( 
					rdragon, 
					rxdra,rydra,rzdra,
					0.6, 0.0, 0.6, --xr,yr,zr
					j1,j2,j3,j4,j5,j6);
	end if;

	if not bkeyheld then

		pictobj.setrect( 
			key2, 
			xbkey,ybkey,zbkey, --xc,yc,zc
			0.1, 0.0, 0.1, --xr,yr,zr
			j1,j2,j3,j4,j5,j6);

	end if;

	if not gkeyheld then

		pictobj.setrect( 
			key3, 
			xgkey,ygkey,zgkey, --xc,yc,zc
			0.1, 0.0, 0.1, --xr,yr,zr
			j1,j2,j3,j4,j5,j6);

	end if;

	if not wkeyheld then

		pictobj.setrect( 
			key1, 
			xwkey,ywkey,zwkey, --xc,yc,zc
			0.1, 0.0, 0.1, --xr,yr,zr
			j1,j2,j3,j4,j5,j6);

	end if;

	if not swordheld then

		pictobj.setrect( 
			sword, 
			xsword,ysword,zsword,
			rsword, 0.0, 0.2*rsword,
			j1,j2,j3,j4,j5,j6);


	end if;

	if not chaliceheld then
		null;
	end if;

	if not gateheld then

			pictobj.setrect( 
				gateway, 
				xgate,ygate,zgate, --xc,yc,zc
				0.2, 0.0, 0.2, --xr,yr,zr
				j1,j2,j3,j4,j5,j6);

	end if;

	if 
		lionopen 
		and (chapter=1 or chapter=3)
	then

			pictobj.setrect( 
				dungdoor,
				xlion, -iymax+1.8*1.3, zlion,
				0.8-0.05, 0.9, 0.05,
				j1,j2,j3,j4,j5,j6);

			--disable KO #lko
			koxlo(lko):=0.0;
			koxhi(lko):=0.0;
			koylo(lko):=0.0;
			koyhi(lko):=0.0;
			kozlo(lko):=0.0;
			kozhi(lko):=0.0;


	end if;

	if 
		labopen 
		and (chapter=2 or chapter=4)
	then

			pictobj.setrect( 
				sh7,
				xlab,ylab-0.9,zlab,
				0.0, 0.9*0.5, 0.8*0.46,
				j1,j2,j3,j4,j5,j6);

			--disable KO
			koxlo(wlabko):=0.0;
			koxhi(wlabko):=0.0;
			koylo(wlabko):=0.0;
			koyhi(wlabko):=0.0;
			kozlo(wlabko):=0.0;
			kozhi(wlabko):=0.0;


	end if;

	if mazeopen then

			pictobj.setrect( 
				gatem1, 
				xmaze, ymaze+0.6, zmaze-0.3, --xc,yc,zc
				0.3, 0.3, 0.01, --xr,yr,zr
				koxlo(gk1),koxhi(gk1),koylo(gk1),
				koyhi(gk1),kozlo(gk1),kozhi(gk1) );
			--koylo(gk1):=20.0;
			--koyhi(gk1):=21.0;
	
	end if;


	if gateopen then --castleGate

			pictobj.setrect( 
				gatezm, 
				-5.0, 1.1, -10.2, --xc,yc,zc
				0.4, 0.4, 0.0, --xr,yr,zr
				koxlo(gzmk),koxhi(gzmk),koylo(gzmk),
				koyhi(gzmk),kozlo(gzmk),kozhi(gzmk) );
			--koylo(gzmk):=20.0;
			--koyhi(gzmk):=19.0;
	
	end if;





end setState;


end gameutils;



