2003-07-28 01:44:38 +00:00
|
|
|
/* Copyright (C) 1994-2003 Revolution Software Ltd
|
|
|
|
*
|
|
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*/
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// ---------------------------------------------------------------------------
|
2003-07-28 01:44:38 +00:00
|
|
|
// ROUTER.CPP by James
|
2003-09-20 15:34:53 +00:00
|
|
|
//
|
|
|
|
// A rehash of Jeremy's original jrouter.c, containing low-level system
|
|
|
|
// routines for calculating routes between points inside a walk-grid, and
|
|
|
|
// constructing walk animations from mega-sets.
|
|
|
|
//
|
|
|
|
// jrouter.c underwent 2 major reworks from the original:
|
|
|
|
// (1) Restructured to allow more flexibility in the mega-sets, ie. more info
|
|
|
|
// taken from the walk-data
|
|
|
|
// - the new George & Nico mega-sets & walk-data were then tested &
|
|
|
|
// tweaked in the Sword1 system
|
2003-07-28 01:44:38 +00:00
|
|
|
// (2) Updated for the new Sword2 system, ie. new object structures
|
2003-09-20 15:34:53 +00:00
|
|
|
// - now compatible with Sword2, the essential code already having been
|
|
|
|
// tested
|
|
|
|
//
|
|
|
|
// ---------------------------------------------------------------------------
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* JROUTER.C polygon router with modular walks
|
|
|
|
* using a tree of modules
|
|
|
|
* 21 july 94
|
|
|
|
* 3 november 94
|
|
|
|
* System currently works by scanning grid data and coming up with a ROUTE
|
|
|
|
* as a series of way points(nodes), the smoothest eight directional PATH
|
|
|
|
* through these nodes is then found, and a WALK created to fit the PATH.
|
|
|
|
*
|
|
|
|
* Two funtions are called by the user, RouteFinder creates a route as a
|
|
|
|
* module list, HardWalk creates an animation list from the module list.
|
|
|
|
* The split is only provided to allow the possibility of turning the
|
|
|
|
* autorouter over two game cycles.
|
|
|
|
****************************************************************************
|
|
|
|
*
|
|
|
|
* Routine timings on osborne 486
|
|
|
|
*
|
|
|
|
* Read floor resource (file already loaded) 112 pixels
|
|
|
|
*
|
|
|
|
* Read mega resource (file already loaded) 112 pixels
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
****************************************************************************
|
|
|
|
*
|
|
|
|
* Modified 12 Oct 95
|
|
|
|
*
|
|
|
|
* Target Points within 1 pixel of a line are ignored ???
|
|
|
|
*
|
|
|
|
* Modules split into Points within 1 pixel of a line are ignored ???
|
|
|
|
*
|
|
|
|
****************************************************************************
|
|
|
|
*
|
|
|
|
* TOTALLY REHASHED BY JAMES FOR NEW MEGAS USING OLD SYSTEM
|
|
|
|
* THEN REINCARNATED BY JAMES FOR NEW MEGAS USING NEW SYSTEM
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2003-07-28 03:12:49 +00:00
|
|
|
#include "stdafx.h"
|
2003-10-28 19:51:30 +00:00
|
|
|
#include "sword2/driver/driver96.h"
|
|
|
|
#include "sword2/sword2.h"
|
|
|
|
#include "sword2/console.h"
|
|
|
|
#include "sword2/debug.h"
|
|
|
|
#include "sword2/defs.h"
|
|
|
|
#include "sword2/header.h"
|
|
|
|
#include "sword2/interpreter.h"
|
|
|
|
#include "sword2/memory.h"
|
|
|
|
#include "sword2/object.h"
|
|
|
|
#include "sword2/resman.h"
|
|
|
|
#include "sword2/router.h"
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-04 00:52:27 +00:00
|
|
|
namespace Sword2 {
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
uint8 Router::returnSlotNo(uint32 megaId) {
|
2003-09-20 15:34:53 +00:00
|
|
|
if (ID == CUR_PLAYER_ID) {
|
|
|
|
// George (8)
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
// One of Nico's mega id's
|
|
|
|
return 1;
|
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::allocateRouteMem(void) {
|
2003-07-28 01:44:38 +00:00
|
|
|
uint8 slotNo;
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// Player character always always slot 0, while the other mega
|
|
|
|
// (normally Nico) always uses slot 1
|
|
|
|
// Better this way, so that if mega object removed from memory while
|
|
|
|
// in middle of route, the old route will be safely cleared from
|
|
|
|
// memory just before they create a new one
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
slotNo = returnSlotNo(ID);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// if this slot is already used, then it can't be needed any more
|
|
|
|
// because this id is creating a new route!
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_routeSlots[slotNo])
|
|
|
|
freeRouteMem();
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-11-03 07:47:42 +00:00
|
|
|
_routeSlots[slotNo] = memory->allocMemory(sizeof(_walkData) * O_WALKANIM_SIZE, MEM_locked, UID_walk_anim);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// 12000 bytes were used for this in Sword1 mega compacts, based on
|
|
|
|
// 20 bytes per '_walkData' frame
|
2003-07-28 01:44:38 +00:00
|
|
|
// ie. allowing for 600 frames including end-marker
|
|
|
|
// Now '_walkData' is 8 bytes, so 8*600 = 4800 bytes.
|
2003-09-20 15:34:53 +00:00
|
|
|
// Note that a 600 frame walk lasts about 48 seconds!
|
|
|
|
// (600fps / 12.5s = 48s)
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// mega keeps note of which slot contains the pointer to it's walk
|
|
|
|
// animation mem block
|
|
|
|
// +1 so that '0' can mean "not walking"
|
|
|
|
// megaObject->route_slot_id = slotNo + 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_walkData* Router::lockRouteMem(void) {
|
|
|
|
uint8 slotNo = returnSlotNo(ID);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-11-03 07:47:42 +00:00
|
|
|
memory->lockMemory(_routeSlots[slotNo]);
|
2003-10-12 14:40:04 +00:00
|
|
|
return (_walkData *) _routeSlots[slotNo]->ad;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::floatRouteMem(void) {
|
|
|
|
uint8 slotNo = returnSlotNo(ID);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-11-03 07:47:42 +00:00
|
|
|
memory->floatMemory(_routeSlots[slotNo]);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::freeRouteMem(void) {
|
|
|
|
uint8 slotNo = returnSlotNo(ID);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
// free the mem block pointed to from this entry of _routeSlots[]
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-11-03 07:47:42 +00:00
|
|
|
memory->freeMemory(_routeSlots[slotNo]);
|
2003-10-12 14:40:04 +00:00
|
|
|
_routeSlots[slotNo] = NULL;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::freeAllRouteMem(void) {
|
|
|
|
for (int i = 0; i < TOTAL_ROUTE_SLOTS; i++) {
|
|
|
|
if (_routeSlots[i]) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// free the mem block pointed to from this entry of
|
2003-10-12 14:40:04 +00:00
|
|
|
// _routeSlots[]
|
2003-11-03 07:47:42 +00:00
|
|
|
memory->freeMemory(_routeSlots[i]);
|
2003-10-12 14:40:04 +00:00
|
|
|
_routeSlots[i] = NULL;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::routeFinder(Object_mega *ob_mega, Object_walkdata *ob_walkdata, int32 x, int32 y, int32 dir) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* RouteFinder.C polygon router with modular walks
|
|
|
|
* 21 august 94
|
|
|
|
* 3 november 94
|
2003-10-12 14:40:04 +00:00
|
|
|
* routeFinder creates a list of modules that enables HardWalk to
|
2003-09-20 15:34:53 +00:00
|
|
|
* create an animation list.
|
|
|
|
*
|
2003-10-12 14:40:04 +00:00
|
|
|
* routeFinder currently works by scanning grid data and coming up
|
2003-09-20 15:34:53 +00:00
|
|
|
* with a ROUTE as a series of way points(nodes), the smoothest eight
|
|
|
|
* directional PATH through these nodes is then found, this
|
|
|
|
* information is made available to HardWalk for a WALK to be created
|
|
|
|
* to fit the PATH.
|
|
|
|
*
|
|
|
|
* 30 november 94 return values modified
|
|
|
|
*
|
|
|
|
* return 0 = failed to find a route
|
|
|
|
*
|
|
|
|
* 1 = found a route
|
|
|
|
*
|
|
|
|
* 2 = mega already at target
|
|
|
|
*
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
int32 routeFlag = 0;
|
|
|
|
int32 solidFlag = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
_walkData *walkAnim;
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// megaId = id;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
setUpWalkGrid(ob_mega, x, y, dir);
|
|
|
|
loadWalkData(ob_walkdata);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// lock the _walkData array (NB. AFTER loading walkgrid & walkdata!)
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim = lockRouteMem();
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// All route data now loaded start finding a route
|
|
|
|
|
|
|
|
// Check if we can get a route through the floor. changed 12 Oct95 JPS
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
routeFlag = getRoute();
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (routeFlag == 2) {
|
|
|
|
// special case for zero length route
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// if target direction specified as any
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_targetDir > 7)
|
|
|
|
_targetDir = _startDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// just a turn on the spot is required set an end module for
|
|
|
|
// the route let the animator deal with it
|
2003-10-12 14:40:04 +00:00
|
|
|
// modularPath is normally set by extractRoute
|
|
|
|
|
|
|
|
_modularPath[0].dir = _startDir;
|
|
|
|
_modularPath[0].num = 0;
|
|
|
|
_modularPath[0].x = _startX;
|
|
|
|
_modularPath[0].y = _startY;
|
|
|
|
_modularPath[1].dir = _targetDir;
|
|
|
|
_modularPath[1].num = 0;
|
|
|
|
_modularPath[1].x = _startX;
|
|
|
|
_modularPath[1].y = _startY;
|
|
|
|
_modularPath[2].dir = 9;
|
|
|
|
_modularPath[2].num = ROUTE_END_FLAG;
|
|
|
|
|
|
|
|
slidyWalkAnimator(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
routeFlag = 2;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else if (routeFlag == 1) {
|
|
|
|
// a normal route
|
|
|
|
|
|
|
|
// Convert the route to an exact path
|
2003-10-12 14:40:04 +00:00
|
|
|
smoothestPath();
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// The Route had waypoints and direction options
|
|
|
|
|
|
|
|
// The Path is an exact set of lines in 8 directions that
|
|
|
|
// reach the target.
|
|
|
|
|
|
|
|
// The path is in module format, but steps taken in each
|
|
|
|
// direction are not accurate
|
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// if target dir = 8 then the walk isn't linked to an anim so
|
2003-09-20 15:34:53 +00:00
|
|
|
// we can create a route without sliding and miss the exact
|
|
|
|
// target
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
#ifndef FORCE_SLIDY
|
|
|
|
if (_targetDir == 8) {
|
|
|
|
// can end facing ANY direction (ie. exact end
|
|
|
|
// position not vital) - so use SOLID walk to
|
|
|
|
// avoid sliding to exact position
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
solidPath();
|
|
|
|
solidFlag = solidWalkAnimator(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-12 14:40:04 +00:00
|
|
|
#endif
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (!solidFlag) {
|
|
|
|
// if we failed to create a SOLID route, do a SLIDY
|
|
|
|
// one instead
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
slidyPath();
|
|
|
|
slidyWalkAnimator(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
// Route didn't reach target so assume point was off the floor
|
|
|
|
// routeFlag = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
floatRouteMem(); // float the _walkData array again
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
return routeFlag; // send back null route
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::getRoute(void) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* GetRoute.C extract a path from walk grid
|
2003-10-01 10:00:35 +00:00
|
|
|
* 12 october 94
|
2003-09-20 15:34:53 +00:00
|
|
|
*
|
|
|
|
* GetRoute currently works by scanning grid data and coming up with
|
|
|
|
* a ROUTE as a series of way points(nodes).
|
|
|
|
*
|
2003-10-12 14:40:04 +00:00
|
|
|
* static _routeData _route[O_ROUTE_SIZE];
|
2003-09-20 15:34:53 +00:00
|
|
|
*
|
|
|
|
* return 0 = failed to find a route
|
|
|
|
*
|
|
|
|
* 1 = found a route
|
|
|
|
*
|
|
|
|
* 2 = mega already at target
|
|
|
|
*
|
|
|
|
* 3 = failed to find a route because target was on a line
|
|
|
|
*
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
int32 routeGot = 0;
|
|
|
|
int32 level;
|
|
|
|
int32 changed;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_startX == _targetX && _startY == _targetY)
|
2003-07-28 01:44:38 +00:00
|
|
|
routeGot = 2;
|
2003-09-20 15:34:53 +00:00
|
|
|
else {
|
|
|
|
// 'else' added by JEL (23jan96) otherwise 'routeGot' affected
|
|
|
|
// even when already set to '2' above - causing some 'turns'
|
|
|
|
// to walk downwards on the spot
|
|
|
|
|
|
|
|
// returns 3 if target on a line ( +- 1 pixel )
|
2003-10-12 14:40:04 +00:00
|
|
|
routeGot = checkTarget(_targetX, _targetY);
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (routeGot == 0) {
|
|
|
|
// still looking for a route check if target is within a pixel
|
|
|
|
// of a line
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// scan through the nodes linking each node to its nearest
|
|
|
|
// neighbour until no more nodes change
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
// This is the routine that finds a route using scan()
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
level = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
changed = scan(level);
|
2003-09-20 15:34:53 +00:00
|
|
|
level++;
|
2003-10-05 15:28:15 +00:00
|
|
|
} while (changed == 1);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// Check to see if the route reached the target
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_node[_nnodes].dist < 9999) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// it did so extract the route as nodes and the
|
|
|
|
// directions to go between each node
|
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
routeGot = 1;
|
2003-10-12 14:40:04 +00:00
|
|
|
extractRoute();
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// route.X,route.Y and route.Dir now hold all the
|
|
|
|
// route infomation with the target dir or route
|
|
|
|
// continuation
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return routeGot;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SLIDY PATH ROUTINES
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::smoothestPath() {
|
2003-09-20 15:34:53 +00:00
|
|
|
// This is the second big part of the route finder and the the only
|
|
|
|
// bit that tries to be clever (the other bits are clever).
|
|
|
|
//
|
|
|
|
// This part of the autorouter creates a list of modules from a set of
|
|
|
|
// lines running across the screen. The task is complicated by two
|
|
|
|
// things:
|
|
|
|
//
|
|
|
|
// Firstly in choosing a route through the maze of nodes the routine
|
|
|
|
// tries to minimise the amount of each individual turn avoiding 90
|
|
|
|
// degree and greater turns (where possible) and reduces the total
|
|
|
|
// number of turns (subject to two 45 degree turns being better than
|
|
|
|
// one 90 degree turn).
|
|
|
|
//
|
|
|
|
// Secondly when walking in a given direction the number of steps
|
|
|
|
// required to reach the end of that run is not calculated accurately.
|
|
|
|
// This is because I was unable to derive a function to relate number
|
|
|
|
// of steps taken between two points to the shrunken step size
|
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 p;
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 dirS;
|
|
|
|
int32 dirD;
|
|
|
|
int32 dS;
|
|
|
|
int32 dD;
|
|
|
|
int32 dSS;
|
|
|
|
int32 dSD;
|
|
|
|
int32 dDS;
|
|
|
|
int32 dDD;
|
|
|
|
int32 SS;
|
|
|
|
int32 SD;
|
|
|
|
int32 DS;
|
|
|
|
int32 DD;
|
|
|
|
int32 i;
|
|
|
|
int32 j;
|
|
|
|
int32 steps;
|
|
|
|
int32 option;
|
|
|
|
int32 options;
|
|
|
|
int32 lastDir;
|
|
|
|
int32 nextDirS;
|
|
|
|
int32 nextDirD;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 tempturns[4];
|
|
|
|
int32 turns[4];
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 turntable[NO_DIRECTIONS] = { 0, 1, 3, 5, 7, 5, 3, 1 };
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// route.X route.Y and route.Dir start at far end
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[0].x = _startX;
|
|
|
|
_smoothPath[0].y = _startY;
|
|
|
|
_smoothPath[0].dir = _startDir;
|
|
|
|
_smoothPath[0].num = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
p = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _startDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// for each section of the route
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
dirS = _route[p].dirS;
|
|
|
|
dirD = _route[p].dirD;
|
|
|
|
nextDirS = _route[p + 1].dirS;
|
|
|
|
nextDirD = _route[p + 1].dirD;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// Check directions into and out of a pair of nodes going in
|
2003-07-28 01:44:38 +00:00
|
|
|
dS = dirS - lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (dS < 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
dS = dS + NO_DIRECTIONS;
|
|
|
|
|
|
|
|
dD = dirD - lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (dD < 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
dD = dD + NO_DIRECTIONS;
|
|
|
|
|
|
|
|
// coming out
|
|
|
|
dSS = dirS - nextDirS;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (dSS < 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
dSS = dSS + NO_DIRECTIONS;
|
|
|
|
|
|
|
|
dDD = dirD - nextDirD;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (dDD < 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
dDD = dDD + NO_DIRECTIONS;
|
|
|
|
|
|
|
|
dSD = dirS - nextDirD;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (dSD < 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
dSD = dSD + NO_DIRECTIONS;
|
|
|
|
|
|
|
|
dDS = dirD - nextDirS;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (dDS < 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
dDS = dDS + NO_DIRECTIONS;
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// Determine the amount of turning involved in each possible
|
|
|
|
// path
|
|
|
|
|
|
|
|
dS = turntable[dS];
|
|
|
|
dD = turntable[dD];
|
2003-07-28 01:44:38 +00:00
|
|
|
dSS = turntable[dSS];
|
|
|
|
dDD = turntable[dDD];
|
2003-09-20 15:34:53 +00:00
|
|
|
dSD = turntable[dSD];
|
|
|
|
dDS = turntable[dDS];
|
|
|
|
|
|
|
|
// get the best path out ie assume next section uses best
|
|
|
|
// direction
|
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
if (dSD < dSS)
|
|
|
|
dSS = dSD;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
if (dDS < dDD)
|
|
|
|
dDD = dDS;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// Rate each option. Split routes look crap so weight against
|
|
|
|
// them
|
|
|
|
|
|
|
|
SS = dS + dSS + 3;
|
2003-07-28 01:44:38 +00:00
|
|
|
SD = dS + dDD;
|
|
|
|
DS = dD + dSS;
|
|
|
|
DD = dD + dDD + 3;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// set up turns as a sorted array of the turn values
|
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
tempturns[0] = SS;
|
|
|
|
turns[0] = 0;
|
|
|
|
tempturns[1] = SD;
|
|
|
|
turns[1] = 1;
|
|
|
|
tempturns[2] = DS;
|
|
|
|
turns[2] = 2;
|
|
|
|
tempturns[3] = DD;
|
|
|
|
turns[3] = 3;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
|
|
if (tempturns[j] > tempturns[j + 1]) {
|
2003-10-12 14:40:04 +00:00
|
|
|
SWAP(turns[j], turns[j + 1]);
|
|
|
|
SWAP(tempturns[j], tempturns[j + 1]);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// best option matched in order of the priority we would like
|
|
|
|
// to see on the screen but each option must be checked to see
|
|
|
|
// if it can be walked
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
options = newCheck(1, _route[p].x, _route[p].y, _route[p + 1].x, _route[p + 1].y);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-07-30 19:25:31 +00:00
|
|
|
#ifdef _SWORD2_DEBUG
|
2003-09-20 15:34:53 +00:00
|
|
|
if (options == 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "BestTurns fail %d %d %d %d", _route[p].x, _route[p].y, _route[p + 1].x, _route[p + 1].y);
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "BestTurns fail %d %d %d %d", turns[0], turns[1], turns[2], options);
|
2003-10-26 15:42:49 +00:00
|
|
|
error("BestTurns failed");
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
steps = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-07-28 01:44:38 +00:00
|
|
|
option = 1 << turns[i];
|
|
|
|
if (option & options)
|
2003-10-12 14:40:04 +00:00
|
|
|
steps = smoothCheck(turns[i], p, dirS, dirD);
|
2003-09-20 15:34:53 +00:00
|
|
|
i++;
|
|
|
|
} while (steps == 0 && i < 4);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-07-30 19:25:31 +00:00
|
|
|
#ifdef _SWORD2_DEBUG
|
2003-09-20 15:34:53 +00:00
|
|
|
if (steps == 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "BestTurns failed %d %d %d %d", _route[p].x, _route[p].y, _route[p + 1].x, _route[p + 1].y);
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "BestTurns failed %d %d %d %d", turns[0], turns[1], turns[2], options);
|
2003-10-26 15:42:49 +00:00
|
|
|
error("BestTurns failed");
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// route.X route.Y route.dir and bestTurns start at far end
|
2003-09-20 15:34:53 +00:00
|
|
|
p++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (p < _routeLength);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// best turns will end heading as near as possible to target dir rest
|
|
|
|
// is down to anim for now
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[steps].dir = 9;
|
|
|
|
_smoothPath[steps].num = ROUTE_END_FLAG;
|
2003-09-20 15:34:53 +00:00
|
|
|
return 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* Slip sliding away
|
|
|
|
* This path checker checks to see if a walk that exactly follows the
|
|
|
|
* path would be valid. This should be inherently true for atleast one
|
|
|
|
* of the turn options.
|
|
|
|
* No longer checks the data it only creates the smoothPath array JPS
|
|
|
|
*********************************************************************/
|
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
static int32 k;
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 x;
|
|
|
|
int32 y;
|
|
|
|
int32 x2;
|
|
|
|
int32 y2;
|
|
|
|
int32 ldx;
|
|
|
|
int32 ldy;
|
|
|
|
int32 dsx;
|
|
|
|
int32 dsy;
|
|
|
|
int32 ddx;
|
|
|
|
int32 ddy;
|
|
|
|
int32 dirX;
|
|
|
|
int32 dirY;
|
|
|
|
int32 ss0;
|
|
|
|
int32 ss1;
|
|
|
|
int32 ss2;
|
|
|
|
int32 sd0;
|
|
|
|
int32 sd1;
|
|
|
|
int32 sd2;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
if (p == 0)
|
|
|
|
k = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
x = _route[p].x;
|
|
|
|
y = _route[p].y;
|
|
|
|
x2 = _route[p + 1].x;
|
|
|
|
y2 = _route[p + 1].y;
|
2003-07-28 12:24:13 +00:00
|
|
|
ldx = x2 - x;
|
|
|
|
ldy = y2 - y;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirX = 1;
|
|
|
|
dirY = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (ldx < 0) {
|
2003-07-28 12:24:13 +00:00
|
|
|
ldx = -ldx;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirX = -1;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (ldy < 0) {
|
2003-07-28 12:24:13 +00:00
|
|
|
ldy = -ldy;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirY = -1;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// set up sd0-ss2 to reflect possible movement in each direction
|
|
|
|
|
|
|
|
if (dirS == 0 || dirS == 4) { // vert and diag
|
2003-09-19 15:01:49 +00:00
|
|
|
ddx = ldx;
|
2003-10-12 14:40:04 +00:00
|
|
|
ddy = (ldx * _diagonaly) / _diagonalx;
|
2003-09-19 15:01:49 +00:00
|
|
|
dsy = ldy - ddy;
|
|
|
|
ddx = ddx * dirX;
|
|
|
|
ddy = ddy * dirY;
|
|
|
|
dsy = dsy * dirY;
|
|
|
|
dsx = 0;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
sd0 = (ddx + _modX[dirD] / 2) / _modX[dirD];
|
|
|
|
ss0 = (dsy + _modY[dirS] / 2) / _modY[dirS];
|
2003-09-20 15:34:53 +00:00
|
|
|
sd1 = sd0 / 2;
|
|
|
|
ss1 = ss0 / 2;
|
2003-09-19 15:01:49 +00:00
|
|
|
sd2 = sd0 - sd1;
|
|
|
|
ss2 = ss0 - ss1;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
2003-09-19 15:01:49 +00:00
|
|
|
ddy = ldy;
|
2003-10-12 14:40:04 +00:00
|
|
|
ddx = (ldy * _diagonalx) / _diagonaly;
|
2003-09-19 15:01:49 +00:00
|
|
|
dsx = ldx - ddx;
|
|
|
|
ddy = ddy * dirY;
|
|
|
|
ddx = ddx * dirX;
|
|
|
|
dsx = dsx * dirX;
|
|
|
|
dsy = 0;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
sd0 = (ddy + _modY[dirD] / 2) / _modY[dirD];
|
|
|
|
ss0 = (dsx + _modX[dirS] / 2) / _modX[dirS];
|
2003-09-20 15:34:53 +00:00
|
|
|
sd1 = sd0 / 2;
|
|
|
|
ss1 = ss0 / 2;
|
2003-09-19 15:01:49 +00:00
|
|
|
sd2 = sd0 - sd1;
|
|
|
|
ss2 = ss0 - ss1;
|
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (best == 0) { // halfsquare, diagonal, halfsquare
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + dsx / 2;
|
|
|
|
_smoothPath[k].y = y + dsy / 2;
|
|
|
|
_smoothPath[k].dir = dirS;
|
|
|
|
_smoothPath[k].num = ss1;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + dsx / 2 + ddx;
|
|
|
|
_smoothPath[k].y = y + dsy / 2 + ddy;
|
|
|
|
_smoothPath[k].dir = dirD;
|
|
|
|
_smoothPath[k].num = sd0;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + dsx + ddx;
|
|
|
|
_smoothPath[k].y = y + dsy + ddy;
|
|
|
|
_smoothPath[k].dir = dirS;
|
|
|
|
_smoothPath[k].num = ss2;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else if (best == 1) { // square, diagonal
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + dsx;
|
|
|
|
_smoothPath[k].y = y + dsy;
|
|
|
|
_smoothPath[k].dir = dirS;
|
|
|
|
_smoothPath[k].num = ss0;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x2;
|
|
|
|
_smoothPath[k].y = y2;
|
|
|
|
_smoothPath[k].dir = dirD;
|
|
|
|
_smoothPath[k].num = sd0;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else if (best == 2) { // diagonal square
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + ddx;
|
|
|
|
_smoothPath[k].y = y + ddy;
|
|
|
|
_smoothPath[k].dir = dirD;
|
|
|
|
_smoothPath[k].num = sd0;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x2;
|
|
|
|
_smoothPath[k].y = y2;
|
|
|
|
_smoothPath[k].dir = dirS;
|
|
|
|
_smoothPath[k].num = ss0;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else { // halfdiagonal, square, halfdiagonal
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + ddx / 2;
|
|
|
|
_smoothPath[k].y = y + ddy / 2;
|
|
|
|
_smoothPath[k].dir = dirD;
|
|
|
|
_smoothPath[k].num = sd1;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x + dsx + ddx / 2;
|
|
|
|
_smoothPath[k].y = y + dsy + ddy / 2;
|
|
|
|
_smoothPath[k].dir = dirS;
|
|
|
|
_smoothPath[k].num = ss0;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_smoothPath[k].x = x2;
|
|
|
|
_smoothPath[k].y = y2;
|
|
|
|
_smoothPath[k].dir = dirD;
|
|
|
|
_smoothPath[k].num = sd2;
|
2003-09-19 15:01:49 +00:00
|
|
|
k++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return k;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::slidyPath() {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
2003-10-12 14:40:04 +00:00
|
|
|
* slidyPath creates a path based on part steps with no sliding to get
|
2003-09-20 15:34:53 +00:00
|
|
|
* as near as possible to the target without any sliding this routine
|
|
|
|
* is currently unused, but is intended for use when just clicking
|
|
|
|
* about.
|
|
|
|
*
|
|
|
|
* produce a module list from the line data
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
int32 smooth;
|
|
|
|
int32 slidy;
|
|
|
|
int32 scale;
|
|
|
|
int32 stepX;
|
|
|
|
int32 stepY;
|
|
|
|
int32 deltaX;
|
|
|
|
int32 deltaY;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// strip out the short sections
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
slidy = 1;
|
|
|
|
smooth = 1;
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[0].x = _smoothPath[0].x;
|
|
|
|
_modularPath[0].y = _smoothPath[0].y;
|
|
|
|
_modularPath[0].dir = _smoothPath[0].dir;
|
|
|
|
_modularPath[0].num = 0;
|
|
|
|
|
|
|
|
while (_smoothPath[smooth].num < ROUTE_END_FLAG) {
|
|
|
|
scale = _scaleA * _smoothPath[smooth].y + _scaleB;
|
|
|
|
deltaX = _smoothPath[smooth].x - _modularPath[slidy - 1].x;
|
|
|
|
deltaY = _smoothPath[smooth].y - _modularPath[slidy - 1].y;
|
|
|
|
stepX = _modX[_smoothPath[smooth].dir];
|
|
|
|
stepY = _modY[_smoothPath[smooth].dir];
|
2003-07-28 01:44:38 +00:00
|
|
|
stepX = stepX * scale;
|
|
|
|
stepY = stepY * scale;
|
2003-09-20 15:34:53 +00:00
|
|
|
stepX = stepX >> 19; // quarter a step minimum
|
2003-07-28 01:44:38 +00:00
|
|
|
stepY = stepY >> 19;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-09-24 06:40:23 +00:00
|
|
|
if (ABS(deltaX) >= ABS(stepX) && ABS(deltaY) >= ABS(stepY)) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[slidy].x = _smoothPath[smooth].x;
|
|
|
|
_modularPath[slidy].y = _smoothPath[smooth].y;
|
|
|
|
_modularPath[slidy].dir = _smoothPath[smooth].dir;
|
|
|
|
_modularPath[slidy].num = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
slidy++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
smooth++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// in case the last bit had no steps
|
|
|
|
|
|
|
|
if (slidy > 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[slidy - 1].x = _smoothPath[smooth - 1].x;
|
|
|
|
_modularPath[slidy - 1].y = _smoothPath[smooth - 1].y;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// set up the end of the walk
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[slidy].x = _smoothPath[smooth - 1].x;
|
|
|
|
_modularPath[slidy].y = _smoothPath[smooth - 1].y;
|
|
|
|
_modularPath[slidy].dir = _targetDir;
|
|
|
|
_modularPath[slidy].num = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
slidy++;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[slidy].x = _smoothPath[smooth - 1].x;
|
|
|
|
_modularPath[slidy].y = _smoothPath[smooth - 1].y;
|
|
|
|
_modularPath[slidy].dir = 9;
|
|
|
|
_modularPath[slidy].num = ROUTE_END_FLAG;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SLOW IN
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::addSlowInFrames(_walkData *walkAnim) {
|
|
|
|
if (_usingSlowInFrames && _modularPath[1].num > 0) {
|
|
|
|
for (uint slowInFrameNo = 0; slowInFrameNo < _numberOfSlowInFrames[_currentDir]; slowInFrameNo++) {
|
|
|
|
walkAnim[_stepCount].frame = _firstSlowInFrame[_currentDir] + slowInFrameNo;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = _currentDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
return 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
return 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::earlySlowOut(Object_mega *ob_mega, Object_walkdata *ob_walkdata) {
|
2003-07-28 01:44:38 +00:00
|
|
|
int32 slowOutFrameNo;
|
|
|
|
int32 walk_pc;
|
|
|
|
_walkData *walkAnim;
|
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "EARLY SLOW-OUT");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
loadWalkData(ob_walkdata);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "********************************");
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "_framesPerStep = %d", _framesPerStep);
|
|
|
|
debug(5, "_numberOfSlowOutFrames = %d", _numberOfSlowOutFrames);
|
|
|
|
debug(5, "_firstWalkingTurnLeftFrame = %d", _firstWalkingTurnLeftFrame);
|
|
|
|
debug(5, "_firstWalkingTurnRightFrame = %d", _firstWalkingTurnRightFrame);
|
|
|
|
debug(5, "_firstSlowOutFrame = %d", _firstSlowOutFrame);
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "********************************");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
walk_pc = ob_mega->walk_pc;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// lock the _walkData array (NB. AFTER loading walkgrid & walkdata!)
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim = lockRouteMem();
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// if this mega does actually have slow-out frames
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingSlowOutFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// overwrite the next step (half a cycle) of the walk
|
|
|
|
// (ie .step - 0..5)
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "STEP NUMBER: walkAnim[%d].step = %d", walk_pc, walkAnim[walk_pc].step);
|
|
|
|
debug(5, "ORIGINAL FRAME: walkAnim[%d].frame = %d", walk_pc, walkAnim[walk_pc].frame);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// map from existing walk frame across to correct
|
|
|
|
// frame number of slow-out - remember, there may be
|
|
|
|
// more slow-out frames than walk-frames!
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (walkAnim[walk_pc].frame >= _firstWalkingTurnRightFrame) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// if it's a walking turn-right, rather than a
|
|
|
|
// normal step, then map it to a normal step
|
|
|
|
// frame first
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[walk_pc].frame -= _firstWalkingTurnRightFrame;
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "MAPPED TO WALK: walkAnim[%d].frame = %d (walking turn-right frame --> walk frame)", walk_pc, walkAnim[walk_pc].frame);
|
2003-10-12 14:40:04 +00:00
|
|
|
} else if (walkAnim[walk_pc].frame >= _firstWalkingTurnLeftFrame) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// if it's a walking turn-left, rather than a
|
|
|
|
// normal step, then map it to a normal step
|
|
|
|
// frame first
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[walk_pc].frame -= _firstWalkingTurnLeftFrame;
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "MAPPED TO WALK: walkAnim[%d].frame = %d (walking turn-left frame --> walk frame)", walk_pc, walkAnim[walk_pc].frame);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[walk_pc].frame += _firstSlowOutFrame + ((walkAnim[walk_pc].frame / _framesPerStep) * (_numberOfSlowOutFrames - _framesPerStep));
|
2003-07-28 01:44:38 +00:00
|
|
|
walkAnim[walk_pc].step = 0;
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SLOW-OUT FRAME: walkAnim[%d].frame = %d",walk_pc, walkAnim[walk_pc].frame);
|
2003-09-20 15:34:53 +00:00
|
|
|
walk_pc++;
|
2003-10-05 15:28:15 +00:00
|
|
|
} while (walkAnim[walk_pc].step > 0);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// add stationary frame(s) (OPTIONAL)
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (slowOutFrameNo = _framesPerStep; slowOutFrameNo < _numberOfSlowOutFrames; slowOutFrameNo++) {
|
2003-09-20 15:34:53 +00:00
|
|
|
walkAnim[walk_pc].frame = walkAnim[walk_pc - 1].frame + 1;
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "EXTRA FRAME: walkAnim[%d].frame = %d", walk_pc, walkAnim[walk_pc].frame);
|
2003-07-28 01:44:38 +00:00
|
|
|
walkAnim[walk_pc].step = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
walkAnim[walk_pc].dir = walkAnim[walk_pc - 1].dir;
|
|
|
|
walkAnim[walk_pc].x = walkAnim[walk_pc - 1].x;
|
|
|
|
walkAnim[walk_pc].y = walkAnim[walk_pc - 1].y;
|
2003-07-28 01:44:38 +00:00
|
|
|
walk_pc++;
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
// this mega doesn't have slow-out frames
|
|
|
|
// stand in current direction
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[walk_pc].frame = _firstStandFrame + walkAnim[walk_pc - 1].dir;
|
2003-09-20 15:34:53 +00:00
|
|
|
walkAnim[walk_pc].step = 0;
|
|
|
|
walkAnim[walk_pc].dir = walkAnim[walk_pc - 1].dir;
|
|
|
|
walkAnim[walk_pc].x = walkAnim[walk_pc - 1].x;
|
|
|
|
walkAnim[walk_pc].y = walkAnim[walk_pc - 1].y;
|
2003-07-28 01:44:38 +00:00
|
|
|
walk_pc++;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// end of sequence
|
|
|
|
walkAnim[walk_pc].frame = 512;
|
|
|
|
|
|
|
|
// so that this doesn't happen again while 'george_walking' is still
|
|
|
|
// '2'
|
|
|
|
walkAnim[walk_pc].step = 99;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// SLOW OUT
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::addSlowOutFrames(_walkData *walkAnim) {
|
2003-07-28 01:44:38 +00:00
|
|
|
int32 slowOutFrameNo;
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// if the mega did actually walk, we overwrite the last step (half a
|
|
|
|
// cycle) with slow-out frames + add any necessary stationary frames
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingSlowOutFrames && _lastCount >= _framesPerStep) {
|
2003-07-28 01:44:38 +00:00
|
|
|
// place stop frames here
|
|
|
|
// slowdown at the end of the last walk
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
slowOutFrameNo = _lastCount - _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "SLOW OUT: slowOutFrameNo(%d) = _lastCount(%d) - _framesPerStep(%d)", slowOutFrameNo, _lastCount, _framesPerStep);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// overwrite the last step (half a cycle) of the walk
|
|
|
|
|
|
|
|
do {
|
|
|
|
// map from existing walk frame across to correct
|
|
|
|
// frame number of slow-out - remember, there may be
|
|
|
|
// more slow-out frames than walk-frames!
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[slowOutFrameNo].frame += _firstSlowOutFrame + ((walkAnim[slowOutFrameNo].frame / _framesPerStep) * (_numberOfSlowOutFrames - _framesPerStep));
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// because no longer a normal walk-step
|
|
|
|
walkAnim[slowOutFrameNo].step = 0;
|
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "walkAnim[%d].frame = %d",slowOutFrameNo,walkAnim[slowOutFrameNo].frame);
|
2003-09-20 15:34:53 +00:00
|
|
|
slowOutFrameNo++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (slowOutFrameNo < _lastCount);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// add stationary frame(s) (OPTIONAL)
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (slowOutFrameNo = _framesPerStep; slowOutFrameNo < _numberOfSlowOutFrames; slowOutFrameNo++) {
|
|
|
|
walkAnim[_stepCount].frame = walkAnim[_stepCount - 1].frame + 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "EXTRA FRAMES: walkAnim[%d].frame = %d", _stepCount, walkAnim[_stepCount].frame);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = walkAnim[_stepCount - 1].dir;
|
|
|
|
walkAnim[_stepCount].x = walkAnim[_stepCount - 1].x;
|
|
|
|
walkAnim[_stepCount].y = walkAnim[_stepCount - 1].y;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::slidyWalkAnimator(_walkData *walkAnim) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* Skidding every where HardWalk creates an animation that exactly
|
|
|
|
* fits the smoothPath and uses foot slipping to fit whole steps into
|
|
|
|
* the route
|
|
|
|
*
|
|
|
|
* Parameters: georgeg, mouseg
|
|
|
|
* Returns: rout
|
|
|
|
*
|
|
|
|
* produce a module list from the line data
|
|
|
|
*********************************************************************/
|
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
static int32 left = 0;
|
|
|
|
int32 p;
|
|
|
|
int32 lastDir;
|
|
|
|
int32 lastRealDir;
|
|
|
|
int32 turnDir;
|
|
|
|
int32 scale;
|
|
|
|
int32 step;
|
|
|
|
int32 module;
|
|
|
|
int32 moduleEnd;
|
|
|
|
int32 module16X;
|
|
|
|
int32 module16Y;
|
|
|
|
int32 stepX;
|
|
|
|
int32 stepY;
|
|
|
|
int32 errorX;
|
|
|
|
int32 errorY;
|
|
|
|
int32 lastErrorX;
|
|
|
|
int32 lastErrorY;
|
|
|
|
int32 frameCount;
|
|
|
|
int32 frames;
|
|
|
|
|
|
|
|
p = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _modularPath[0].dir;
|
|
|
|
_currentDir = _modularPath[1].dir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_currentDir == NO_DIRECTIONS)
|
|
|
|
_currentDir = lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_moduleX = _startX;
|
|
|
|
_moduleY = _startY;
|
|
|
|
module16X = _moduleX << 16;
|
|
|
|
module16Y = _moduleY << 16;
|
|
|
|
_stepCount = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY
|
|
|
|
// BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SLIDY: STARTING THE WALK");
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _framesPerChar + lastDir;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// TURN TO START THE WALK
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SLIDY: TURNING TO START THE WALK");
|
2003-07-28 01:44:38 +00:00
|
|
|
// rotate if we need to
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (lastDir != _currentDir) {
|
2003-07-28 01:44:38 +00:00
|
|
|
// get the direction to turn
|
2003-10-12 14:40:04 +00:00
|
|
|
turnDir = _currentDir - lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (turnDir < 0)
|
|
|
|
turnDir += NO_DIRECTIONS;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
if (turnDir > 4)
|
|
|
|
turnDir = -1;
|
|
|
|
else if (turnDir > 0)
|
|
|
|
turnDir = 1;
|
|
|
|
|
|
|
|
// rotate to new walk direction
|
|
|
|
// for george and nico put in a head turn at the start
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingStandingTurnFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// new frames for turn frames 29oct95jps
|
|
|
|
if (turnDir < 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnLeftFrame + lastDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnRightFrame + lastDir;
|
|
|
|
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// rotate till were facing new dir then go back 45 degrees
|
2003-10-12 14:40:04 +00:00
|
|
|
while (lastDir != _currentDir) {
|
2003-07-28 01:44:38 +00:00
|
|
|
lastDir += turnDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// new frames for turn frames 29oct95jps
|
|
|
|
if (turnDir < 0) {
|
2003-07-28 01:44:38 +00:00
|
|
|
if ( lastDir < 0)
|
2003-09-19 15:01:49 +00:00
|
|
|
lastDir += NO_DIRECTIONS;
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnLeftFrame + lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
2003-07-28 01:44:38 +00:00
|
|
|
if ( lastDir > 7)
|
2003-09-19 15:01:49 +00:00
|
|
|
lastDir -= NO_DIRECTIONS;
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnRightFrame + lastDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// the back 45 degrees bit
|
2003-09-20 15:34:53 +00:00
|
|
|
// step back one because new head turn for george takes us
|
|
|
|
// past the new dir
|
2003-10-12 14:40:04 +00:00
|
|
|
_stepCount--;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// his head is in the right direction
|
2003-10-12 14:40:04 +00:00
|
|
|
lastRealDir = _currentDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// SLIDY: THE SLOW IN
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
addSlowInFrames(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// THE WALK
|
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SLIDY: THE WALK");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// start the walk on the left or right leg, depending on how the
|
|
|
|
// slow-in frames were drawn
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// (0 = left; 1 = right)
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_leadingLeg[_currentDir] == 0) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// start the walk on the left leg (ie. at beginning of the
|
|
|
|
// first step of the walk cycle)
|
|
|
|
left = 0;
|
|
|
|
} else {
|
|
|
|
// start the walk on the right leg (ie. at beginning of the
|
|
|
|
// second step of the walk cycle)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_lastCount = _stepCount;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// this ensures that we don't put in turn frames for the start
|
|
|
|
lastDir = 99;
|
|
|
|
|
|
|
|
// this ensures that we don't put in turn frames for the start
|
2003-10-12 14:40:04 +00:00
|
|
|
_currentDir = 99;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
assert(_stepCount < O_WALKANIM_SIZE);
|
|
|
|
while (_modularPath[p].num == 0) {
|
2003-09-20 15:34:53 +00:00
|
|
|
p++;
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_currentDir != 99)
|
|
|
|
lastRealDir = _currentDir;
|
|
|
|
lastDir = _currentDir;
|
|
|
|
_lastCount = _stepCount;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// calculate average amount to lose in each step on the way
|
|
|
|
// to the next node
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_currentDir = _modularPath[p].dir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_currentDir < NO_DIRECTIONS) {
|
|
|
|
module = _currentDir * _framesPerStep * 2 + left;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
if (left == 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
2003-09-20 15:34:53 +00:00
|
|
|
left = 0;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
moduleEnd = module + _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
step = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
scale = (_scaleA * _moduleY + _scaleB);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
module16X += _dx[module] * scale;
|
|
|
|
module16Y += _dy[module] * scale;
|
|
|
|
_moduleX = module16X >> 16;
|
|
|
|
_moduleY = module16Y >> 16;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = step; // normally 0,1,2,3,4,5,0,1,2,etc
|
|
|
|
walkAnim[_stepCount].dir = _currentDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-09-20 15:34:53 +00:00
|
|
|
step++;
|
|
|
|
module++;
|
2003-10-05 15:28:15 +00:00
|
|
|
} while (module < moduleEnd);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
stepX = _modX[_modularPath[p].dir];
|
|
|
|
stepY = _modY[_modularPath[p].dir];
|
|
|
|
errorX = _modularPath[p].x - _moduleX;
|
2003-07-28 01:44:38 +00:00
|
|
|
errorX = errorX * stepX;
|
2003-10-12 14:40:04 +00:00
|
|
|
errorY = _modularPath[p].y - _moduleY;
|
2003-07-28 01:44:38 +00:00
|
|
|
errorY = errorY * stepY;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (errorX < 0 || errorY < 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[p].num = 0; // the end of the path
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// okay those last steps took us past our
|
|
|
|
// target but do we want to scoot or moonwalk
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
frames = _stepCount - _lastCount;
|
|
|
|
errorX = _modularPath[p].x - walkAnim[_stepCount - 1].x;
|
|
|
|
errorY = _modularPath[p].y - walkAnim[_stepCount - 1].y;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (frames > _framesPerStep) {
|
|
|
|
lastErrorX = _modularPath[p].x - walkAnim[_stepCount - 7].x;
|
|
|
|
lastErrorY = _modularPath[p].y - walkAnim[_stepCount - 7].y;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (stepX == 0) {
|
2003-09-24 06:40:23 +00:00
|
|
|
if (3 * ABS(lastErrorY) < ABS(errorY)) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// the last stop was
|
|
|
|
// closest
|
2003-10-12 14:40:04 +00:00
|
|
|
_stepCount -= _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
if (left == 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
|
|
|
left = 0;
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
2003-09-24 06:40:23 +00:00
|
|
|
if (3 * ABS(lastErrorX) < ABS(errorX)) {
|
2003-09-20 15:34:53 +00:00
|
|
|
//the last stop was
|
|
|
|
// closest
|
2003-10-12 14:40:04 +00:00
|
|
|
_stepCount -= _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
if (left == 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
|
|
|
left = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
errorX = _modularPath[p].x - walkAnim[_stepCount-1].x;
|
|
|
|
errorY = _modularPath[p].y - walkAnim[_stepCount-1].y;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// okay we've reached the end but we still
|
|
|
|
// have an error
|
|
|
|
|
|
|
|
if (errorX != 0) {
|
2003-07-28 01:44:38 +00:00
|
|
|
frameCount = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
frames = _stepCount - _lastCount;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
frameCount++;
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_lastCount + frameCount - 1].x += errorX * frameCount / frames;
|
2003-10-05 15:28:15 +00:00
|
|
|
} while (frameCount < frames);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (errorY != 0) {
|
2003-07-28 01:44:38 +00:00
|
|
|
frameCount = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
frames = _stepCount - _lastCount;
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
|
|
|
frameCount++;
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_lastCount + frameCount - 1].y += errorY * frameCount / frames;
|
2003-10-05 15:28:15 +00:00
|
|
|
} while (frameCount < frames);
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now is the time to put in the turn frames
|
|
|
|
// for the last turn
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (frames < _framesPerStep) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// this ensures that we don't put in
|
|
|
|
// turn frames for this walk or the
|
|
|
|
// next
|
2003-10-12 14:40:04 +00:00
|
|
|
_currentDir = 99;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_currentDir != 99)
|
|
|
|
lastRealDir = _currentDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// check each turn condition in turn
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// only for george
|
2003-10-12 14:40:04 +00:00
|
|
|
if (lastDir != 99 && _currentDir != 99 && _usingWalkingTurnFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// 1 and -7 going right -1 and 7 going
|
|
|
|
// left
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _currentDir - lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (lastDir == -1 || lastDir == 7 || lastDir == -2 || lastDir == 6) {
|
|
|
|
// turn at the end of the last
|
|
|
|
// walk
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_frame = _lastCount - _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
|
|
|
// turning left
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_frame].frame += _firstWalkingTurnLeftFrame;
|
|
|
|
_frame++;
|
|
|
|
} while (_frame < _lastCount);
|
2003-09-20 15:34:53 +00:00
|
|
|
} else if (lastDir == 1 || lastDir == -7 || lastDir == 2 || lastDir == -6) {
|
|
|
|
// turn at the end of the
|
|
|
|
// current walk
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_frame = _lastCount - _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
|
|
|
// turning right
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_frame].frame += _firstWalkingTurnRightFrame;
|
|
|
|
_frame++;
|
|
|
|
} while (_frame < _lastCount);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _currentDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// all turns checked
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_lastCount = _stepCount;
|
|
|
|
_moduleX = walkAnim[_stepCount - 1].x;
|
|
|
|
_moduleY = walkAnim[_stepCount - 1].y;
|
|
|
|
module16X = _moduleX << 16;
|
|
|
|
module16Y = _moduleY << 16;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (_modularPath[p].dir < NO_DIRECTIONS);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-07-30 19:25:31 +00:00
|
|
|
#ifdef _SWORD2_DEBUG
|
2003-07-28 01:44:38 +00:00
|
|
|
if (lastRealDir == 99)
|
2003-10-26 15:42:49 +00:00
|
|
|
error("slidyWalkAnimatorlast direction error");
|
2003-07-28 01:44:38 +00:00
|
|
|
#endif
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SLOW OUT
|
2003-10-12 14:40:04 +00:00
|
|
|
addSlowOutFrames(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// TURNS TO END THE WALK ?
|
|
|
|
|
|
|
|
// We've done the walk now put in any turns at the end
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_targetDir == 8) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// ANY direction -> stand in the last direction
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandFrame + lastRealDir;
|
|
|
|
_targetDir = lastRealDir;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastRealDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_targetDir == 9) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// 'stance' was non-zero
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_stepCount == 0) {
|
|
|
|
module = _framesPerChar + lastRealDir;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastRealDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-12 14:40:04 +00:00
|
|
|
} else if (_targetDir != lastRealDir) {
|
2003-07-28 01:44:38 +00:00
|
|
|
// rotate to target direction
|
2003-10-12 14:40:04 +00:00
|
|
|
turnDir = _targetDir - lastRealDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
if ( turnDir < 0)
|
2003-09-20 15:34:53 +00:00
|
|
|
turnDir += NO_DIRECTIONS;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
if (turnDir > 4)
|
|
|
|
turnDir = -1;
|
|
|
|
else if (turnDir > 0)
|
|
|
|
turnDir = 1;
|
|
|
|
|
|
|
|
// rotate to target direction
|
|
|
|
// for george and nico put in a head turn at the start
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingStandingTurnFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// new frames for turn frames 29oct95jps
|
|
|
|
if (turnDir < 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnLeftFrame + lastDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnRightFrame + lastDir;
|
|
|
|
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastRealDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// rotate if we need to
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
while (lastRealDir != _targetDir) {
|
2003-07-28 01:44:38 +00:00
|
|
|
lastRealDir += turnDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// new frames for turn frames 29oct95jps
|
|
|
|
if (turnDir < 0) {
|
|
|
|
if (lastRealDir < 0)
|
2003-09-19 15:01:49 +00:00
|
|
|
lastRealDir += NO_DIRECTIONS;
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnLeftFrame + lastRealDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
if (lastRealDir > 7)
|
2003-09-19 15:01:49 +00:00
|
|
|
lastRealDir -= NO_DIRECTIONS;
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnRightFrame + lastRealDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastRealDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandFrame + lastRealDir;
|
|
|
|
walkAnim[_stepCount - 1].frame = module;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
// just stand at the end
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandFrame + lastRealDir;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastRealDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = 512;
|
|
|
|
walkAnim[_stepCount].step = 99;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = 512;
|
|
|
|
walkAnim[_stepCount].step = 99;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = 512;
|
|
|
|
walkAnim[_stepCount].step = 99;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// write all the frames to "debug.txt"
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "THE WALKDATA:");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (_frame = 0; _frame <= _stepCount; _frame++)
|
|
|
|
debug(5, "walkAnim[%d].frame=%d", _frame, walkAnim[_frame].frame);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "routeFinder RouteSize is %d", _stepCount);
|
2003-07-28 01:44:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
#ifndef FORCE_SLIDY
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SOLID PATH ROUTINES
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::solidPath() {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* SolidPath creates a path based on whole steps with no sliding to
|
|
|
|
* get as near as possible to the target without any sliding this
|
|
|
|
* routine is currently unused, but is intended for use when just
|
|
|
|
* clicking about.
|
|
|
|
*
|
|
|
|
* produce a module list from the line data
|
|
|
|
*********************************************************************/
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 smooth;
|
|
|
|
int32 solid;
|
|
|
|
int32 scale;
|
|
|
|
int32 stepX;
|
|
|
|
int32 stepY;
|
|
|
|
int32 deltaX;
|
|
|
|
int32 deltaY;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// strip out the short sections
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
solid = 1;
|
|
|
|
smooth = 1;
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[0].x = _smoothPath[0].x;
|
|
|
|
_modularPath[0].y = _smoothPath[0].y;
|
|
|
|
_modularPath[0].dir = _smoothPath[0].dir;
|
|
|
|
_modularPath[0].num = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
scale = _scaleA * _smoothPath[smooth].y + _scaleB;
|
|
|
|
deltaX = _smoothPath[smooth].x - _modularPath[solid - 1].x;
|
|
|
|
deltaY = _smoothPath[smooth].y - _modularPath[solid - 1].y;
|
|
|
|
stepX = _modX[_smoothPath[smooth].dir];
|
|
|
|
stepY = _modY[_smoothPath[smooth].dir];
|
2003-07-28 01:44:38 +00:00
|
|
|
stepX = stepX * scale;
|
|
|
|
stepY = stepY * scale;
|
|
|
|
stepX = stepX >> 16;
|
|
|
|
stepY = stepY >> 16;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-09-24 06:40:23 +00:00
|
|
|
if (ABS(deltaX) >= ABS(stepX) && ABS(deltaY) >= ABS(stepY)) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[solid].x = _smoothPath[smooth].x;
|
|
|
|
_modularPath[solid].y = _smoothPath[smooth].y;
|
|
|
|
_modularPath[solid].dir = _smoothPath[smooth].dir;
|
|
|
|
_modularPath[solid].num = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
solid++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
smooth++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (_smoothPath[smooth].num < ROUTE_END_FLAG);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// in case the last bit had no steps
|
|
|
|
|
|
|
|
if (solid == 1) {
|
|
|
|
// there were no paths so put in a dummy end
|
|
|
|
solid = 2;
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[1].dir = _smoothPath[0].dir;
|
|
|
|
_modularPath[1].num = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[solid - 1].x = _smoothPath[smooth - 1].x;
|
|
|
|
_modularPath[solid - 1].y = _smoothPath[smooth - 1].y;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// set up the end of the walk
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[solid].x = _smoothPath[smooth - 1].x;
|
|
|
|
_modularPath[solid].y = _smoothPath[smooth - 1].y;
|
|
|
|
_modularPath[solid].dir = 9;
|
|
|
|
_modularPath[solid].num = ROUTE_END_FLAG;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
return 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::solidWalkAnimator(_walkData *walkAnim) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* SolidWalk creates an animation based on whole steps with no sliding
|
|
|
|
* to get as near as possible to the target without any sliding. This
|
|
|
|
* routine is is intended for use when just clicking about.
|
|
|
|
*
|
|
|
|
* produce a module list from the line data
|
|
|
|
*
|
|
|
|
* returns 0 if solid route not found
|
|
|
|
*********************************************************************/
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
int32 p;
|
|
|
|
int32 i;
|
|
|
|
int32 left;
|
|
|
|
int32 lastDir;
|
|
|
|
int32 turnDir;
|
|
|
|
int32 scale;
|
|
|
|
int32 step;
|
|
|
|
int32 module;
|
|
|
|
int32 module16X;
|
|
|
|
int32 module16Y;
|
|
|
|
int32 errorX;
|
|
|
|
int32 errorY;
|
|
|
|
int32 moduleEnd;
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 slowStart = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// start at the beginning for a change
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _modularPath[0].dir;
|
2003-07-28 01:44:38 +00:00
|
|
|
p = 1;
|
2003-10-12 14:40:04 +00:00
|
|
|
_currentDir = _modularPath[1].dir;
|
|
|
|
module = _framesPerChar + lastDir;
|
|
|
|
_moduleX = _startX;
|
|
|
|
_moduleY = _startY;
|
|
|
|
module16X = _moduleX << 16;
|
|
|
|
module16Y = _moduleY << 16;
|
|
|
|
_stepCount = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY
|
|
|
|
// BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED
|
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SOLID: STARTING THE WALK");
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// TURN TO START THE WALK
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SOLID: TURNING TO START THE WALK");
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// rotate if we need to
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (lastDir != _currentDir) {
|
2003-07-28 01:44:38 +00:00
|
|
|
// get the direction to turn
|
2003-10-12 14:40:04 +00:00
|
|
|
turnDir = _currentDir - lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
if (turnDir < 0)
|
|
|
|
turnDir += NO_DIRECTIONS;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
if (turnDir > 4)
|
|
|
|
turnDir = -1;
|
|
|
|
else if (turnDir > 0)
|
|
|
|
turnDir = 1;
|
|
|
|
|
|
|
|
// rotate to new walk direction
|
|
|
|
// for george and nico put in a head turn at the start
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingStandingTurnFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// new frames for turn frames 29oct95jps
|
|
|
|
if (turnDir < 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnLeftFrame + lastDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnRightFrame + lastDir;
|
|
|
|
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// rotate till were facing new dir then go back 45 degrees
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
while (lastDir != _currentDir) {
|
2003-07-28 01:44:38 +00:00
|
|
|
lastDir += turnDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// new frames for turn frames 29oct95jps
|
|
|
|
if (turnDir < 0) {
|
|
|
|
if (lastDir < 0)
|
|
|
|
lastDir += NO_DIRECTIONS;
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnLeftFrame + lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
2003-07-28 01:44:38 +00:00
|
|
|
if ( lastDir > 7)
|
2003-09-20 15:34:53 +00:00
|
|
|
lastDir -= NO_DIRECTIONS;
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _firstStandingTurnRightFrame + lastDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = lastDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// the back 45 degrees bit
|
2003-09-20 15:34:53 +00:00
|
|
|
// step back one because new head turn for george takes us
|
|
|
|
// past the new dir
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_stepCount--;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SLOW IN
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
slowStart = addSlowInFrames(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// THE WALK
|
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "SOLID: THE WALK");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// start the walk on the left or right leg, depending on how the
|
|
|
|
// slow-in frames were drawn
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// (0 = left; 1 = right)
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_leadingLeg[_currentDir] == 0) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// start the walk on the left leg (ie. at beginning of the
|
|
|
|
// first step of the walk cycle)
|
|
|
|
left = 0;
|
|
|
|
} else {
|
|
|
|
// start the walk on the right leg (ie. at beginning of the
|
|
|
|
// second step of the walk cycle)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_lastCount = _stepCount;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// this ensures that we don't put in turn frames for the start
|
|
|
|
lastDir = 99;
|
|
|
|
|
|
|
|
// this ensures that we don't put in turn frames for the start
|
2003-10-12 14:40:04 +00:00
|
|
|
_currentDir = 99;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
while (_modularPath[p].num > 0) {
|
|
|
|
_currentDir = _modularPath[p].dir;
|
|
|
|
if (_currentDir < NO_DIRECTIONS) {
|
|
|
|
module = _currentDir * _framesPerStep * 2 + left;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
if (left == 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
|
|
|
left = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
moduleEnd = module + _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
step = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
scale = (_scaleA * _moduleY + _scaleB);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
module16X += _dx[module] * scale;
|
|
|
|
module16Y += _dy[module] * scale;
|
|
|
|
_moduleX = module16X >> 16;
|
|
|
|
_moduleY = module16Y >> 16;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = step; // normally 0,1,2,3,4,5,0,1,2,etc
|
|
|
|
walkAnim[_stepCount].dir = _currentDir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-09-20 15:34:53 +00:00
|
|
|
module++;
|
|
|
|
step++;
|
2003-10-05 15:28:15 +00:00
|
|
|
} while (module < moduleEnd);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
errorX = _modularPath[p].x - _moduleX;
|
|
|
|
errorX = errorX * _modX[_modularPath[p].dir];
|
|
|
|
errorY = _modularPath[p].y - _moduleY;
|
|
|
|
errorY = errorY * _modY[_modularPath[p].dir];
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (errorX < 0 || errorY < 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_modularPath[p].num = 0;
|
|
|
|
_stepCount -= _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
if (left == 0)
|
2003-10-12 14:40:04 +00:00
|
|
|
left = _framesPerStep;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
|
|
|
left = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// Okay this is the end of a section
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_moduleX = walkAnim[_stepCount - 1].x;
|
|
|
|
_moduleY = walkAnim[_stepCount - 1].y;
|
|
|
|
module16X = _moduleX << 16;
|
|
|
|
module16Y = _moduleY << 16;
|
|
|
|
_modularPath[p].x = _moduleX;
|
|
|
|
_modularPath[p].y = _moduleY;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// Now is the time to put in the turn
|
|
|
|
// frames for the last turn
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_stepCount - _lastCount < _framesPerStep) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// no step taken
|
|
|
|
|
|
|
|
// clean up if a slow in but no
|
|
|
|
// walk
|
|
|
|
|
|
|
|
if (slowStart == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_stepCount -= _numberOfSlowInFrames[_currentDir];
|
|
|
|
_lastCount -= _numberOfSlowInFrames[_currentDir];
|
2003-07-28 01:44:38 +00:00
|
|
|
slowStart = 0;
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// this ensures that we don't
|
|
|
|
// put in turn frames for this
|
|
|
|
// walk or the next
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_currentDir = 99;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// check each turn condition in turn
|
2003-10-12 14:40:04 +00:00
|
|
|
if (lastDir != 99 && _currentDir != 99 && _usingWalkingTurnFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// only for george
|
|
|
|
// 1 and -7 going right -1 and
|
|
|
|
// 7 going left
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _currentDir - lastDir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (lastDir == -1 || lastDir == 7 || lastDir == -2 || lastDir == 6) {
|
|
|
|
// turn at the end of
|
|
|
|
// the last walk
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_frame = _lastCount - _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
// turning left
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_frame].frame += _firstWalkingTurnLeftFrame;
|
|
|
|
_frame++;
|
|
|
|
} while (_frame < _lastCount);
|
2003-09-20 15:34:53 +00:00
|
|
|
} else if (lastDir == 1 || lastDir == -7 || lastDir == 2 || lastDir == -6) {
|
|
|
|
// turn at the end of
|
|
|
|
// the current walk
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_frame = _lastCount - _framesPerStep;
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
|
|
|
// turning right
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_frame].frame += _firstWalkingTurnRightFrame;
|
|
|
|
_frame++;
|
|
|
|
} while (_frame < _lastCount);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// all turns checked
|
2003-10-12 14:40:04 +00:00
|
|
|
_lastCount = _stepCount;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
p++;
|
2003-10-12 14:40:04 +00:00
|
|
|
lastDir = _currentDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// can only be valid first time round
|
|
|
|
slowStart = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (_modularPath[p].dir < NO_DIRECTIONS);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SLOW OUT
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
addSlowOutFrames(walkAnim);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
module = _framesPerChar + _modularPath[p - 1].dir;
|
|
|
|
walkAnim[_stepCount].frame = module;
|
|
|
|
walkAnim[_stepCount].step = 0;
|
|
|
|
walkAnim[_stepCount].dir = _modularPath[p - 1].dir;
|
|
|
|
walkAnim[_stepCount].x = _moduleX;
|
|
|
|
walkAnim[_stepCount].y = _moduleY;
|
|
|
|
_stepCount++;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = 512;
|
|
|
|
walkAnim[_stepCount].step = 99;
|
|
|
|
_stepCount++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = 512;
|
|
|
|
walkAnim[_stepCount].step = 99;
|
|
|
|
_stepCount++;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
walkAnim[_stepCount].frame = 512;
|
|
|
|
walkAnim[_stepCount].step = 99;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "THE WALKDATA:");
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (_frame = 0; _frame <= _stepCount; _frame++)
|
|
|
|
debug(5, "walkAnim[%d].frame=%d", _frame, walkAnim[_frame].frame);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// NO END TURNS
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "routeFinder RouteSize is %d", _stepCount);
|
2003-09-20 15:34:53 +00:00
|
|
|
// now check the route
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
if (!check(_modularPath[i].x, _modularPath[i].y, _modularPath[i + 1].x, _modularPath[i + 1].y))
|
2003-09-20 15:34:53 +00:00
|
|
|
p = 0;
|
|
|
|
i++;
|
|
|
|
} while (i < p - 1);
|
|
|
|
|
|
|
|
if (p != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
_targetDir = _modularPath[p - 1].dir;
|
|
|
|
if (checkTarget(_moduleX, _moduleY) == 3) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// new target on a line
|
|
|
|
p = 0;
|
2003-10-12 14:40:04 +00:00
|
|
|
debug(5, "Solid walk target was on a line %d %d", _moduleX, _moduleY);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
2003-10-12 14:40:04 +00:00
|
|
|
#endif
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SCAN ROUTINES
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::scan(int32 level) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
2003-10-12 14:40:04 +00:00
|
|
|
* Called successively from routeFinder until no more changes take
|
2003-09-20 15:34:53 +00:00
|
|
|
* place in the grid array, ie he best path has been found
|
|
|
|
*
|
|
|
|
* Scans through every point in the node array and checks if there is
|
|
|
|
* a route between each point and if this route gives a new route.
|
|
|
|
*
|
|
|
|
* This routine could probably halve its processing time if it doubled
|
|
|
|
* up on the checks after each route check
|
|
|
|
*
|
|
|
|
*********************************************************************/
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 i;
|
|
|
|
int32 k;
|
|
|
|
int32 x1;
|
|
|
|
int32 y1;
|
|
|
|
int32 x2;
|
|
|
|
int32 y2;
|
|
|
|
int32 distance;
|
|
|
|
int32 changed = 0;
|
|
|
|
|
|
|
|
// For all the nodes that have new values and a distance less than
|
|
|
|
// enddist, ie dont check for new routes from a point we checked
|
|
|
|
// before or from a point that is already further away than the best
|
|
|
|
// route so far.
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
i = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_node[i].dist < _node[_nnodes].dist && _node[i].level == level) {
|
|
|
|
x1 = _node[i].x;
|
|
|
|
y1 = _node[i].y;
|
|
|
|
k = _nnodes;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_node[k].dist > _node[i].dist) {
|
|
|
|
x2 = _node[k].x;
|
|
|
|
y2 = _node[k].y;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-24 06:40:23 +00:00
|
|
|
if (ABS(x2 - x1) > 4.5 * ABS(y2-y1))
|
|
|
|
distance = (8 * ABS(x2 - x1) + 18 * ABS(y2 - y1)) / (54 * 8) + 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
else
|
2003-09-24 06:40:23 +00:00
|
|
|
distance = (6 * ABS(x2 - x1) + 36 * ABS(y2 - y1)) / (36 * 14) + 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (distance + _node[i].dist < _node[_nnodes].dist && distance + _node[i].dist < _node[k].dist) {
|
|
|
|
if (newCheck(0, x1, y1, x2, y2)) {
|
|
|
|
_node[k].level = level + 1;
|
|
|
|
_node[k].dist = distance + _node[i].dist;
|
|
|
|
_node[k].prev = i;
|
2003-07-28 01:44:38 +00:00
|
|
|
changed = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
k--;
|
|
|
|
} while (k > 0);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
i++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (i < _nnodes);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
2003-10-12 14:40:04 +00:00
|
|
|
* newCheck routine checks if the route between two points can be
|
2003-09-20 15:34:53 +00:00
|
|
|
* achieved without crossing any of the bars in the Bars array.
|
|
|
|
*
|
2003-10-12 14:40:04 +00:00
|
|
|
* newCheck differs from check in that that 4 route options are
|
2003-09-20 15:34:53 +00:00
|
|
|
* considered corresponding to actual walked routes.
|
|
|
|
*
|
|
|
|
* Note distance doesnt take account of shrinking ???
|
|
|
|
*
|
|
|
|
* Note Bars array must be properly calculated ie min max dx dy co
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
int32 ldx;
|
|
|
|
int32 ldy;
|
|
|
|
int32 dlx;
|
|
|
|
int32 dly;
|
|
|
|
int32 dirX;
|
|
|
|
int32 dirY;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 step1;
|
|
|
|
int32 step2;
|
|
|
|
int32 step3;
|
|
|
|
int32 steps;
|
|
|
|
int32 options;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
steps = 0;
|
|
|
|
options = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
ldx = x2 - x1;
|
|
|
|
ldy = y2 - y1;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirX = 1;
|
|
|
|
dirY = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (ldx < 0) {
|
2003-07-28 12:24:13 +00:00
|
|
|
ldx = -ldx;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirX = -1;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (ldy < 0) {
|
2003-07-28 12:24:13 +00:00
|
|
|
ldy = -ldy;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirY = -1;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// make the route options
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_diagonaly * ldx > _diagonalx * ldy) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// dir = 1,2 or 2,3 or 5,6 or 6,7
|
|
|
|
|
|
|
|
dly = ldy;
|
2003-10-12 14:40:04 +00:00
|
|
|
dlx = (ldy * _diagonalx) / _diagonaly;
|
2003-07-28 12:24:13 +00:00
|
|
|
ldx = ldx - dlx;
|
2003-07-28 01:44:38 +00:00
|
|
|
dlx = dlx * dirX;
|
|
|
|
dly = dly * dirY;
|
2003-07-28 12:24:13 +00:00
|
|
|
ldx = ldx * dirX;
|
|
|
|
ldy = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
//options are
|
|
|
|
//square, diagonal a code 1 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x1 + ldx, y1);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1 + ldx, y1, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
|
|
|
steps = step1 + step2;
|
2003-07-28 01:44:38 +00:00
|
|
|
options = options + 2;
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
//diagonal, square a code 2 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (steps == 0 || status == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x1 + dlx, y1 + dly);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1 + dlx, y2, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
|
|
|
steps = step1 + step2;
|
2003-07-28 01:44:38 +00:00
|
|
|
options = options + 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
//halfsquare, diagonal, halfsquare a code 0 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (steps == 0 || status == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x1 + ldx / 2, y1);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1 + ldx / 2, y1, x1 + ldx / 2 + dlx, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step3 = check(x1 + ldx / 2 + dlx, y2, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step3 != 0) {
|
|
|
|
steps = step1 + step2 + step3;
|
|
|
|
options++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
//halfdiagonal, square, halfdiagonal a code 3 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (steps == 0 || status == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + ldx + dlx / 2, y1 + dly / 2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step3 = check(x1 + ldx + dlx / 2, y1 + dly / 2, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step3 != 0) {
|
|
|
|
steps = step1 + step2 + step3;
|
2003-07-28 01:44:38 +00:00
|
|
|
options = options + 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
// dir = 7,0 or 0,1 or 3,4 or 4,5
|
|
|
|
|
|
|
|
dlx = ldx;
|
2003-10-12 14:40:04 +00:00
|
|
|
dly = (ldx * _diagonaly) / _diagonalx;
|
2003-07-28 12:24:13 +00:00
|
|
|
ldy = ldy - dly;
|
2003-07-28 01:44:38 +00:00
|
|
|
dlx = dlx * dirX;
|
|
|
|
dly = dly * dirY;
|
2003-07-28 12:24:13 +00:00
|
|
|
ldy = ldy * dirY;
|
|
|
|
ldx = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
//options are
|
|
|
|
//square, diagonal a code 1 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1 ,y1, x1, y1 + ldy);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1, y1 + ldy, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
|
|
|
steps = step1 + step2;
|
2003-07-28 01:44:38 +00:00
|
|
|
options = options + 2;
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
//diagonal, square a code 2 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (steps == 0 || status == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x2, y1 + dly);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x2, y1 + dly, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
|
|
|
steps = step1 + step2;
|
2003-07-28 01:44:38 +00:00
|
|
|
options = options + 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
//halfsquare, diagonal, halfsquare a code 0 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (steps == 0 || status == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x1, y1 + ldy / 2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1, y1 + ldy / 2, x2, y1 + ldy / 2 + dly);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step3 = check(x2, y1 + ldy / 2 + dly, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step3 != 0) {
|
|
|
|
steps = step1 + step2 + step3;
|
|
|
|
options++;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
//halfdiagonal, square, halfdiagonal a code 3 route
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (steps == 0 || status == 1) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step1 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + dlx / 2, y1 + ldy + dly / 2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step2 != 0) {
|
2003-10-12 14:40:04 +00:00
|
|
|
step3 = check(x1 + dlx / 2, y1 + ldy + dly / 2, x2, y2);
|
2003-09-20 15:34:53 +00:00
|
|
|
if (step3 != 0) {
|
|
|
|
steps = step1 + step2 + step3;
|
2003-07-28 01:44:38 +00:00
|
|
|
options = options + 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
if (status == 0)
|
|
|
|
status = steps;
|
|
|
|
else
|
|
|
|
status = options;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// CHECK ROUTINES
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::check(int32 x1, int32 y1, int32 x2, int32 y2) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// call the fastest line check for the given line
|
|
|
|
// returns 1 if line didn't cross any bars
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (x1 == x2 && y1 == y2)
|
|
|
|
return 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (x1 == x2)
|
2003-10-12 14:40:04 +00:00
|
|
|
return vertCheck(x1, y1, y2);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
if (y1 == y2)
|
2003-10-12 14:40:04 +00:00
|
|
|
return horizCheck(x1, y1, x2);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
return lineCheck(x1, y1, x2, y2);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::lineCheck(int32 x1, int32 y1, int32 x2, int32 y2) {
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 dirx;
|
|
|
|
int32 diry;
|
|
|
|
int32 co;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 slope;
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 i;
|
|
|
|
int32 xc;
|
|
|
|
int32 yc;
|
|
|
|
int32 xmin;
|
|
|
|
int32 ymin;
|
|
|
|
int32 xmax;
|
|
|
|
int32 ymax;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 linesCrossed = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (x1 > x2) {
|
2003-10-01 10:00:35 +00:00
|
|
|
xmin = x2;
|
2003-09-20 15:34:53 +00:00
|
|
|
xmax = x1;
|
|
|
|
} else {
|
2003-10-01 10:00:35 +00:00
|
|
|
xmin = x1;
|
|
|
|
xmax = x2;
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (y1 > y2) {
|
2003-10-01 10:00:35 +00:00
|
|
|
ymin = y2;
|
2003-09-20 15:34:53 +00:00
|
|
|
ymax = y1;
|
|
|
|
} else {
|
2003-10-01 10:00:35 +00:00
|
|
|
ymin = y1;
|
|
|
|
ymax = y2;
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// line set to go one step in chosen direction
|
|
|
|
// so ignore if it hits anything
|
|
|
|
|
|
|
|
dirx = x2 - x1;
|
2003-07-28 01:44:38 +00:00
|
|
|
diry = y2 - y1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
co = (y1 * dirx)- (x1 * diry); // new line equation
|
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
i = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
// skip if not on module
|
2003-10-12 14:40:04 +00:00
|
|
|
if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// skip if not on module
|
2003-10-12 14:40:04 +00:00
|
|
|
if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) {
|
2003-11-07 01:36:53 +00:00
|
|
|
// okay its a valid line calculate an intercept
|
|
|
|
// wow but all this arithmetic we must have
|
2003-09-20 15:34:53 +00:00
|
|
|
// loads of time
|
|
|
|
|
|
|
|
// slope it he slope between the two lines
|
2003-10-12 14:40:04 +00:00
|
|
|
slope = (_bars[i].dx * diry) - (_bars[i].dy *dirx);
|
2003-09-20 15:34:53 +00:00
|
|
|
// assuming parallel lines don't cross
|
|
|
|
if (slope != 0) {
|
|
|
|
// calculate x intercept and check its
|
|
|
|
// on both lines
|
2003-10-12 14:40:04 +00:00
|
|
|
xc = ((_bars[i].co * dirx) - (co * _bars[i].dx)) / slope;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// skip if not on module
|
2003-10-01 10:00:35 +00:00
|
|
|
if (xc >= xmin - 1 && xc <= xmax + 1) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// skip if not on line
|
2003-10-12 14:40:04 +00:00
|
|
|
if (xc >= _bars[i].xmin - 1 && xc <= _bars[i].xmax + 1) {
|
|
|
|
yc = ((_bars[i].co * diry) - (co * _bars[i].dy)) / slope;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// skip if not on module
|
|
|
|
if (yc >= ymin - 1 && yc <= ymax + 1) {
|
|
|
|
// skip if not on line
|
2003-10-12 14:40:04 +00:00
|
|
|
if (yc >= _bars[i].ymin - 1 && yc <= _bars[i].ymax + 1) {
|
2003-09-20 15:34:53 +00:00
|
|
|
linesCrossed = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
i++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (i < _nbars && linesCrossed);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
return linesCrossed;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::horizCheck(int32 x1, int32 y, int32 x2) {
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 ldy;
|
|
|
|
int32 i;
|
|
|
|
int32 xc;
|
|
|
|
int32 xmin;
|
|
|
|
int32 xmax;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 linesCrossed = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (x1 > x2) {
|
2003-10-01 10:00:35 +00:00
|
|
|
xmin = x2;
|
2003-09-20 15:34:53 +00:00
|
|
|
xmax = x1;
|
|
|
|
} else {
|
2003-10-01 10:00:35 +00:00
|
|
|
xmin = x1;
|
|
|
|
xmax = x2;
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// line set to go one step in chosen direction
|
|
|
|
// so ignore if it hits anything
|
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
i = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-01 10:00:35 +00:00
|
|
|
// skip if not on module
|
2003-10-12 14:40:04 +00:00
|
|
|
if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) {
|
2003-10-01 10:00:35 +00:00
|
|
|
// skip if not on module
|
2003-10-12 14:40:04 +00:00
|
|
|
if (y >= _bars[i].ymin && y <= _bars[i].ymax) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// okay its a valid line calculate an intercept
|
2003-11-07 01:36:53 +00:00
|
|
|
// wow but all this arithmetic we must have
|
2003-09-20 15:34:53 +00:00
|
|
|
// loads of time
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_bars[i].dy == 0)
|
2003-10-01 10:00:35 +00:00
|
|
|
linesCrossed = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
else {
|
2003-10-12 14:40:04 +00:00
|
|
|
ldy = y - _bars[i].y1;
|
|
|
|
xc = _bars[i].x1 + (_bars[i].dx * ldy) / _bars[i].dy;
|
2003-09-20 15:34:53 +00:00
|
|
|
// skip if not on module
|
2003-10-01 10:00:35 +00:00
|
|
|
if (xc >= xmin - 1 && xc <= xmax + 1)
|
|
|
|
linesCrossed = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
i++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (i < _nbars && linesCrossed);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
return linesCrossed;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::vertCheck(int32 x, int32 y1, int32 y2) {
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 ldx;
|
|
|
|
int32 i;
|
|
|
|
int32 yc;
|
|
|
|
int32 ymin;
|
|
|
|
int32 ymax;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 linesCrossed = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (y1 > y2) {
|
2003-10-01 10:00:35 +00:00
|
|
|
ymin = y2;
|
2003-09-20 15:34:53 +00:00
|
|
|
ymax = y1;
|
|
|
|
} else {
|
2003-10-01 10:00:35 +00:00
|
|
|
ymin = y1;
|
|
|
|
ymax = y2;
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// line set to go one step in chosen direction
|
|
|
|
// so ignore if it hits anything
|
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
i = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
if (x >= _bars[i].xmin && x <= _bars[i].xmax) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// overlapping
|
|
|
|
// skip if not on module
|
2003-10-12 14:40:04 +00:00
|
|
|
if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// okay its a valid line calculate an intercept
|
2003-11-07 01:36:53 +00:00
|
|
|
// wow but all this arithmetic we must have
|
2003-09-20 15:34:53 +00:00
|
|
|
// loads of time
|
|
|
|
|
|
|
|
// both lines vertical and overlap in x and y
|
|
|
|
// so they cross
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_bars[i].dx == 0)
|
2003-09-20 15:34:53 +00:00
|
|
|
linesCrossed = 0;
|
|
|
|
else {
|
2003-10-12 14:40:04 +00:00
|
|
|
ldx = x - _bars[i].x1;
|
|
|
|
yc = _bars[i].y1 + (_bars[i].dy * ldx) / _bars[i].dx;
|
2003-09-20 15:34:53 +00:00
|
|
|
// the intercept overlaps
|
|
|
|
if (yc >= ymin - 1 && yc <= ymax + 1)
|
|
|
|
linesCrossed = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
i++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (i < _nbars && linesCrossed);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
return linesCrossed;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
int32 Router::checkTarget(int32 x, int32 y) {
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 ldx;
|
|
|
|
int32 ldy;
|
|
|
|
int32 i;
|
|
|
|
int32 xc;
|
|
|
|
int32 yc;
|
|
|
|
int32 xmin;
|
|
|
|
int32 xmax;
|
|
|
|
int32 ymin;
|
|
|
|
int32 ymax;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 onLine = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
xmin = x - 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
xmax = x + 1;
|
2003-10-01 10:00:35 +00:00
|
|
|
ymin = y - 1;
|
2003-07-28 01:44:38 +00:00
|
|
|
ymax = y + 1;
|
|
|
|
|
|
|
|
// check if point +- 1 is on the line
|
2003-09-20 15:34:53 +00:00
|
|
|
//so ignore if it hits anything
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-01 10:00:35 +00:00
|
|
|
i = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
do {
|
|
|
|
// overlapping line
|
2003-10-12 14:40:04 +00:00
|
|
|
if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) {
|
2003-09-20 15:34:53 +00:00
|
|
|
//overlapping line
|
2003-10-12 14:40:04 +00:00
|
|
|
if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// okay this line overlaps the target calculate
|
|
|
|
// an y intercept for x
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// vertical line so we know it overlaps y
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_bars[i].dx == 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
yc = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
else {
|
2003-10-12 14:40:04 +00:00
|
|
|
ldx = x - _bars[i].x1;
|
|
|
|
yc = _bars[i].y1 + (_bars[i].dy * ldx) / _bars[i].dx;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// overlapping point for y
|
|
|
|
if (yc >= ymin && yc <= ymax) {
|
|
|
|
// target on a line so drop out
|
|
|
|
onLine = 3;
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "RouteFail due to target on a line %d %d", x, y);
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
// vertical line so we know it overlaps y
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_bars[i].dy == 0)
|
2003-07-28 01:44:38 +00:00
|
|
|
xc = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
else {
|
2003-10-12 14:40:04 +00:00
|
|
|
ldy = y - _bars[i].y1;
|
|
|
|
xc = _bars[i].x1 + (_bars[i].dx * ldy) / _bars[i].dy;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// skip if not on module
|
|
|
|
if (xc >= xmin && xc <= xmax) {
|
|
|
|
// target on a line so drop out
|
|
|
|
onLine = 3;
|
2003-09-27 11:02:58 +00:00
|
|
|
debug(5, "RouteFail due to target on a line %d %d", x, y);
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (i < _nbars && onLine == 0);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
return onLine;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE SETUP ROUTINES
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::loadWalkData(Object_walkdata *ob_walkdata) {
|
|
|
|
int i;
|
2003-09-20 15:34:53 +00:00
|
|
|
uint16 firstFrameOfDirection;
|
|
|
|
uint16 walkFrameNo;
|
2003-10-12 14:40:04 +00:00
|
|
|
uint32 frameCounter = 0; // starts at frame 0 of mega set
|
2003-10-01 10:00:35 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_nWalkFrames = ob_walkdata->nWalkFrames;
|
|
|
|
_usingStandingTurnFrames = ob_walkdata->usingStandingTurnFrames;
|
|
|
|
_usingWalkingTurnFrames = ob_walkdata->usingWalkingTurnFrames;
|
|
|
|
_usingSlowInFrames = ob_walkdata->usingSlowInFrames;
|
|
|
|
_usingSlowOutFrames = ob_walkdata->usingSlowOutFrames;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// 0 = not using slow out frames; non-zero = using that many frames
|
|
|
|
// for each leading leg for each direction
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_numberOfSlowOutFrames = _usingSlowOutFrames;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
memcpy(&_numberOfSlowInFrames[0], ob_walkdata->nSlowInFrames, NO_DIRECTIONS * sizeof(_numberOfSlowInFrames[0]));
|
|
|
|
memcpy(&_leadingLeg[0], ob_walkdata->leadingLeg, NO_DIRECTIONS * sizeof(_leadingLeg[0]));
|
|
|
|
memcpy(&_dx[0], ob_walkdata->dx, NO_DIRECTIONS * (_nWalkFrames + 1) * sizeof(_dx[0]));
|
|
|
|
memcpy(&_dy[0], ob_walkdata->dy, NO_DIRECTIONS * (_nWalkFrames + 1) * sizeof(_dy[0]));
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (i = 0; i < NO_DIRECTIONS; i++) {
|
|
|
|
firstFrameOfDirection = i * _nWalkFrames;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_modX[i] = 0;
|
|
|
|
_modY[i] = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (walkFrameNo = firstFrameOfDirection; walkFrameNo < firstFrameOfDirection + _nWalkFrames / 2; walkFrameNo++) {
|
|
|
|
// eg. _modX[0] is the sum of the x-step sizes for the
|
2003-09-20 15:34:53 +00:00
|
|
|
// first half of the walk cycle for direction 0
|
2003-10-12 14:40:04 +00:00
|
|
|
_modX[i] += _dx[walkFrameNo];
|
|
|
|
_modY[i] += _dy[walkFrameNo];
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_diagonalx = _modX[3];
|
|
|
|
_diagonaly = _modY[3];
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// interpret the walk data
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_framesPerStep = _nWalkFrames / 2;
|
|
|
|
_framesPerChar = _nWalkFrames * NO_DIRECTIONS;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// offset pointers added Oct 30 95 JPS
|
|
|
|
// mega id references removed 16sep96 by JEL
|
|
|
|
|
|
|
|
// WALK FRAMES
|
|
|
|
// start on frame 0
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
frameCounter += _framesPerChar;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// STAND FRAMES
|
2003-09-20 15:34:53 +00:00
|
|
|
// stand frames come after the walk frames
|
|
|
|
// one stand frame for each direction
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_firstStandFrame = frameCounter;
|
2003-09-20 15:34:53 +00:00
|
|
|
frameCounter += NO_DIRECTIONS;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// STANDING TURN FRAMES - OPTIONAL!
|
2003-09-20 15:34:53 +00:00
|
|
|
// standing turn-left frames come after the slow-out frames
|
|
|
|
// one for each direction
|
|
|
|
// standing turn-left frames come after the standing turn-right frames
|
|
|
|
// one for each direction
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingStandingTurnFrames) {
|
|
|
|
_firstStandingTurnLeftFrame = frameCounter;
|
2003-09-20 15:34:53 +00:00
|
|
|
frameCounter += NO_DIRECTIONS;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_firstStandingTurnRightFrame = frameCounter;
|
2003-09-20 15:34:53 +00:00
|
|
|
frameCounter += NO_DIRECTIONS;
|
|
|
|
} else {
|
|
|
|
// refer instead to the normal stand frames
|
2003-10-12 14:40:04 +00:00
|
|
|
_firstStandingTurnLeftFrame = _firstStandFrame;
|
|
|
|
_firstStandingTurnRightFrame = _firstStandFrame;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// WALKING TURN FRAMES - OPTIONAL!
|
2003-09-20 15:34:53 +00:00
|
|
|
// walking left-turn frames come after the stand frames
|
|
|
|
// walking right-turn frames come after the walking left-turn frames
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingWalkingTurnFrames) {
|
|
|
|
_firstWalkingTurnLeftFrame = frameCounter;
|
|
|
|
frameCounter += _framesPerChar;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_firstWalkingTurnRightFrame = frameCounter;
|
|
|
|
frameCounter += _framesPerChar;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
2003-10-12 14:40:04 +00:00
|
|
|
_firstWalkingTurnLeftFrame = 0;
|
|
|
|
_firstWalkingTurnRightFrame = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// SLOW-IN FRAMES - OPTIONAL!
|
2003-09-20 15:34:53 +00:00
|
|
|
// slow-in frames come after the walking right-turn frames
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingSlowInFrames) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// Make note of frame number of first slow-in frame for each
|
|
|
|
// direction. There may be a different number of slow-in
|
|
|
|
// frames in each direction
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (i = 0; i < NO_DIRECTIONS; i++) {
|
|
|
|
_firstSlowInFrame[i] = frameCounter;
|
|
|
|
frameCounter += _numberOfSlowInFrames[i];
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// SLOW-OUT FRAMES - OPTIONAL!
|
2003-09-20 15:34:53 +00:00
|
|
|
// slow-out frames come after the slow-in frames
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_usingSlowOutFrames)
|
|
|
|
_firstSlowOutFrame = frameCounter;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// THE ROUTE EXTRACTOR
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::extractRoute() {
|
2003-09-20 15:34:53 +00:00
|
|
|
/*********************************************************************
|
2003-10-12 14:40:04 +00:00
|
|
|
* extractRoute gets route from the node data after a full scan, route
|
2003-09-20 15:34:53 +00:00
|
|
|
* is written with just the basic way points and direction options for
|
|
|
|
* heading to the next point.
|
|
|
|
*********************************************************************/
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 prev;
|
|
|
|
int32 prevx;
|
|
|
|
int32 prevy;
|
|
|
|
int32 last;
|
|
|
|
int32 point;
|
2003-10-01 10:00:35 +00:00
|
|
|
int32 p;
|
2003-09-20 15:34:53 +00:00
|
|
|
int32 dirx;
|
|
|
|
int32 diry;
|
|
|
|
int32 dir;
|
|
|
|
int32 ldx;
|
|
|
|
int32 ldy;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// extract the route from the node data
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
prev = _nnodes;
|
2003-07-28 01:44:38 +00:00
|
|
|
last = prev;
|
|
|
|
point = O_ROUTE_SIZE - 1;
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[point].x = _node[last].x;
|
|
|
|
_route[point].y = _node[last].y;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
point--;
|
2003-10-12 14:40:04 +00:00
|
|
|
prev = _node[last].prev;
|
|
|
|
prevx = _node[prev].x;
|
|
|
|
prevy = _node[prev].y;
|
|
|
|
_route[point].x = prevx;
|
|
|
|
_route[point].y = prevy;
|
2003-07-28 01:44:38 +00:00
|
|
|
last = prev;
|
2003-09-20 15:34:53 +00:00
|
|
|
} while (prev > 0);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// now shuffle route down in the buffer
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_routeLength = 0;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[_routeLength].x = _route[point].x;
|
|
|
|
_route[_routeLength].y = _route[point].y;
|
2003-09-20 15:34:53 +00:00
|
|
|
point++;
|
2003-10-12 14:40:04 +00:00
|
|
|
_routeLength++;
|
2003-09-20 15:34:53 +00:00
|
|
|
} while (point < O_ROUTE_SIZE);
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_routeLength--;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// okay the route exists as a series point now put in some directions
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
p = 0;
|
|
|
|
|
|
|
|
do {
|
2003-10-12 14:40:04 +00:00
|
|
|
ldx = _route[p + 1].x - _route[p].x;
|
|
|
|
ldy = _route[p + 1].y - _route[p].y;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirx = 1;
|
|
|
|
diry = 1;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (ldx < 0) {
|
2003-07-28 12:24:13 +00:00
|
|
|
ldx = -ldx;
|
2003-07-28 01:44:38 +00:00
|
|
|
dirx = -1;
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
if (ldy < 0) {
|
2003-07-28 12:24:13 +00:00
|
|
|
ldy = -ldy;
|
2003-07-28 01:44:38 +00:00
|
|
|
diry = -1;
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_diagonaly * ldx > _diagonalx * ldy) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// dir = 1,2 or 2,3 or 5,6 or 6,7
|
|
|
|
|
|
|
|
// 2 or 6
|
|
|
|
dir = 4 - 2 * dirx;
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[p].dirS = dir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// 1, 3, 5 or 7
|
|
|
|
dir = dir + diry * dirx;
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[p].dirD = dir;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
|
|
|
// dir = 7,0 or 0,1 or 3,4 or 4,5
|
|
|
|
|
|
|
|
// 0 or 4
|
|
|
|
dir = 2 + 2 * diry;
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[p].dirS = dir;
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
// 2 or 6
|
|
|
|
dir = 4 - 2 * dirx;
|
|
|
|
|
|
|
|
// 1, 3, 5 or 7
|
|
|
|
dir = dir + diry * dirx;
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[p].dirD = dir;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
p++;
|
2003-10-12 14:40:04 +00:00
|
|
|
} while (p < _routeLength);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// set the last dir to continue previous route unless specified
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_targetDir == 8) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// ANY direction
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[p].dirS = _route[p - 1].dirS;
|
|
|
|
_route[p].dirD = _route[p - 1].dirD;
|
2003-09-20 15:34:53 +00:00
|
|
|
} else {
|
2003-10-12 14:40:04 +00:00
|
|
|
_route[p].dirS = _targetDir;
|
|
|
|
_route[p].dirD = _targetDir;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::setUpWalkGrid(Object_mega *ob_mega, int32 x, int32 y, int32 dir) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// get walk grid file + extra grid into 'bars' & 'node' arrays
|
2003-10-12 14:40:04 +00:00
|
|
|
loadWalkGrid();
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// copy the mega structure into the local variables for use in all
|
|
|
|
// subroutines
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_startX = ob_mega->feet_x;
|
|
|
|
_startY = ob_mega->feet_y;
|
|
|
|
_startDir = ob_mega->current_dir;
|
|
|
|
_targetX = x;
|
|
|
|
_targetY = y;
|
|
|
|
_targetDir = dir;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_scaleA = ob_mega->scale_a;
|
|
|
|
_scaleB = ob_mega->scale_b;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// mega's current position goes into first node
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_node[0].x = _startX;
|
|
|
|
_node[0].y = _startY;
|
|
|
|
_node[0].level = 1;
|
|
|
|
_node[0].prev = 0;
|
|
|
|
_node[0].dist = 0;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// reset other nodes
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (int i = 1; i < _nnodes; i++) {
|
|
|
|
_node[i].level = 0;
|
|
|
|
_node[i].prev = 0;
|
|
|
|
_node[i].dist = 9999;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// target position goes into final node
|
2003-10-12 14:40:04 +00:00
|
|
|
_node[_nnodes].x = _targetX;
|
|
|
|
_node[_nnodes].y = _targetY;
|
|
|
|
_node[_nnodes].level = 0;
|
|
|
|
_node[_nnodes].prev = 0;
|
|
|
|
_node[_nnodes].dist = 9999;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::plotWalkGrid(void) {
|
|
|
|
int32 i;
|
2003-10-01 10:00:35 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// get walk grid file + extra grid into 'bars' & 'node' arrays
|
2003-10-12 14:40:04 +00:00
|
|
|
loadWalkGrid();
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// lines
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (i = 0; i < _nbars; i++)
|
2003-10-26 15:42:49 +00:00
|
|
|
g_display->drawLine(_bars[i].x1, _bars[i].y1, _bars[i].x2, _bars[i].y2, 254);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-07-28 01:44:38 +00:00
|
|
|
// nodes
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// leave node 0 for start node
|
2003-10-12 14:40:04 +00:00
|
|
|
for (i = 1; i < _nnodes; i++)
|
|
|
|
plotCross(_node[i].x, _node[i].y, 184);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::plotCross(int16 x, int16 y, uint8 colour) {
|
2003-10-26 15:42:49 +00:00
|
|
|
g_display->drawLine(x - 1, y - 1, x + 1, y + 1, colour);
|
|
|
|
g_display->drawLine(x + 1, y - 1, x - 1, y + 1, colour);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::loadWalkGrid(void) {
|
2003-09-20 15:34:53 +00:00
|
|
|
_walkGridHeader floorHeader;
|
|
|
|
uint8 *fPolygrid;
|
2003-07-28 01:44:38 +00:00
|
|
|
uint32 theseBars;
|
|
|
|
uint32 theseNodes;
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_nbars = 0; // reset counts
|
|
|
|
_nnodes = 1; // leave node 0 for start-node
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// STATIC GRIDS (added/removed by object logics)
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// go through walkgrid list
|
2003-10-12 14:40:04 +00:00
|
|
|
for (int i = 0; i < MAX_WALKGRIDS; i++) {
|
|
|
|
if (_walkGridList[i]) {
|
2003-09-20 15:34:53 +00:00
|
|
|
// open walk grid file
|
2003-11-03 07:47:42 +00:00
|
|
|
fPolygrid = res_man->openResource(_walkGridList[i]);
|
2003-07-28 01:44:38 +00:00
|
|
|
fPolygrid += sizeof(_standardHeader);
|
2003-09-20 15:34:53 +00:00
|
|
|
memmove((uint8 *) &floorHeader, fPolygrid, sizeof(_walkGridHeader));
|
2003-07-28 01:44:38 +00:00
|
|
|
fPolygrid += sizeof(_walkGridHeader);
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// how many bars & nodes are we getting from this
|
|
|
|
// walkgrid file
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
theseBars = floorHeader.numBars;
|
|
|
|
theseNodes = floorHeader.numNodes;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
#ifdef _SWORD2_DEBUG
|
|
|
|
// check that we're not going to exceed the max
|
|
|
|
// allowed in the complete walkgrid arrays
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_nbars + theseBars >= O_GRID_SIZE)
|
2003-10-26 15:42:49 +00:00
|
|
|
error("Adding walkgrid(%d): %d+%d bars exceeds max %d",
|
2003-10-12 14:40:04 +00:00
|
|
|
_walkGridList[i], _nbars, theseBars,
|
2003-09-27 11:02:58 +00:00
|
|
|
O_GRID_SIZE);
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
if (_nnodes + theseNodes >= O_GRID_SIZE)
|
2003-10-26 15:42:49 +00:00
|
|
|
error("Adding walkgrid(%d): %d+%d nodes exceeds max %d",
|
2003-10-12 14:40:04 +00:00
|
|
|
_walkGridList[i], _nnodes, theseBars,
|
2003-09-27 11:02:58 +00:00
|
|
|
O_GRID_SIZE);
|
2003-09-20 15:34:53 +00:00
|
|
|
#endif
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// lines
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
memmove((uint8 *) &_bars[_nbars], fPolygrid, theseBars * sizeof(_barData));
|
2003-09-20 15:34:53 +00:00
|
|
|
|
|
|
|
//move pointer to start of node data
|
|
|
|
fPolygrid += theseBars * sizeof(_barData);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// nodes
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// leave node 0 for start node
|
2003-10-12 14:40:04 +00:00
|
|
|
for (uint j = 0; j < theseNodes; j++) {
|
|
|
|
memmove((uint8 *) &_node[_nnodes + j].x, fPolygrid, 2 * sizeof(int16));
|
2003-09-20 15:34:53 +00:00
|
|
|
fPolygrid += 2 * sizeof(int16);
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// close walk grid file
|
2003-11-03 07:47:42 +00:00
|
|
|
res_man->closeResource(_walkGridList[i]);
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// increment counts of total bars & nodes in whole
|
|
|
|
// walkgrid
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
_nbars += theseBars;
|
|
|
|
_nnodes += theseNodes;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// EXTRA GRIDS (moveable grids added by megas)
|
|
|
|
|
2003-09-20 15:34:53 +00:00
|
|
|
// Note that these will be checked against allowed max at the time of
|
|
|
|
// creating them
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// extra lines
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
memmove((uint8 *) &_bars[_nbars], (uint8 *) &_extraBars[0], _nExtraBars * sizeof(_barData));
|
|
|
|
_nbars += _nExtraBars;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
|
|
|
// extra nodes
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
memmove((uint8 *) &_node[_nnodes], (uint8 *) &_extraNode[0], _nExtraNodes * sizeof(_nodeData));
|
|
|
|
_nnodes += _nExtraNodes;
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::clearWalkGridList(void) {
|
|
|
|
memset(_walkGridList, 0, ARRAYSIZE(_walkGridList));
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// called from fnAddWalkGrid
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::addWalkGrid(int32 gridResource) {
|
|
|
|
int i;
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
// First, scan the list to see if this grid is already included
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (i = 0; i < MAX_WALKGRIDS; i++) {
|
|
|
|
if (_walkGridList[i] == gridResource)
|
|
|
|
return;
|
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
// Scan the list for a free slot
|
2003-07-28 01:44:38 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
for (i = 0; i < MAX_WALKGRIDS; i++) {
|
|
|
|
if (_walkGridList[i] == 0) {
|
|
|
|
_walkGridList[i] = gridResource;
|
|
|
|
return;
|
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-12 14:40:04 +00:00
|
|
|
|
2003-10-26 15:42:49 +00:00
|
|
|
error("ERROR: _walkGridList[] full");
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-18 08:11:50 +00:00
|
|
|
// called from fnRemoveWalkGrid
|
2003-09-20 15:34:53 +00:00
|
|
|
|
2003-10-12 14:40:04 +00:00
|
|
|
void Router::removeWalkGrid(int32 gridResource) {
|
|
|
|
for (int i = 0; i < MAX_WALKGRIDS; i++) {
|
|
|
|
if (_walkGridList[i] == gridResource) {
|
|
|
|
// If we've found it in the list, reset entry to zero.
|
|
|
|
// Otherwise just ignore the request.
|
|
|
|
_walkGridList[i] = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-07-28 01:44:38 +00:00
|
|
|
}
|
2003-10-04 00:52:27 +00:00
|
|
|
|
|
|
|
} // End of namespace Sword2
|