diff options
| -rw-r--r-- | engines/avalanche/trip6.cpp | 1491 | ||||
| -rw-r--r-- | engines/avalanche/trip6.h | 227 | 
2 files changed, 1718 insertions, 0 deletions
| diff --git a/engines/avalanche/trip6.cpp b/engines/avalanche/trip6.cpp new file mode 100644 index 0000000000..ac0e8d0609 --- /dev/null +++ b/engines/avalanche/trip6.cpp @@ -0,0 +1,1491 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 2 + * 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 should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This code is based on the original source code of Lord Avalot d'Argent version 1.3. + * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. + */ + +/* TRIP5	Trippancy V */ + +#include "avalanche/trip6.h" +#include "common/scummsys.h" +#include "common/textconsole.h" + +#include "avalanche/scrolls2.h" +#include "avalanche/lucerna2.h" +#include "avalanche/visa2.h" +#include "avalanche/gyro2.h" +#include "avalanche/celer2.h" +#include "avalanche/sequence2.h" +#include "avalanche/timeout2.h" +#include "avalanche/enid2.h" + +/*#include "Dropdown.h"*/ + + +namespace Avalanche { + +	namespace Trip { + +	void loadtrip() { +		byte gm; + +		for (gm = 1; gm <= numtr; gm ++) tr[gm].original(); +		for (int i = 0; i < sizeof(aa); aa[i] = 0); +	} + +	byte checkfeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl) { +		byte a, c; +		int16 fv, ff; + +		/* if not alive then begin checkfeet:=0; exit; end;*/ +		byte checkfeet_result; +		a = 0; + +		warning("STUB: Trip::checkfeet()"); +		 +		checkfeet_result = a; +		return checkfeet_result; +	} + +	byte geida_ped(byte which) { +		byte geida_ped_result; +		switch (which) { +		case 1: +			geida_ped_result = 7; +			break; +		case 2: +		case 6: +			geida_ped_result = 8; +			break; +		case 3: +		case 5: +			geida_ped_result = 9; +			break; +		case 4: +			geida_ped_result = 10; +			break; +		} +		return geida_ped_result; +	} + +	void catamove(byte ped) +	/* When you enter a new position in the catacombs, this procedure should +	  be called. It changes the Also codes so that they may match the picture +	  on the screen. (Coming soon: It draws up the screen, too.) */ +	{ + +		warning("Repair array indexes in Trip::catamove()"); + +		int32 here; +		uint16 xy_uint16; +		byte fv, ff; + +		/* XY_uint16 is cat_x+cat_y*256. Thus, every room in the +		  catacombs has a different number for it. */ + + +		 +		xy_uint16 = Gyro::dna.cat_x + Gyro::dna.cat_y * 256; +		Gyro::dna.geida_spin = 0; +		 +		switch (xy_uint16) { +		case 1801: { /* Exit catacombs */ +			fliproom(r__lustiesroom, 4); +			Scrolls::display("Phew! Nice to be out of there!"); +			return; +		} +		break; +		case 1033: { /* Oubliette */ +			fliproom(r__oubliette, 1); +			Scrolls::display("Oh, NO!\231\2"); +			return; +		} +		break; +		case 4: { +			fliproom(r__geidas, 1); +			return; +		} +		break; +		case 2307: { +			fliproom(r__lusties, 5); +			Scrolls::display("Oh no... here we go again..."); +			Gyro::dna.user_moves_avvy = false; +			tr[1].iy = 1; +			tr[1].ix = 0; +			return; +		} +		break; +		} + +		if (! Gyro::dna.enter_catacombs_from_lusties_room) Lucerna::load(29); +		here = Gyro::catamap[Gyro::dna.cat_y][Gyro::dna.cat_x]; + +		switch (here & 0xf) { /* West. */ +		case 0: { /* no connection (wall) */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::nix; /* Door. */ +			Celer::show_one(28); +		} +		break; +		case 0x1: { /* no connection (wall + shield), */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::nix; /* Door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(29); /* ...shield. */ +		} +		break; +		case 0x2: { /* wall with door */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::special; /* Door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(30); /* ...door. */ +		} +		break; +		case 0x3: { /* wall with door and shield */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::special; /* Door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(30); /* ...door, and... */ +			Celer::show_one(29); /* ...shield. */ +		} +		break; +		case 0x4: { /* no connection (wall + window), */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::nix; /* Door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(5);  /* ...window. */ +		} +		break; +		case 0x5: { /* wall with door and window */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::special; /* Door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(30); /* ...door, and... */ +			Celer::show_one(5); /* ...window. */ +		} +		break; +		case 0x6: { /* no connection (wall + torches), */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::nix; /* No door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(7); /* ...torches. */ +		} +		break; +		case 0x7: { /* wall with door and torches */ +			Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[13].op = Gyro::special; /* Door. */ +			Celer::show_one(28); /* Wall, plus... */ +			Celer::show_one(30); /* ...door, and... */ +			Celer::show_one(7); /* ...torches. */ +		} +		break; +		case 0xf: { /* straight-through corridor. */ +			Gyro::magics[2].op = Gyro::nix; /* Sloping wall. */ +			Gyro::magics[3].op = Gyro::special; /* Straight wall. */ +		} +		break; +		} + +		/*  ---- */ + +		switch ((here & 0xf0) >> 4) { /* East */ +		case 0: { /* no connection (wall) */ +			Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::nix; /* Door. */ +			Celer::show_one(19); +		} +		break; +		case 0x1: { /* no connection (wall + window), */ +			Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::nix; /* Door. */ +			Celer::show_one(19); /* Wall, plus... */ +			Celer::show_one(20); /* ...window. */ +		} +		break; +		case 0x2: { /* wall with door */ +			Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::special; /* Door. */ +			Celer::show_one(19); /* Wall, plus... */ +			Celer::show_one(21); /* ...door. */ +		} +		break; +		case 0x3: { /* wall with door and window */ +			Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::special; /* Door. */ +			Celer::show_one(19); /* Wall, plus... */ +			Celer::show_one(20); /* ...door, and... */ +			Celer::show_one(21); /* ...window. */ +		} +		break; +		case 0x6: { /* no connection (wall + torches), */ +			Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::nix; /* No door. */ +			Celer::show_one(19); /* Wall, plus... */ +			Celer::show_one(18); /* ...torches. */ +		} +		break; +		case 0x7: { /* wall with door and torches */ +			Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::special; /* Door. */ +			Celer::show_one(19); /* Wall, plus... */ +			Celer::show_one(21); /* ...door, and... */ +			Celer::show_one(18); /* ...torches. */ +		} +		break; +		case 0xf: { /* straight-through corridor. */ +			Gyro::magics[5].op = Gyro::nix; /* Sloping wall. */ +			Gyro::magics[6].op = Gyro::special; /* Straight wall. */ +			Gyro::portals[15].op = Gyro::nix; /* Door. */ +		} +		break; +		} + +		/*  ---- */ + +		switch ((here & 0xf00) >> 8) { /* South */ +		case 0: { /* No connection. */ +			Gyro::magics[7].op = Gyro::bounces; +			Gyro::magics[12].op = Gyro::bounces; +			Gyro::magics[13].op = Gyro::bounces; +		} +		break; +		case 0x1: { +			Celer::show_one(22); +			 +			if ((xy_uint16 == 2051) & (Gyro::dna.geida_follows)) +				Gyro::magics[13].op = Gyro::exclaim; +			else Gyro::magics[13].op = Gyro::special; /* Right exit south. */ + +			Gyro::magics[7].op = Gyro::bounces; +			Gyro::magics[12].op = Gyro::bounces; +		} +		break; +		case 0x2: { +			Celer::show_one(23); +			Gyro::magics[7].op = Gyro::special; /* Middle exit south. */ +			Gyro::magics[12].op = Gyro::bounces; +			Gyro::magics[13].op = Gyro::bounces; +		} +		break; +		case 0x3: { +			Celer::show_one(24); +			Gyro::magics[12].op = Gyro::special; /* Left exit south. */ +			Gyro::magics[7].op = Gyro::bounces; +			Gyro::magics[13].op = Gyro::bounces; +		} +		break; +		} + +		switch ((here & 0xf000) >> 12) { /* North */ +		case 0: { /* No connection */ +			Gyro::magics[1].op = Gyro::bounces; +			Gyro::portals[12].op = Gyro::nix; /* Door. */ +		} +		break; +		/* LEFT handles: */ +		/*  $1: begin +			  Celer::show_one(4); +			  Gyro::magics[1].op:=Gyro::bounces; { Left exit north. } { Change magic number! } +			  Gyro::portals[12].op:=Gyro::special; { Door. } +			 end;*/ +		case 0x2: { +			Celer::show_one(4); +			Gyro::magics[1].op = Gyro::bounces; /* Middle exit north. */ +			Gyro::portals[12].op = Gyro::special; /* Door. */ +		} +		break; +		/*  $3: begin +			  Celer::show_one(4); +			  Gyro::magics[1].op:=Gyro::bounces; { Right exit north. } { Change magic number! } +			  Gyro::portals[12].op:=Gyro::special; { Door. } +			 end; +		  { RIGHT handles: } +		  $4: begin +			  Celer::show_one(3); +			  Gyro::magics[1].op:=Gyro::bounces; { Left exit north. } { Change magic number! } +			  Gyro::portals[12].op:=Gyro::special; { Door. } +			 end;*/ +		case 0x5: { +			Celer::show_one(3); +			Gyro::magics[1].op = Gyro::bounces; /* Middle exit north. */ +			Gyro::portals[12].op = Gyro::special; /* Door. */ +		} +		break; +		/*  $6: begin +			  Celer::show_one(3); +			  Gyro::magics[1].op:=Gyro::bounces; { Right exit north. } +			  Gyro::portals[12].op:=Gyro::special; { Door. } +			 end;*/ +		/* ARCHWAYS: */ +		case 0x7: +		case 0x8: +		case 0x9: { +			Celer::show_one(6); + +			if (((here & 0xf000) >> 12) > 0x7)  Celer::show_one(31); +			if (((here & 0xf000) >> 12) == 0x9)  Celer::show_one(32); + +			Gyro::magics[1].op = Gyro::special; /* Middle arch north. */ +			Gyro::portals[12].op = Gyro::nix; /* Door. */ +		} +		break; +		/* DECORATIONS: */ +		case 0xd: { /* No connection + WINDOW */ +			Gyro::magics[1].op = Gyro::bounces; +			Gyro::portals[12].op = Gyro::nix; /* Door. */ +			Celer::show_one(14); +		} +		break; +		case 0xe: { /* No connection + TORCH */ +			Gyro::magics[1].op = Gyro::bounces; +			Gyro::portals[12].op = Gyro::nix; /* Door. */ +			Celer::show_one(8); +		} +		break; +		/* Recessed door: */ +		case 0xf: { +			Gyro::magics[1].op = Gyro::nix; /* Door to Geida's room. */ +			Celer::show_one(1); +			Gyro::portals[12].op = Gyro::special; /* Door. */ +		} +		break; +		} + +		switch (xy_uint16) { +		case 514: +			Celer::show_one(17); +			break;     /* [2,2] : "Art Gallery" sign over door. */ +		case 264: +			Celer::show_one(9); +			break;      /* [8,1] : "The Wrong Way!" sign. */ +		case 1797: +			Celer::show_one(2); +			break;      /* [5,7] : "Ite Mingite" sign. */ +		case 258: +			for (fv = 0; fv <= 2; fv ++) { /* [2,1] : Art gallery - pictures */ +				Celer::show_one_at(15, 130 + fv * 120, 70); +				Celer::show_one_at(16, 184 + fv * 120, 78); +			} +			break; +		case 1287: +			for (fv = 10; fv <= 13; fv ++) Celer::show_one(fv); +			break; /* [7,5] : 4 candles. */ +		case 776: +			Celer::show_one(10); +			break;     /* [8,3] : 1 candle. */ +		case 2049: +			Celer::show_one(11); +			break;     /* [1,8] : another candle. */ +		case 257: { +			Celer::show_one(12); +			Celer::show_one(13); +		} +		break; /* [1,1] : the other two. */ +		} + +		if ((Gyro::dna.geida_follows) & (ped > 0)) { +			triptype &with = tr[2]; + +			if (! with.quick)  /* If we don't already have her... */ +				tr[2].init(5, true); /* ...Load Geida. */ +			apped(2, geida_ped(ped)); +			tr[2].call_eachstep = true; +			tr[2].eachstep = procgeida_procs; +		} +	} + +	void call_special(uint16 which); + +	/* This proc gets called whenever you touch a line defined as Gyro::special. */ +	static void dawndelay() { +		Timeout::set_up_timer(2, Timeout::procdawn_delay, Timeout::reason_dawndelay); +	} + +	void call_special(uint16 which) { +		switch (which) { +		case 1: { /* Gyro::special 1: Room 22: top of stairs. */ +			Celer::show_one(1); +			Gyro::dna.brummie_stairs = 1; +			Gyro::magics[10].op = Gyro::nix; +			Timeout::set_up_timer(10, Timeout::procstairs, Timeout::reason_brummiestairs); +			stopwalking(); +			Gyro::dna.user_moves_avvy = false; +		} +		break; +		case 2: { /* Gyro::special 2: Room 22: bottom of stairs. */ +			Gyro::dna.brummie_stairs = 3; +			Gyro::magics[11].op = Gyro::nix; +			Gyro::magics[12].op = Gyro::exclaim; +			Gyro::magics[12].data = 5; +			Gyro::magics[4].op = Gyro::bounces; /* Now works as planned! */ +			stopwalking(); +			Visa::dixi('q', 26); +			Gyro::dna.user_moves_avvy = true; +		} +		break; +		case 3: { /* Gyro::special 3: Room 71: triggers dart. */ +			tr[1].bounce(); /* Must include that. */ + +			if (! Gyro::dna.arrow_triggered) { +				Gyro::dna.arrow_triggered = true; +				apped(2, 4); /* The dart starts at ped 4, and... */ +				tr[2].walkto(5); /* flies to ped 5. */ +				tr[2].face = 0; /* Only face. */ +				/* Should call some kind of Eachstep procedure which will deallocate +				  the sprite when it hits the wall, and replace it with the chunk +				  graphic of the arrow buried in the plaster. */ +				/* OK! */ +				tr[2].call_eachstep = true; +				tr[2].eachstep = procarrow_procs; +			} +		} +		break; + +		case 4: { /* This is the ghost room link. */ +			Lucerna::dusk(); +			tr[1].turn(right); /* you'll see this after we get back from bootstrap */ +			Timeout::set_up_timer(1, Timeout::procghost_room_phew, Timeout::reason_ghost_room_phew); +			Enid::back_to_bootstrap(3); +		} +		break; + +		case 5: +			if (Gyro::dna.friar_will_tie_you_up) { +				/* Gyro::special 5: Room 42: touched tree, and get tied up. */ +				Gyro::magics[4].op = Gyro::bounces; /* Boundary effect is now working again. */ +				Visa::dixi('q', 35); +				tr[1].done(); +				/*tr[1].vanishifstill:=true;*/ +				Celer::show_one(2); +				Visa::dixi('q', 36); +				Gyro::dna.tied_up = true; +				Gyro::dna.friar_will_tie_you_up = false; +				tr[2].walkto(3); +				tr[2].vanishifstill = true; +				tr[2].check_me = true; /* One of them must have Check_Me switched on. */ +				Gyro::whereis[Gyro::pfriartuck] = 177; /* Not here, then. */ +				Timeout::set_up_timer(364, Timeout::prochang_around, Timeout::reason_hanging_around); +			} +			break; + +		case 6: { /* Gyro::special 6: fall down oubliette. */ +			Gyro::dna.user_moves_avvy = false; +			tr[1].ix = 3; +			tr[1].iy = 0; +			tr[1].face = right; +			Timeout::set_up_timer(1, Timeout::procfall_down_oubliette, Timeout::reason_falling_down_oubliette); +		} +		break; + +		case 7: { /* Gyro::special 7: stop falling down oubliette. */ +			tr[1].visible = false; +			Gyro::magics[10].op = Gyro::nix; +			stopwalking(); +			Timeout::lose_timer(Timeout::reason_falling_down_oubliette); +			Lucerna::mblit(12, 80, 38, 160, 3, 0); +			Lucerna::mblit(12, 80, 38, 160, 3, 1); +			Scrolls::display("Oh dear, you seem to be down the bottom of an oubliette."); +			Timeout::set_up_timer(200, Timeout::procmeet_avaroid, Timeout::reason_meeting_avaroid); +		} +		break; + +		case 8:        /* Gyro::special 8: leave du Lustie's room. */ +			if ((Gyro::dna.geida_follows) && (! Gyro::dna.lustie_is_asleep)) { +				Visa::dixi('q', 63); +				tr[2].turn(down); +				tr[2].stopwalk(); +				tr[2].call_eachstep = false; /* Geida */ +				Lucerna::gameover(); +			} +			break; + +		case 9: { /* Gyro::special 9: lose Geida to Robin Hood... */ +			if (! Gyro::dna.geida_follows)  return;   /* DOESN'T COUNT: no Geida. */ +			tr[2].call_eachstep = false; /* She no longer follows Avvy around. */ +			tr[2].walkto(4); /* She walks to somewhere... */ +			tr[1].done();     /* Lose Avvy. */ +			Gyro::dna.user_moves_avvy = false; +			Timeout::set_up_timer(40, Timeout::procrobin_hood_and_geida, Timeout::reason_robin_hood_and_geida); +		} +		break; + +		case 10: { /* Gyro::special 10: transfer north in catacombs. */ +			if ((Gyro::dna.cat_x == 4) && (Gyro::dna.cat_y == 1)) { +				/* Into Geida's room. */ +				if (Gyro::dna.obj[Gyro::key])  Visa::dixi('q', 62); +				else { +					Visa::dixi('q', 61); +					return; +				} +			} +			Lucerna::dusk(); +			Gyro::dna.cat_y -= 1; +			catamove(4); +			if (Gyro::dna.room != r__catacombs)  return; +			Lucerna::delavvy(); +			switch ((Gyro::catamap[Gyro::dna.cat_y][Gyro::dna.cat_x] & 0xf00) >> 8) { +			case 0x1: +				apped(1, 12); +				break; +			case 0x3: +				apped(1, 11); +				break; +			default: +				apped(1, 4); +			} +			getback(); +			dawndelay(); +		} +		break; +		case 11: { /* Gyro::special 11: transfer east in catacombs. */ +			Lucerna::dusk(); +			Gyro::dna.cat_x += 1; +			catamove(1); +			if (Gyro::dna.room != r__catacombs)  return; +			Lucerna::delavvy(); +			apped(1, 1); +			getback(); +			dawndelay(); +		} +		break; +		case 12: { /* Gyro::special 12: transfer south in catacombs. */ +			Lucerna::dusk(); +			Gyro::dna.cat_y += 1; +			catamove(2); +			if (Gyro::dna.room != r__catacombs)  return; +			Lucerna::delavvy(); +			apped(1, 2); +			getback(); +			dawndelay(); +		} +		break; +		case 13: { /* Gyro::special 13: transfer west in catacombs. */ +			Lucerna::dusk(); +			Gyro::dna.cat_x -= 1; +			catamove(3); +			if (Gyro::dna.room != r__catacombs)  return; +			Lucerna::delavvy(); +			apped(1, 3); +			getback(); +			dawndelay(); +		} +		break; +		} +	} + +	void hide_in_the_cupboard(); + +	void open_the_door(byte whither, byte ped, byte magicnum) +	/* This slides the door open. (The data really ought to be saved in +	  the Also file, and will be next time. However, for now, they're +	  here.) */ +	{ +		switch (Gyro::dna.room) { +		case r__outsideyours: +		case r__outsidenottspub: +		case r__outsideducks: { +			Sequence::first_show(1); +			Sequence::then_show(2); +			Sequence::then_show(3); +		} +		break; +		case r__insidecardiffcastle: { +			Sequence::first_show(1); +			Sequence::then_show(5); +		} +		break; +		case r__avvysgarden: +		case r__entrancehall: +		case r__insideabbey: { +			Sequence::first_show(1); +			Sequence::then_show(2); +		} +		break; +		case r__musicroom: +		case r__outsideargentpub: { +			Sequence::first_show(5); +			Sequence::then_show(6); +		} +		break; +		case r__lusties: +			switch (magicnum) { +			case 14: +				if (Gyro::dna.avvys_in_the_cupboard) { +					hide_in_the_cupboard(); +					Sequence::first_show(8); +					Sequence::then_show(7); +					Sequence::start_to_close(); +					return; +				} else { +					apped(1, 6); +					tr[1].face = right; /* added by TT 12/3/1995 */ +					Sequence::first_show(8); +					Sequence::then_show(9); +				} +				break; +			case 12: { +				Sequence::first_show(4); +				Sequence::then_show(5); +				Sequence::then_show(6); +			} +			break; +			} +			break; +		} + +		Sequence::then_flip(whither, ped); +		Sequence::start_to_open(); +	} + +	void newspeed() { +	/* Given that you've just changed the speed in triptype.xs, this adjusts +	  ix. */ +		warning("STUB: Trip::newspeed()"); +	} + +	triptype *triptype::init(byte spritenum, bool do_check) { +		warning("STUB: Trip::init()"); +		return this; +	} + +	void triptype::original() { +		quick = false; +		whichsprite = 177; +	} + +	void triptype::andexor() { +		warning("STUB: Trip::andexor()"); +	} + +	void triptype::turn(byte whichway) { +		if (whichway == 8)  face = 0; +		else face = whichway; +	} + +	void triptype::appear(int16 wx, int16 wy, byte wf) { +		x = (wx / 8) * 8; +		y = wy; +		ox[Gyro::cp] = wx; +		oy[Gyro::cp] = wy; +		turn(wf); +		visible = true; +		ix = 0; +		iy = 0; +	} + + + + +	bool triptype::collision_check() { +		byte fv; + +		bool collision_check_result; +		for (fv = 1; fv <= numtr; fv ++) +			if (tr[fv].quick && (tr[fv].whichsprite != whichsprite) && +					((x + a.xl) > tr[fv].x) && +					(x < (tr[fv].x + tr[fv].a.xl)) && +					(tr[fv].y == y)) { +				collision_check_result = true; +				return collision_check_result; +			} +		collision_check_result = false; +		return collision_check_result; +	} + +	void triptype::walk() { +		warning("STUB: Trip::walk()"); +	} + +	void triptype::bounce() { +		x = ox[Gyro::cp]; +		y = oy[Gyro::cp]; +		if (check_me)  stopwalking(); +		else stopwalk(); +		Gyro::oncandopageswap = false; +		Lucerna::showrw(); +		Gyro::oncandopageswap = true; +	} + +	int8 sgn(int16 x) { +		int8 sgn_result; +		if (x > 0)  sgn_result = 1; +		else if (x < 0)  sgn_result = -1; +		else +			sgn_result = 0; /* x=0 */ +		return sgn_result; +	} + +	void triptype::walkto(byte pednum) { +		speed(sgn(Gyro::peds[pednum].x - x) * 4, sgn(Gyro::peds[pednum].y - y)); +		hx = Gyro::peds[pednum].x - a.xl / 2; +		hy = Gyro::peds[pednum].y - a.yl; +		homing = true; +	} + +	void triptype::stophoming() { +		homing = false; +	} + +	void triptype::homestep() { +		int16 temp; + +		if ((hx == x) && (hy == y)) { +			/* touching the target */ +			stopwalk(); +			return; +		} +		ix = 0; +		iy = 0; +		if (hy != y) { +			temp = hy - y; +			if (temp > 4)  iy = 4; +			else if (temp < -4)  iy = -4; +			else iy = temp; +		} +		if (hx != x) { +			temp = hx - x; +			if (temp > 4)  ix = 4; +			else if (temp < -4)  ix = -4; +			else ix = temp; +		} +	} + +	void triptype::speed(int8 xx, int8 yy) { +		ix = xx; +		iy = yy; +		if ((ix == 0) && (iy == 0))  return; /* no movement */ +		if (ix == 0) { +			/* No horz movement */ +			if (iy < 0)  turn(up); +			else turn(down); +		} else { +			if (ix < 0)  turn(left); +			else turn(right); +		} +	} + +	void triptype::stopwalk() { +		ix = 0; +		iy = 0; +		homing = false; +	} + +	void triptype::chatter() { +		Gyro::talkx = x + a.xl / 2; +		Gyro::talky = y; +		Gyro::talkf = a.fgc; +		Gyro::talkb = a.bgc; +	} + +	void triptype::set_up_saver(trip_saver_type &v) { +		v.whichsprite = whichsprite; +		v.face = face; +		v.step = step; +		v.x = x; +		v.y = y; +		v.ix = ix; +		v.iy = iy; +		v.visible = visible; +		v.homing = homing; +		v.check_me = check_me; +		v.count = count; +		v.xw = xw; +		v.xs = xs; +		v.ys = ys; +		v.totalnum = totalnum; +		v.hx = hx; +		v.hy = hy; +		v.call_eachstep = call_eachstep; +		v.eachstep = eachstep; +		v.vanishifstill = vanishifstill; +	} + +	void triptype::unload_saver(trip_saver_type v) { +		whichsprite = v.whichsprite; +		face = v.face; +		step = v.step; +		x = v.x; +		y = v.y; +		ix = v.ix; +		iy = v.iy; +		visible = v.visible; +		homing = v.homing; +		check_me = v.check_me; +		count = v.count; +		xw = v.xw; +		xs = v.xs; +		ys = v.ys; +		totalnum = v.totalnum; +		hx = v.hx; +		hy = v.hy; +		call_eachstep = v.call_eachstep; +		eachstep = v.eachstep; +		vanishifstill = v.vanishifstill; +	} + +	void triptype::savedata(/*untyped_file &f*/) { +		warning("STUB: Timeout::savedata()"); +	} + +	void triptype::loaddata(/*untyped_file &f*/) { +		warning("STUB: Timeout::loaddata()"); +	} + +	triptype *triptype::done() { +		int16 gd, gm; +		Common::String xx; +		byte fv/*,nds*/; +		byte aa, bb; +		int32 id; +		uint16 soa; + +		{ +			adxtype &with = a; + +			/*  nds:=num div seq;*/ +			xw = with.xl / 8; +			if ((with.xl % 8) > 0)  xw += 1; +			for (aa = 1; aa <= /*nds*seq*/ with.num; aa ++) { +				totalnum --; +				free(mani[totalnum]); +				free(sil[totalnum]); /* <<- Width of a siltype. */ +			} +		} + +		quick = false; +		whichsprite = 177; +		return this; +	} + +	getsettype *getsettype::init() { +		numleft = 0; /* initialise array pointer */ +		return this; +	} + +	void getsettype::remember(Gyro::bytefield r) { +		numleft ++; +		warning("STUB: Timeout::getsettype::remember()"); +		gs[numleft] = r; +	} + +	void getsettype::recall(Gyro::bytefield &r) { +		r = gs[numleft]; +		numleft --; +	} + +	void rwsp(byte t, byte r) { +		{ +			switch (r) { +			case up: +				tr[t].speed(0, -tr[t].ys); +				break; +			case down: +				tr[t].speed(0, tr[t].ys); +				break; +			case left: +				tr[t].speed(-tr[t].xs,  0); +				break; +			case right: +				tr[t].speed(tr[t].xs,  0); +				break; +			case ul: +				tr[t].speed(-tr[t].xs, -tr[t].ys); +				break; +			case ur: +				tr[t].speed(tr[t].xs, -tr[t].ys); +				break; +			case dl: +				tr[t].speed(-tr[t].xs, tr[t].ys); +				break; +			case dr: +				tr[t].speed(tr[t].xs, tr[t].ys); +				break; +			} +		} +	} + +	void apped(byte trn, byte np) { +		tr[trn].appear(tr[trn].x - tr[trn].a.xl / 2, tr[trn].y - tr[trn].a.yl, Gyro::peds[np].dir); +		rwsp(trn, Gyro::peds[np].dir); +	} + + + +	void getback(); + +	static Gyro::bytefield r; + +	/*   function overlap(x1,y1,x2,y2,x3,y3,x4,y4:uint16):bool; +	   begin { By De Morgan's law: } +		overlap:=(x2>=x3) and (x4>=x1) and (y2>=y3) and (y4>=y1); +	   end;*/ +	/* x1,x2 - as Gyro::bytefield, but *8. y1,y2 - as Gyro::bytefield. +	  x3,y3 = mx,my. x4,y4 = mx+16,my+16. */ +	static bool overlaps_with_mouse() { +		bool overlaps_with_mouse_result; +		overlaps_with_mouse_result = +			(r.x2 * 8 >= Gyro::mx) && (Gyro::mx + 16 >= r.x1 * 8) && (r.y2 >= Gyro::my) && (Gyro::my + 16 >= r.y1); +		return overlaps_with_mouse_result; +	} + +	void getback() { +		byte fv; +		bool endangered; + + +		endangered = false; +		/* Super_Off;*/ + +		{ +			while (getset[1 - Gyro::cp].numleft > 0) { +				getset[1 - Gyro::cp].recall(r); + +				/*    if overlaps_with_mouse and not endangered then +					begin +					 endangered:=true; +					 blitfix; +					 Super_Off; +					end;*/ + +				Lucerna::mblit(r.x1, r.y1, r.x2, r.y2, 3, 1 - Gyro::cp); +			} +		} + +		Lucerna::blitfix(); +		/*if endangered then*/ /*Super_On;*/ +	} + +	/* Eachstep procedures: */ +	void follow_avvy_y(byte tripnum) { +		if (tr[1].face == left) +			return; +		if (tr[tripnum].homing) +			tr[tripnum].hy = tr[1].y; +		else { +			if (tr[tripnum].y < tr[1].y) +				tr[tripnum].y += 1; +			else if (tr[tripnum].y > tr[1].y) +				tr[tripnum].y -= 1; +			else +				return; +			if (tr[tripnum].ix == 0)  { +				tr[tripnum].step += 1; +				if (tr[tripnum].step == tr[tripnum].a.seq)  tr[tripnum].step = 0; +				tr[tripnum].count = 0; +			} +		} +	} + +	void back_and_forth(byte tripnum) { +		if (! tr[tripnum].homing) { +			if (tr[tripnum].face == right) +				tr[tripnum].walkto(4); +			else +				tr[tripnum].walkto(5); +		} +	} + +	void face_avvy(byte tripnum) { +		if (! tr[tripnum].homing) { +			if (tr[1].x >= tr[tripnum].x)  tr[tripnum].face = right; +			else tr[tripnum].face = left; +		} +	} + +	void arrow_procs(byte tripnum) { +		byte fv; +			 +		if (tr[tripnum].homing) { +			/* Arrow is still in flight. */ +			/* We must check whether or not the arrow has collided tr[tripnum] Avvy's head. +				This is so if: a) the bottom of the arrow is below Avvy's head, +				b) the left of the arrow is left of the right of Avvy's head, and +				c) the right of the arrow is right of the left of Avvy's head. */ +			if (((tr[tripnum].y + tr[tripnum].a.yl) >= tr[1].y) /* A */ +					&& (tr[tripnum].x <= (tr[1].x + tr[1].a.xl)) /* B */ +					&& ((tr[tripnum].x + tr[tripnum].a.xl) >= tr[1].x)) { /* C */ +				/* OK, it's hit him... what now? */ + +				tr[2].call_eachstep = false; /* prevent recursion. */ +				Visa::dixi('Q', 47); /* Complaint! */ +				tr[tripnum].done(); /* Deallocate the arrow. */ +				/*     tr[1].done; { Deallocate normal pic of Avvy. } + +						off; +						for fv:=0 to 1 do +						begin +						cp:=1-cp; +						getback; +						end; +						on;*/ + +				Lucerna::gameover(); + +				Gyro::dna.user_moves_avvy = false; /* Stop the user from moving him. */ +				Timeout::set_up_timer(55, Timeout::procnaughty_duke, Timeout::reason_naughty_duke); +			} +		} else { /* Arrow has hit the wall! */ +			tr[tripnum].done(); /* Deallocate the arrow. */ +			Celer::show_one(3); /* Show pic of arrow stuck into the door. */ +			Gyro::dna.arrow_in_the_door = true; /* So that we can pick it up. */ +		} +		 +	} + +	/*procedure Spludwick_procs(tripnum:byte); +	var fv:byte; +	begin +	 with tr[tripnum] do +	  if not homing then { We only need to do anything if Spludwick *stops* +						   walking. } +	  with Gyro::dna do +	   begin +		inc(DogfoodPos); +		if DogfoodPos=8 then DogfoodPos:=1; +		walkto(DogfoodPos); +	   end; +	end;*/ + +	void grab_avvy(byte tripnum) {     /* For Friar Tuck, in Nottingham. */ +		byte fv; +		int16 tox, toy; +			 +		tox = tr[1].x + 17; +		toy = tr[1].y - 1; +		if ((tr[tripnum].x == tox) && (tr[tripnum].y == toy)) { +			tr[tripnum].call_eachstep = false; +			tr[tripnum].face = left; +			tr[tripnum].stopwalk(); +			/* ... whatever ... */ +		} else { +			/* Still some way to go. */ +			if (tr[tripnum].x < tox) { +				tr[tripnum].x += 5; +				if (tr[tripnum].x > tox)  tr[tripnum].x = tox; +			} +			if (tr[tripnum].y < toy)  tr[tripnum].y += 1; +			tr[tripnum].step += 1; +			if (tr[tripnum].step == tr[tripnum].a.seq)  tr[tripnum].step = 0; +		} +	} + + + +	void geida_procs(byte tripnum); + +	static void take_a_step(byte &tripnum) { +		if (tr[tripnum].ix == 0) { +			tr[tripnum].step += 1; +			if (tr[tripnum].step == tr[tripnum].a.seq)  tr[tripnum].step = 0; +			tr[tripnum].count = 0; +		} +	} + +	static void spin(byte whichway, byte &tripnum) { +		if (tr[tripnum].face != whichway) { +			tr[tripnum].face = whichway; +			if (tr[tripnum].whichsprite == 2)  return; /* Not for Spludwick */ + +			Gyro::dna.geida_spin += 1; +			Gyro::dna.geida_time = 20; +			if (Gyro::dna.geida_spin == 5) { +				Scrolls::display("Steady on, Avvy, you'll make the poor girl dizzy!"); +				Gyro::dna.geida_spin = 0; +				Gyro::dna.geida_time = 0; /* knock out records */ +			} +		} +	} + +	void geida_procs(byte tripnum) { +		if (Gyro::dna.geida_time > 0) { +			Gyro::dna.geida_time -= 1; +			if (Gyro::dna.geida_time == 0)  Gyro::dna.geida_spin = 0; +		} + +		if (tr[tripnum].y < (tr[1].y - 2)) { +			/* Geida is further from the screen than Avvy. */ +			spin(down, tripnum); +			tr[tripnum].iy = 1; +			tr[tripnum].ix = 0; +			take_a_step(tripnum); +			return; +		} else if (tr[tripnum].y > (tr[1].y + 2)) { +			/* Avvy is further from the screen than Geida. */ +			spin(up, tripnum); +			tr[tripnum].iy = -1; +			tr[tripnum].ix = 0; +			take_a_step(tripnum); +			return; +		} + +		tr[tripnum].iy = 0; +		if (tr[tripnum].x < tr[1].x - tr[1].xs * 8) { +			tr[tripnum].ix = tr[1].xs; +			spin(right, tripnum); +			take_a_step(tripnum); +		} else if (tr[tripnum].x > tr[1].x + tr[1].xs * 8) { +			tr[tripnum].ix = -tr[1].xs; +			spin(left, tripnum); +			take_a_step(tripnum); +		} else tr[tripnum].ix = 0; +	} + +	/* That's all... */ + +	void call_andexors() { +		byte order[5]; +		byte fv, temp; +		bool ok; + +		for (int i = 0; i < 5; i++) +			order[i] = 0; + +		for (fv = 1; fv <= numtr; fv ++) { +			if (tr[fv].quick && tr[fv].visible) +				order[fv] = fv; +		} + +		do { +			ok = true; +			for (fv = 1; fv <= 4; fv ++) +				if (((order[fv] != 0) && (order[fv + 1] != 0)) +						&& (tr[order[fv]].y > tr[order[fv + 1]].y)) { +					/* Swap them! */ +					temp = order[fv]; +					order[fv] = order[fv + 1]; +					order[fv + 1] = temp; +					ok = false; +				} +		} while (!ok); + +		for (fv = 1; fv <= 5; fv ++) +			if (order[fv] > 0) +				tr[order[fv]].andexor(); +	} + +	void trippancy_link() { +		byte fv; + +		if (Gyro::ddmnow | Gyro::ontoolbar | Gyro::seescroll)  return; +		for (fv = 1; fv <= numtr; fv ++) { +			if (tr[fv].quick) +				tr[fv].walk(); +		} + +		call_andexors(); +		for (fv = 1; fv <= numtr; fv ++) { +			triptype &with = tr[fv]; +			if (with.quick && with.call_eachstep) { +				switch (tr[fv].eachstep) { +				case procfollow_avvy_y : +					follow_avvy_y(fv); +					break; +				case procback_and_forth : +					back_and_forth(fv); +					break; +				case procface_avvy : +					face_avvy(fv); +					break; +				case procarrow_procs : +					arrow_procs(fv); +					break; +					/*    PROCSpludwick_procs : spludwick_procs(fv);*/ +				case procgrab_avvy : +					grab_avvy(fv); +					break; +				case procgeida_procs : +					geida_procs(fv); +					break; +				} +			} +		} +		if (mustexclaim) { +			mustexclaim = false; +			Visa::dixi('x', saywhat); +		} +	} + +	void get_back_loretta() { +		byte fv; + +		/* for fv:=1 to numtr do with tr[fv] do if quick then getback;*/ +		for (fv = 1; fv <= numtr; fv ++) if (tr[fv].quick) { +				getback(); +				return; +			} +		/* for fv:=0 to 1 do begin cp:=1-cp; getback; end;*/ +	} + +	void stopwalking() { +		tr[1].stopwalk(); +		Gyro::dna.rw = stopped; +		if (Gyro::alive) +			tr[1].step = 1; +	} + +	void tripkey(char dir) { +		if ((Gyro::ctrl == Gyro::cjoy) | (! Gyro::dna.user_moves_avvy)) +			return; + +		{ +			triptype &with = tr[1]; +			{ +				switch (dir) { +				case 'H': +					if (Gyro::dna.rw != up) { +						Gyro::dna.rw = up; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'P': +					if (Gyro::dna.rw != down) { +						Gyro::dna.rw = down; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'K': +					if (Gyro::dna.rw != left) { +						Gyro::dna.rw = left; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'M': +					if (Gyro::dna.rw != right) { +						Gyro::dna.rw = right; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'I': +					if (Gyro::dna.rw != ur) { +						Gyro::dna.rw = ur; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'Q': +					if (Gyro::dna.rw != dr) { +						Gyro::dna.rw = dr; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'O': +					if (Gyro::dna.rw != dl) { +						Gyro::dna.rw = dl; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'G': +					if (Gyro::dna.rw != ul) { +						Gyro::dna.rw = ul; +						rwsp(1, Gyro::dna.rw); +					} else stopwalking(); +					break; +				case 'L': +					stopwalking(); +					break; +				} +			} +		} +	} + +	void readstick() { +		warning("STUB: Trip::readstick()"); +	} + +	void getsetclear() { +		byte fv; + +		for (fv = 0; fv <= 1; fv ++) +			getset[fv].init(); +	} + +	void hide_in_the_cupboard() { +		const char nowt = 250; /* As in Acci. */ + +		if (Gyro::dna.avvys_in_the_cupboard) { +			if (Gyro::dna.wearing == nowt) +				Scrolls::display("\6AVVY!\22 Get dressed first!"); +			else { +				tr[1].visible = true; +				Gyro::dna.user_moves_avvy = true; +				apped(1, 3); /* Walk out of the cupboard. */ +				Scrolls::display("You leave the cupboard. Nice to be out of there!"); +				Gyro::dna.avvys_in_the_cupboard = false; +				Sequence::first_show(8); +				Sequence::then_show(7); +				Sequence::start_to_close; +			} +		} else { +			/* Not hiding in the cupboard */ +			tr[1].visible = false; +			Gyro::dna.user_moves_avvy = false; +			Scrolls::display(Common::String("You walk into the room...\20It seems to be an empty, ") + +					"but dusty, cupboard. Hmmmm... you leave the door slightly open to " + +					"avoid suffocation."); +			Gyro::dna.avvys_in_the_cupboard = true; +			Celer::show_one(8); +		} +	} + + + +	void fliproom(byte room, byte ped); + +	static int16 beforex, beforey; + +	static void tidy_after_mouse(); + +	static void tidy_up(int16 a, int16 b, int16 c, int16 d) { +		warning("STUB: Trip::tidy_up()"); +	} + + + +	static void tidy_after_mouse() { +		tidy_up(beforex, beforey, beforex + 15, beforey + 15); +		Gyro::xycheck(); +		tidy_up(Gyro::mx, Gyro::my, Gyro::mx + 15, Gyro::my + 15); +	} + +	void fliproom(byte room, byte ped) { +		byte fv; + + +		if (! Gyro::alive) { +			/* You can't leave the room if you're dead. */ +			tr[1].ix = 0; +			tr[1].iy = 0; /* Stop him from moving. */ +			return; +		} + +		if ((ped == 177) && (Gyro::dna.room == r__lusties)) { +			hide_in_the_cupboard(); +			return; +		} + +		if ((Gyro::dna.jumpstatus > 0) && (Gyro::dna.room == r__insidecardiffcastle)) { +			/* You can't *jump* out of Cardiff Castle! */ +			tr[1].ix = 0; +			return; +		} + +		Gyro::xycheck(); +		beforex = Gyro::mx; +		beforey = Gyro::my; + +		Lucerna::exitroom(Gyro::dna.room); +		Lucerna::dusk(); +		getsetclear(); + + +		for (fv = 2; fv <= numtr; fv ++) { +			if (tr[fv].quick) +				tr[fv].done(); +		} /* Deallocate sprite */ + +		if (Gyro::dna.room == r__lustiesroom) +			Gyro::dna.enter_catacombs_from_lusties_room = true; + +		Lucerna::enterroom(room, ped); +		apped(1, ped); +		Gyro::dna.enter_catacombs_from_lusties_room = false; +		Gyro::oldrw = Gyro::dna.rw; +		Gyro::dna.rw = tr[1].face; +		Lucerna::showrw; + +		for (fv = 0; fv <= 1; fv ++) { +			Gyro::cp = 1 - Gyro::cp; +			getback(); +		} +		Lucerna::dawn; + +		/* Tidy up after mouse. I know it's a kludge... */ +		/*  tidy_after_mouse;*/ +	} + +	bool infield(byte which) { +	/* returns True if you're within field "which" */ +		int16 yy; +		 +		yy = tr[1].y + tr[1].a.yl; + +		return (tr[1].x >= Gyro::fields[which].x1) && (tr[1].x <= Gyro::fields[which].x2) +			&& (yy >= Gyro::fields[which].y1) && (yy <= Gyro::fields[which].y2); + +	} + +	bool neardoor() {       /* returns True if you're near a door! */ +		int16 ux, uy; +		byte fv; +		bool nd; + +		bool neardoor_result; +		if (Gyro::numfields < 9) { +			/* there ARE no doors here! */ +			neardoor_result = false; +			return neardoor_result; +		} +		 +		ux = tr[1].x; +		uy = tr[1].y + tr[1].a.yl; +		 +		nd = false; +		for (fv = 9; fv <= Gyro::numfields; fv ++) { +			Gyro::fields[fv]; + +			if ((ux >= Gyro::fields[fv].x1) && (ux <= Gyro::fields[fv].x2) +				&& (uy >= Gyro::fields[fv].y1) && (uy <= Gyro::fields[fv].y2))  +					nd = true; +		} +		return nd; +	} + +	void new_game_for_trippancy() {   /* Called by gyro.newgame */ +		tr[1].visible = false; +	} + +	void triptype::save_data_to_mem(uint16 &where) { +		warning("STUB: Trip::save_data_to_mem()"); +	} + +	void triptype::load_data_from_mem(uint16 &where) { +		warning("STUB: Trip::load_data_from_mem()"); +	} + +	} // End of namespace Trip. + +} // End of namespace Avalanche. diff --git a/engines/avalanche/trip6.h b/engines/avalanche/trip6.h new file mode 100644 index 0000000000..0227bab7b6 --- /dev/null +++ b/engines/avalanche/trip6.h @@ -0,0 +1,227 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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 2 + * 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 should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This code is based on the original source code of Lord Avalot d'Argent version 1.3. + * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. + */ + +/* TRIP5	Trippancy V */ + + +#ifndef TRIP6_H +#define TRIP6_H + + + +#include "common/scummsys.h" +#include "common/str.h" + +#include "avalanche/gyro2.h" + +namespace Avalanche { + +	namespace Trip { + +	// Call it where Trip is first used. +	// Procuded to replace the initizalization part of the original Pascal unit. +	void initialize_trip(); + +	const int16 maxgetset = 35; + +	typedef byte manitype[2049]; // manitype = array[5..2053] of byte;  +	// Be aware!!! + +	typedef byte siltype[51][11]; /* 35, 4 */ + +	struct adxtype { /* Second revision of ADX type */ +		Common::String name; /* name of character */ +		Common::String comment; /* comment */ +		byte num; /* number of pictures */ +		byte xl, yl; /* x & y lengths of pictures */ +		byte seq; /* how many in one stride */ +		uint16 size; /* the size of one picture */ +		byte fgc, bgc; /* foreground & background bubble colours */ +		byte accinum; /* the number according to Acci (1=Avvy, etc.) */ +	}; + +	struct trip_saver_type { +		byte whichsprite; +		byte face; +		byte step; +		int16 x; +		int16 y; +		int8 ix; +		int8 iy; +		bool visible; +		bool homing; +		bool check_me; +		byte count; +		byte xw, xs, ys; +		byte totalnum; +		int16 hx; +		int16 hy; +		bool call_eachstep; +		byte eachstep; +		bool vanishifstill; +	}; + +	class triptype { +	public: +		adxtype a; /* vital statistics */ +		byte face, step; +		int16 x, y; /* current xy coords */ +		int16 ox[2], oy[2];  /* last xy coords */ +		int8 ix, iy; /* amount to move sprite by, each step */ +		manitype *mani[24]; +		siltype *sil[24]; +		byte whichsprite; +		bool quick, visible, homing, check_me; +		int16 hx, hy; /* homing x & y coords */ +		byte count; /* counts before changing step */ +		byte xw; /* x-width in bytes */ +		byte xs, ys; /* x & y speed */ +		byte totalnum; /* total number of sprites */ +		bool vanishifstill; /* Do we show this sprite if it's still? */ + +		bool call_eachstep; /* Do we call the eachstep procedure? */ +		byte eachstep; + +		triptype *init(byte spritenum, bool do_check); +		/* loads & sets up the sprite */ +		void original();    /* just sets Quick to false */ +		void andexor();    /* drops sprite onto screen */ +		void turn(byte whichway);      /* turns him round */ +		void appear(int16 wx, int16 wy, byte wf); /* switches him on */ +		void bounce();    /* bounces off walls. */ +		void walk();    /* prepares for andexor, etc. */ +		void walkto(byte pednum);      /* home in on a point */ +		void stophoming();    /* self-explanatory */ +		void homestep();    /* calculates ix & iy for one homing step */ +		void speed(int8 xx, int8 yy); /* sets ix & iy, non-homing, etc */ +		void stopwalk();    /* Stops the sprite from moving */ +		void chatter();    /* Sets up talk vars */ +		void set_up_saver(trip_saver_type &v); +		void unload_saver(trip_saver_type v); + +		void savedata(/*untyped_file &f*/); /* Self-explanatory, */ +		void loaddata(/*untyped_file &f*/);  /* really. */ +		 +	 + + +		void save_data_to_mem(uint16 &where); +		void load_data_from_mem(uint16 &where); +		triptype *done(); + +	private: +		bool collision_check(); +	}; + +	class getsettype { +	public: +		Gyro::bytefield gs[maxgetset]; +		byte numleft; + +		getsettype *init(); +		void remember(Gyro::bytefield r); +		void recall(Gyro::bytefield &r); +	}; + + +	const int16 up = 0; +	const int16 right = 1; +	const int16 down = 2; +	const int16 left = 3; +	const int16 ur = 4; +	const int16 dr = 5; +	const int16 dl = 6; +	const int16 ul = 7; +	const int16 stopped = 8; + +	const int16 numtr = 5; /* current max no. of sprites */ + + + +	const int16 procfollow_avvy_y = 1; + +	const int16 procback_and_forth = 2; + +	const int16 procface_avvy = 3; + +	const int16 procarrow_procs = 4; + +	const int16 procspludwick_procs = 5; + +	const int16 procgrab_avvy = 6; + +	const int16 procgeida_procs = 7; + + +	void trippancy_link(); + +	void get_back_loretta(); + +	void loadtrip(); + +	void call_special(uint16 which); + +	void open_the_door(byte whither, byte ped, byte magicnum); /* Handles slidey-open doors. */ + +	void catamove(byte ped); + +	void stopwalking(); + +	void tripkey(char dir); + +	void rwsp(byte t, byte r); + +	void apped(byte trn, byte np); + +	void getback(); + +	void fliproom(byte room, byte ped); + +	bool infield(byte which);          /* returns True if you're within field "which" */ + +	bool neardoor();        /* returns True if you're near a door! */ + +	void readstick(); + +	void newspeed(); + +	void new_game_for_trippancy(); + + + +	triptype tr[numtr]; +	getsettype getset[2]; +	byte aa[1600]; + +	bool mustexclaim; +	uint16 saywhat; + +	} // End of namespace Trip. + +} // End of namespace Avalanche. + +#endif // TRIP6_H | 
