[13968] in Athena Bugs
NetProb ticket #2896, decmips 7.7G: cygnus/g++
daemon@ATHENA.MIT.EDU (Mike Barker)
Thu Nov 2 18:02:48 1995
To: bugs@MIT.EDU
Date: Thu, 02 Nov 1995 18:02:24 EST
From: Mike Barker <mbarker@MIT.EDU>
------- Forwarded Message
Received: from PACIFIC-CARRIER-ANNEX.MIT.EDU by po8.MIT.EDU (5.61/4.7) id AA24300; Thu, 2 Nov 95 11:59:03 EST
Received: from ANNEX-V32BIS-07.SLIP.ANDREW.CMU.EDU by MIT.EDU with SMTP
id AA12291; Thu, 2 Nov 95 11:53:25 EST
Received: (from jody@localhost) by cmu.edu (8.6.12/8.6.9) id LAA03502; Thu, 2 Nov 1995 11:38:50 -0500
Date: Thu, 2 Nov 1995 11:38:50 -0500
From: Jody Goldberg <jody@cmu.edu>
Message-Id: <199511021638.LAA03502@cmu.edu>
To: bug-g++@prep.ai.mit.edu, mbarker@MIT.EDU
Subject: Re: NetProb ticket #2896, decmips 7.7G: cygnus/g++
HI there,
Thanks for the bug report (Fri, 9 Jun 1995) outlined below.
This problem was fixed in the current release of gcc (2.7.0). It
compiles your code snippet cleanly.
/////////////////////////////////////////////////////////
> Return-Path: mbarker@mit.edu
> Return-Path: mbarker@mit.edu
> Received: from life.ai.mit.edu (life.ai.mit.edu [128.52.32.80]) by cygnus.com (8.6.12/8.6.9) with SMTP id JAA10666 for <bug-g++-in@cygnus.com>; Fri, 9 Jun 1995 09:26:59 -0700
> From: mbarker@mit.edu
> Received: from MIT.EDU (SOUTH-STATION-ANNEX.MIT.EDU) by life.ai.mit.edu (4.1/AI-4.10) for bug-g++-in@cygnus.com id AA17536; Fri, 9 Jun 95 12:26:54 EDT
> Received: from GULCH.MIT.EDU by MIT.EDU with SMTP
> id AA19350; Fri, 9 Jun 95 12:26:51 EDT
> Received: by gulch.MIT.EDU (5.0/4.7) id AA04114; Fri, 9 Jun 1995 12:26:51 -0400
> Date: Fri, 9 Jun 1995 12:26:51 -0400
> Message-Id: <9506091626.AA04114@gulch.MIT.EDU>
> To: bug-g++@prep.ai.mit.edu
> Subject: NetProb ticket #2896, decmips 7.7G: cygnus/g++
> Content-Length: 76885
>
> >From hardts@MIT.EDU Thu Dec 22 19:55:55 1994
> >Received: by gregor.MIT.EDU (5.57/4.7) id AA05914; Thu, 22 Dec 94 19:55:51 -05>00
> >Received: from AL-FORNO.MIT.EDU by MIT.EDU with SMTP
> > id AA20659; Thu, 22 Dec 94 19:55:41 EST
> >From: hardts@MIT.EDU
> >Received: by al-forno.MIT.EDU (5.57/4.7) id AA18437; Thu, 22 Dec 94 19:55:35 ->0500
> >Date: Thu, 22 Dec 94 19:55:35 -0500
> >Message-Id: <9412230055.AA18437@al-forno.MIT.EDU>
> >To: bugs@MIT.EDU
> >Subject: decmips 7.7G: cygnus/g++
> >
> >System name: bolognese
> >Type and version: KN02ca 7.7G (1 update(s) to same version)
> >Display type:
> >
> >
> >g++ in the cygnus locker crashed under the following situation:
> >Using a decmips machine bolognese.mit.edu) December 22, 1994
> >
> >athena% add cygnus
> >/afs/athena.mit.edu/user/h/a/hardts/src/X/xevil
> >athena% /mit/cygnus/decmipsbin/g++ test.cc
> >Fixed up unaligned data access for pid 8547 (cc1plus) at pc 0x5c9770
> >pid 8547 (cc1plus) was killed on a kernel access, at pc 0x5c976c
> >In file included from test.cc:2:
> >physical.hh:755: Internal compiler error.
> >physical.hh:755: Please submit a full bug report to `bug-g++@prep.ai.mit.edu'.>
> >athena%
> >
> >
> >Do you know of any other C++ compilers on Athena, g++ in the gnu locker
> >did basically the same thing. g++ in cygnus-930630 gave me a bunch of
> >different errors.
> >
> >
> >
> >
> >;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RELEVANT FILES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;>
> >"test.cc"
> >"physical.hh"
> >"utils.hh"
> >"coord.hh"
> >"area.hh"
> >"world.hh"
> >"id.hh"
> >"intel.hh"
> >"locator.hh"
> >
> >
> >;;;;;;;;;;;;; "test.cc"
> >#include <iostream.h>
> >#include "physical.hh"
> >
> >main()
> >{
> > cout << "Hello World." << endl;
> >}
> >
> >
> >
> >
> >;;;;;;;;; "physical.hh"
> >// "physical.hh" Interior nodes of the physical object tree. These classes
> >// are never instantiated.
> >// TAG: PH
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> > */
> >
> >#ifndef PHYSICAL_HH
> >#define PHYSICAL_HH
> >
> >#pragma interface
> >
> >
> >// Include Files
> >#include "utils.hh"
> >#include "coord.hh"
> >#include "area.hh"
> >#include "world.hh"
> >#include "id.hh"
> >#include "intel.hh"
> >#include "locator.hh"
> >
> >
> >// Defines
> >#define PH_ANIM_MAX 4
> >#define PH_FRAME_MAX 7
> >#define PH_WEAPONS_MAX 10
> >#define PH_ITEMS_MAX 20
> >#define PH_AMMO_UNLIMITED -1
> >#define PH_CORPSE_TIME 400
> >
> >
> >
> >// Other declarations
> >enum PHsig {PH_NO_SIG, PH_NOT_SET, PH_ID_CHANGED};
> >
> >
> >
> >// Class declarations
> >
> >////////// Physical
> >/* The parent class of all physical objects. */
> >
> >struct PhysicalContext {
> > Health health;
> > Mass mass;
> > ClassId classId;
> > const char *clas;
> >};
> >
> >
> >class Physical {
> >public:
> > Physical(const PhysicalContext &,WorldP,LocatorP);
> > /* EFFECTS: Create a new, mapped physical with no Id with undefined area. */>
> >
> > Physical();
> > /* NOTE: Should never be called. */
> >
> > virtual ~Physical();
> >
> > virtual const Area &get_area() = 0;
> > Health get_health() {return health;}
> > Health get_health_max() {return pc->health;}
> > Mass get_mass() {return mass;}
> > virtual Vel get_vel();
> > virtual Dir get_dir();
> >
> > ClassId get_class_id() {return pc->classId;}
> > const char *identify() {return pc->clas;}
> >
> > virtual int get_drawing_level();
> >
> > Boolean delete_me() {return deleteMe;}
> >
> > Boolean alive() {return health >= 0;}
> > /* NOTE: Is publicly known that (health >= 0) <=> alive. So this function i>s
> > just for convenience. */
> >
> > /* Should only be used for abstract classes. Actual classes can be tested
> > for with get_class_id(). */
> > virtual Boolean is_moving();
> > virtual Boolean is_shot();
> > virtual Boolean is_item();
> > virtual Boolean is_bomb();
> > virtual Boolean is_weapon();
> > virtual Boolean is_cutter();
> > virtual Boolean is_gun();
> > virtual Boolean is_creature();
> > virtual Boolean is_user();
> > virtual Boolean is_fighter();
> > virtual Boolean is_walking();
> > virtual Boolean is_sticky();
> > virtual Boolean is_flying();
> >
> > Boolean get_mapped() {return mapped;}
> >
> > virtual Boolean collidable();
> > /* NOTE: This value never changes for an object. */
> >
> > const Acc *get_unit_accs() {return unitAccs;}
> > const Vel *get_unit_vels() {return unitVels;}
> >
> > Id get_id() {assert(idValid); return id;}
> >
> > PHsig get_id(Id &id);
> > /* MODIFIES: id */
> > /* EFFECTS: Set id to be the Id and return PH_NO_SIG if set. Otherwise,
> > return PH_NOT_SET. */
> >
> > PhysicalP get_dont_collide() {return dontCollide;}
> > /* EFFECTS: If there is another object that *this is not allowed to collide
> > with, return it. Otherwise return NULL; */
> >
> > IntelP get_intel() {return intel;}
> > /* NOTE: Can be NULL. */
> >
> > void set_command(ITcommand c) {command = c;}
> > /* EFFECTS: Sets the command to be c, overrides any previous command
> > setting. */
> > /* NOTE: command is not clocked. */
> >
> > PHsig set_id(const Id &id);
> > /* EFFECTS: Set the Id to be id. Return PH_NO_SIG if there was no previous
> > id. Return PH_ID_CHANGED if there was a previous id. The id is set in
> > either case. */
> >
> > void set_dont_collide(PhysicalP other) {dontCollide = other;}
> > /* EFFECTS: *this will not be allowed to collide with other. Any previous
> > value will be overridden. A setting of NULL disables this feature. */
> >
> > void set_intel(IntelP i) {intel = i; if (i) i->set_id(id);}
> > /* REQUIRES: Object has been added to locator (has valid id.)
> > /* NOTE: Can be NULL. */
> >
> > void set_health_next(Health h) {healthNext = h;}
> >
> > virtual void set_mapped_next(Boolean val);
> > /* NOTE: Should be ok to set the value to the previous value. */
> > /* NOTE: idempotent */
> > /* Calls up the tree. */
> >
> > void set_no_death_delete() {noDeathDelete = True;}
> >
> > virtual void corporeal_attack(PhysicalP killer,int damage);
> > virtual void heat_attack(PhysicalP,int heat,Boolean secondary = False);
> > /* NOTE: Sometimes call up the tree. */
> > /* NOTE: killer is the one responsible for causing the damage. Can be
> > NULL. Adds kills to the killer. */
> > /* NOTE: Only the last call before the update cycle takes effect. */
> >
> > virtual void avoid(PhysicalP);
> > virtual void collide(PhysicalP);
> > /* EFFECTS: Collision procedures. avoid is called on the lighter of the two>
> > objects. collide is called on both objects. */
> > /* NOTE: Not always called up the tree. */
> >
> > void intelligence() {if (intel) intel->clock(this);}
> >
> > void kill_self() {healthNext = -1;}
> >
> > virtual void set_quiet_death();
> > /* EFFECTS: When this dies, do not do any funny things like leaving corpses
> > or exploding or any other type of physical evidence. */
> > /* NOTE: Calls up the tree. */
> >
> > void virtual act();
> > /* EFFECTS: Action phase. All next variables must be set here. Commands
> > are interpreted here.*/
> >
> > void virtual update();
> > /* EFFECTS: Set current variables to be the next ones. No interactions
> > between physical objects. */
> >
> > void virtual draw(Drawable buffer,Xvars &xvars, const Area &area) = 0;
> > /* REQUIRES: buffer is at least as big as area. */
> > /* EFFECTS: Draw the physical object in buffer. buffer represents area. */
> > /* NOTE: Does not check for overlap */
> > /* NOTE: X variables initialized in draw. Thus, if draw is never called for>
> > a base class, the X variables never need to be initialized. */
> >
> > void virtual die();
> > /* EFFECTS: If the *this dies a natural death (I.e. health < 0), then this
> > function is called. Not called if *this is
> > destroyed for any other reason. E.g. end of game. The default is to
> > kill the intel and set_delete_me. */
> > /* NOTE: Intel is created/destroyed by Game or Locator. */
> > /* NOTE: Should be called in update phase. */
> > /* NOTE: Calls up the tree. */
> > /* NOTE: Guaranteed to be called only once. */
> >
> >
> > virtual int get_weapons_num();
> > virtual int get_items_num();
> > /* NOTE: Returned value is not valid after current turn. */
> >
> > virtual PhysicalP get_weapon(int);
> > virtual PhysicalP get_item(int);
> > virtual PhysicalP get_weapon_current();
> > virtual PhysicalP get_item_current();
> > /* NOTE: Can return NULL. */
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > WorldP get_world() {return world;}
> >
> > Boolean alive_next() {return healthNext >= 0;}
> >
> > LocatorP get_locator() {return locator;}
> >
> > const ITcommand &get_command() {return command;}
> > /* EFFECTS: Gets the command. */
> > /* NOTE: command is not clocked. */
> >
> > Boolean get_mapped_next() {return mappedNext;}
> >
> > void set_mass_next(Mass mss) {massNext = mss;}
> >
> > void set_delete_me() {deleteMe = True;}
> >
> >
> >private:
> > void init_static();
> >
> > static Boolean staticValid;
> > static Acc unitAccs[CO_DIR_MAX];
> > static Vel unitVels[CO_DIR_MAX];
> > Boolean idValid;
> > Id id;
> > WorldP world;
> > LocatorP locator;
> > ITcommand command;
> > const PhysicalContext *pc;
> > Health health, healthNext;
> > Mass mass, massNext;
> > PhysicalP dontCollide;
> > IntelP intel;
> > Boolean deleteMe;
> > Boolean mapped,mappedNext;
> > Boolean noDeathDelete; // Should set_delete_me be called at death.
> > Boolean dieCalled;
> > int heat, heatNext;
> > Boolean previousHeatWasSecondary;
> >};
> >// PhysicalP defined in locator.hh
> >
> >
> >
> >////////// Moving
> >// Parent: Physical
> >// Has all 19 directions. Multiple pixmaps. Can change size and position.
> >// Top speed is VEL_MAX.
> >
> >/* Only sizes[CO_air] and offsets[CO_air] are required to be set.
> > Gives initial size and offset. */
> >struct MovingContext {
> > char *foreColorName;
> > Boolean foreWhiteDefault;
> > const char *backColorName;
> > Boolean backWhiteDefault;
> > int animMax[CO_DIR_MAX];
> > Size sizes[CO_DIR_MAX];
> > Size offsets[CO_DIR_MAX];
> > char *pixmapBits[CO_DIR_MAX][PH_ANIM_MAX];
> > char *maskBits[CO_DIR_MAX][PH_ANIM_MAX];
> > PhysicalContext physicalContext;
> >};
> >
> >
> >class MovingXdata {
> >public:
> > MovingXdata() {valid = False;}
> >
> > Boolean valid;
> > Pixmap pixmaps[CO_DIR_MAX][PH_ANIM_MAX],
> > masks[CO_DIR_MAX][PH_ANIM_MAX];
> >};
> >
> >
> >class Moving: public Physical {
> >public:
> > Moving(const MovingContext &m_c,
> > MovingXdata &x_data,
> > WorldP world,
> > LocatorP l,
> > const Pos &rawPos,
> > Dir dirInitial = CO_air);
> >
> > Moving();
> > /* NOTE: Should never be called. */
> >
> > virtual Boolean is_moving();
> >
> > virtual const Area &get_area();
> > virtual Vel get_vel();
> > const Pos &get_raw_pos() {return rawPos;}
> > virtual Dir get_dir();
> >
> > void set_middle_next(const Pos &pos);
> > /* EFFECTS: Sets the middle of pos according to the current (not next) value>s
> > of dir, and area (for size). */
> > /* NOTE: May be called before or after act phase. */
> >
> > void set_extra_vel_next(const Vel &vel)
> > {extraVelNext = vel; extraVelNextSet = True;}
> >
> > virtual void act();
> > virtual void update();
> > virtual void draw(Drawable,Xvars &,const Area &);
> > virtual void avoid(PhysicalP);
> > virtual void collide(PhysicalP);
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > Boolean hit_wall() {return hitWall;}
> > Boolean hit_wall_next() {return hitWallNext;}
> >
> > Dir get_dir_next() {return dirNext;}
> >
> > const Area &get_area_next() {return areaNext;}
> > const MovingContext *get_moving_context() {return mc;}
> > Vel get_vel_next() {return velNext;}
> >
> > void set_vel(const Vel &v) {vel = v;}
> >
> > void set_vel_next(const Vel &vel) {velNext = vel;}
> > void set_vel_next(int zero) {assert (zero == 0); velNext.set_zero();}
> > /* EFFECTS: Sets the next velocity for the object to be vel. Can be called
> > multiple times before update, only the last call is used. */
> >
> >// void set_extra_vel(const Vel &vel) {extraVel = vel;}
> > /* NOTE: Not clocked. */
> >
> > void set_dir(const Dir &d) {dir = d;}
> > /* NOTE: Only used by Lance for initialization. */
> >
> > void set_dir_next(const Dir &d) {dirNext = d;}
> >
> > void set_raw_pos_next(const Pos &rpos)
> > {rawPosNext = rpos; rawPosChanged = True;}
> >
> > void update_next();
> > /* EFFECTS: Compute areaNext and hitWallNext. May modify rawPosNext or
> > dirNext. */
> > /* NOTE: May be called more than once per turn. */
> >
> > virtual void get_pixmap_mask(Pixmap &pixmap,Pixmap &mask,
> > Dir dir,int animNum);
> > /* MODIFIES: pixmap, mask */
> > /* NOTE: Only used so that children of Moving can affect Moving's actions. *>/
> >
> > virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
> > /* MODIFIES: size, offset */
> > /* NOTE: Only used so that children of Moving can affect Moving's actions. *>/
> >
> > virtual void init_x(Xvars &);
> > /* NOTE: Now called up the tree. */
> >
> >
> >private:
> > Boolean context_valid();
> > /* EFFECTS: Returns True if this->cx is valid, False otherwise. */
> >
> > float compute_collision(Mass m1,float v1,Mass m2,float v2);
> >
> >
> > MovingXdata *movingXdata;
> > int movingAnimNum;
> > Timer animTimer;
> > const MovingContext *mc;
> > Pos rawPos,rawPosNext; Boolean rawPosChanged;
> > Area area,areaNext;
> > Dir dir,dirNext;
> > Vel vel,velNext;
> > Boolean extraVelNextSet;
> > Vel extraVel,extraVelNext; // Follows clock in non-standard way.
> > Boolean hitWall,hitWallNext;
> >};
> >typedef Moving *MovingP;
> >
> >
> >
> >////////// Shot
> >// Parent: Moving
> >
> >struct ShotContext {
> > int damage; // Or heat.
> > Speed speed;
> > MovingContext movingContext;
> >};
> >
> >typedef MovingXdata ShotXdata ;
> >
> >class Shot: public Moving {
> >public:
> > Shot(const ShotContext &,ShotXdata &,WorldP,LocatorP,
> > const Pos &,const Id &shooter,
> > Dir shotDir,Dir movingDir = CO_air);
> >
> > const Id &get_shooter() {return shooter;}
> >
> > virtual Boolean is_shot();
> >
> > virtual void avoid(PhysicalP other);
> > virtual void collide(PhysicalP other);
> >
> > virtual void update();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> > protected:
> >#endif
> > int get_damage() {return context->damage;}
> >
> >
> >private:
> > Id shooter;
> > const ShotContext *context;
> >};
> >
> >
> >
> >////////// Falling
> >// Parent: Moving
> >// Moving with gravity. Falls until it is blocked by the world.
> >
> >struct FallingContext {
> > MovingContext movingContext;
> >};
> >
> >typedef MovingXdata FallingXdata;
> >
> >class Falling: public Moving {
> >public:
> > Falling(const FallingContext &h_c,FallingXdata &x_data,
> > WorldP world,LocatorP l,const Pos &rawPos,
> > Dir dirInitial = CO_air);
> >
> > virtual void act();
> >};
> >
> >
> >
> >//////////// Heavy
> >// Parent: Falling
> >// Does damage to things it lands on.
> >
> >struct HeavyContext {
> > int damage;
> > FallingContext fallingContext;
> >};
> >
> >typedef FallingXdata HeavyXdata;
> >
> >class Heavy: public Falling {
> > public:
> > Heavy(const HeavyContext &h_c,
> > HeavyXdata &x_data,
> > WorldP world,
> > LocatorP l,
> > const Pos &rawPos);
> >
> > virtual void collide(PhysicalP);
> > /* EFFECTS: Crush things it falls on. */
> >
> >
> > private:
> > const HeavyContext *context;
> >};
> >
> >
> >
> >//////////// Generator
> >// Parent: Heavy
> >// Generate machines and register them with the locator.
> >
> >struct GeneratorContext {
> > HeavyContext heavyContext;
> >};
> >
> >typedef HeavyXdata GeneratorXdata;
> >
> >class Generator: public Heavy {
> >public:
> > Generator(const IntelOptions &ops,ITmask opMask,
> > const char *prefix,
> > const GeneratorContext &g_c,
> > GeneratorXdata &x_data,
> > WorldP w,
> > LocatorP l,
> > const Pos &rawPos);
> >
> > virtual void act();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > virtual PhysicalP generate() = 0;
> >
> >
> >private:
> > enum {MAX = 10, TIME = 100};
> >
> > Timer timer;
> > int machineCount; // Always increasing.
> > IntelOptions machineOps;
> > ITmask machineOpMask;
> > const char *machinePrefix;
> >
> > Id generated[MAX];
> > const GeneratorContext *generatorContext;
> >};
> >
> >
> >
> >//////////// Item
> >// Parent: Falling
> >//
> >struct ItemContext {
> > Boolean persists;
> > FallingContext fallingContext;
> >};
> >typedef FallingXdata ItemXdata;
> >
> >
> >class Item: public Falling {
> >public:
> > Item(const ItemContext &c_x,
> > ItemXdata &x_data,
> > WorldP w,
> > LocatorP l,
> > const Pos &pos);
> >
> > Boolean is_item() {return True;}
> >
> > Boolean is_held() {return held;}
> >
> > Boolean can_take() {return canTake.ready() && !held && !cantTake;}
> > /* EFFECTS: Returns whether the object can be picked up. */
> >
> > virtual int get_drawing_level();
> > /* NOTE: Items are at drawing level 1. */
> >
> > Boolean persists() {return context->persists;}
> >
> > virtual void follow_user(const Pos &userMiddle,Dir userDir);
> >
> > void taken(PhysicalP);
> > /* EFFECTS: The object has been taken by another Physical. */
> > /* NOTE: Changes immediate externally visible state. Should only be called
> > in the collision phase. */
> >
> > void dropped(PhysicalP);
> > /* EFFECTS: The object has been dropped by another Physical. */
> > /* NOTE: Called by another object in the act phase. */
> > /* NOTE: Called in either the act or update phase. */
> > /* NOTE: Calls up the tree. */
> >
> > virtual void use(PhysicalP);
> > /* EFFECTS: p uses *this. */
> > /* NOTE: Called by another object in act phase. */
> >
> > void set_used_message() {usedMessage = True;}
> > /* EFFECTS: On death, the printed message will say the item was used instead>
> > of saying the item was destroyed. */
> >
> > virtual void act();
> >
> > virtual void die();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > void set_cant_take() {cantTake = True;}
> >
> >
> >private:
> > Boolean held;
> > Boolean usedMessage;
> > Timer canTake;
> > Boolean cantTake;
> > const ItemContext *context;
> >};
> >typedef Item *ItemP;
> >
> >
> >
> >//////////// Animated
> >// Parent: Item
> >//
> >struct AnimatedContext {
> > char *colorName;
> > Size size;
> > int animMax[PH_FRAME_MAX];
> > char *pixmapBits[PH_FRAME_MAX][PH_ANIM_MAX];
> > char *maskBits[PH_FRAME_MAX][PH_ANIM_MAX];
> > ItemContext itemContext;
> >};
> >
> >
> >class AnimatedXdata {
> >public:
> > AnimatedXdata() {valid = False;}
> > Boolean valid;
> > Pixmap pixmaps[PH_FRAME_MAX][PH_ANIM_MAX],
> > masks[PH_FRAME_MAX][PH_ANIM_MAX];
> > ItemXdata itemXdata;
> >};
> >
> >
> >class Animated: public Item {
> >public:
> > Animated::Animated(const AnimatedContext &,AnimatedXdata &,
> > WorldP,LocatorP,const Pos &);
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > void set_frame(Frame fr) {frame = fr;}
> > void set_frame_next(Frame fr) {frameNext = fr;}
> > Frame get_frame() {return frame;}
> >
> > virtual void get_pixmap_mask(Pixmap &pixmap,Pixmap &mask,
> > Dir dir,int animNum);
> > virtual void get_size_offset_next(Size &size,Size &offset,
> > Dir dirNext);
> >
> > virtual void init_x(Xvars &);
> >
> > virtual void update();
> >
> >
> >private:
> > Boolean context_valid();
> >
> > AnimatedXdata *animatedXdata;
> > const AnimatedContext *ac;
> > Frame frame,frameNext;
> > int animatedAnimNum;
> >};
> >
> >
> >
> >//////////// Weapon
> >// Parent: Item
> >//
> >struct WeaponContext {
> > Boolean defaultable;
> > ItemContext itemContext;
> >};
> >typedef ItemXdata WeaponXdata;
> >class Weapon;
> >typedef Weapon *WeaponP;
> >
> >
> >class Weapon: public Item {
> >public:
> > Weapon(const WeaponContext &c_x,
> > WeaponXdata &x_data,
> > WorldP w,
> > LocatorP l,
> > const Pos &pos);
> >
> > Boolean is_weapon() {return True;}
> >
> > virtual Boolean ready() = 0;
> > /* EFFECTS: Can the weapon be fired now. */
> > /* NOTE: Sometimes calls up the tree.*/
> >
> > Boolean defaultable() {return wc->defaultable;}
> > /* EFFECTS: Is this a type of weapon that can safely be set automatically as>
> > the current weapon. E.g. You do not want to set a soul-swapper as the
> > current weapon unless the user explicitly says so. */
> >
> > virtual int get_ammo() = 0;
> > virtual int get_ammo_max() = 0;
> > /* NOTE: Can return PH_AMMO_UNLIMITED. */
> >
> > virtual void fire(const Id &id,ITcommand command);
> > /* REQUIRES: command is a weapon command. */
> > /* EFFECTS: Fire the weapon according to the specified command. id is the
> > physical firing the weapon. */
> >
> > virtual void enter_scope_next(PhysicalP user);
> > virtual void leave_scope_next(PhysicalP user);
> > /* NOTE: Called during act(collide) or update phase. Should be just
> > act(). */
> > /* NOTE: Calls up the tree. */
> > /* NOTE: ok to call multiple times in same turn, but must enter/leave scope
> > in proper order. */
> >
> > void take_ammo_from(WeaponP other);
> > /* EFFECTS: Take as much ammo as possible from the other weapon. */
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> > protected:
> >#endif
> > Boolean entered_scope() {return enteredScope;}
> >
> > virtual void set_ammo(int) = 0;
> >
> >
> >private:
> > const WeaponContext *wc;
> > Boolean enteredScope; // not clocked
> >};
> >// typedef Weapon *WeaponP; Defined above.
> >
> >
> >
> >//////////// Cutter
> >// Parent: Weapon
> >// NOTE: Uses CO_center for cutter directly in front of user.
> >struct CutterContext {
> > int damage; // per turn
> > Size offsets[CO_DIR_MAX]; // From User's middle to Cutter's middle.
> >
> > char *unheldColorName;
> > Size unheldSize;
> > char *unheldPixmapBits;
> > char *unheldMaskBits;
> > WeaponContext weaponContext;
> >};
> >
> >
> >class CutterXdata {
> > public:
> > CutterXdata() {valid = False;}
> >
> > Boolean valid;
> > Pixmap unheldPixmap,unheldMask;
> > WeaponXdata weaponXdata;
> >};
> >
> >
> >class Cutter: public Weapon {
> >public:
> > Cutter(const CutterContext &c_x,CutterXdata &x_data,
> > WorldP w,LocatorP l,const Pos &pos);
> >
> > virtual Boolean is_cutter();
> >
> > virtual Boolean ready();
> >
> > virtual int get_ammo();
> > virtual int get_ammo_max();
> >
> > virtual void get_pixmap_mask(Pixmap &pixmap,Pixmap &mask,
> > Dir dir,int animNum);
> >
> > virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
> >
> > virtual void set_ammo(int);
> >
> > virtual void follow_user(const Pos &,Dir);
> >
> > virtual void enter_scope_next(PhysicalP);
> > virtual void leave_scope_next(PhysicalP);
> >
> > virtual void collide(PhysicalP);
> >
> > virtual void update();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> > protected:
> >#endif
> > virtual void init_x(Xvars &);
> >
> >
> >private:
> > Dir dir_4_from_user_dir(Dir);
> >
> > Boolean inScope,inScopeNext;
> > Id killerId; // Valid iff inScope.
> > CutterXdata *cutterXdata;
> > const CutterContext *context;
> >};
> >
> >
> >
> >
> >////////// Creature
> >// Parent: Moving
> >// Moving with stances. Can be affected by gravity.
> >struct CreatureContext {
> > Speed crawlSpeed;
> > Speed centerSpeed;
> > Speed airSpeed;
> > Speed climbSpeed;
> > Speed jump;
> > Speed acceleration;
> > Health corpseHealth; // A positive number.
> >
> > Size deadSize;
> > Size deadOffset;
> > char *deadPixmapBits;
> > char *deadMaskBits;
> >
> > MovingContext movingContext;
> >};
> >
> >
> >struct CreatureXdata
> >{
> > CreatureXdata() {valid = False;}
> >
> > Pixmap deadPixmap,deadMask;
> > Boolean valid;
> > MovingXdata movingXdata;
> >};
> >
> >
> >class Creature: public Moving {
> >public:
> > Creature(const CreatureContext &m_c,
> > CreatureXdata &x_data,
> > WorldP world,
> > LocatorP l,
> > const Pos &rawPos);
> >
> > Creature();
> > /* NOTE: Should never be called. */
> >
> > virtual Boolean is_creature() {return True;}
> > Stance get_stance() {return stance;}
> > Boolean can_climb() {return canClimb;}
> >
> > Boolean was_attacked() {return wasAttacked;}
> > /* EFFECTS: Was *this attacked last turn. Use get_killer_id() to
> > get the attacker. */
> >
> > const Hanging &get_hanging() {return hanging;}
> > /* EFFECTS: Get the corner that the object is hanging off of, or CO_AIR if
> > not hanging off a corner. */
> >
> > const Touching &get_touching_area() {return touching;}
> > /* EFFECTS: The object's actual touching. I.e. according to its area. */
> >
> > Grav get_grav() {return grav;}
> >
> > const Id &get_killer_id() {return killerId;}
> > /* EFFECTS: Return the id of the most recent attacker. May be invalid. */
> >
> > virtual void set_quiet_death();
> >
> > virtual void corporeal_attack(PhysicalP,int damage);
> > virtual void heat_attack(PhysicalP,int heat,Boolean secondary);
> >
> > virtual void act();
> > virtual void update();
> > virtual void die();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > Stance get_stance_next() {return stanceNext;}
> >
> > const CreatureContext *get_creature_context() {return cc;}
> >
> > Touching get_touching_stance();
> > /* EFFECTS: The object's touching according to its stance. */
> >
> > virtual void get_pixmap_mask(Pixmap &pixmap,Pixmap &mask,
> > Dir dir,int animNum);
> > /* MODIFIES: pixmap, mask */
> >
> > virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
> > /* MODIFIES: size, offset */
> >
> > void set_stance(const Stance &st) {stance = st;}
> >
> > void set_stance_next(const Stance &stance);
> > /* EFFECTS: Sets the next stanceection for the object to be stance. Can be
> > called multiple times before update, only the last call is used. */
> >
> > void set_grav_next(const Grav &g)
> > {gravNext = g;}
> > /* EFFECTS: Sets the pull of gravity for the next turn to be grav. */
> >
> > void center_wsquare_x_next(const Loc &loc);
> > /* REQUIRES: loc overlaps with the area, stanceNext set to CO_climb */
> > /* EFFECTS: Tries to center the x position object on the wsquare at loc.
> > (May be bumped a bit if a wall prevents exact centering.) */
> >
> > void corner(const Hanging &hanging);
> > /* REQUIRES: stanceNext is set to correspond to h.corner. */
> > /* EFFECTS: Tries to move the object around the corner it is hanging off of.>
> > Note that hanging.corner is the initial corner, not the desired final
> > one. */
> >
> > virtual void init_x(Xvars &);
> >
> >
> >private:
> > static Dir compute_dir(const Stance &stance,const Vel &vel);
> > /* USES: nothing */
> > /* EFFECTS: Return the dir corresponding to stance and vel. */
> >
> > Boolean context_valid();
> >
> > Touching touching;
> > Hanging hanging;
> > Boolean canClimb;
> > Stance stance,stanceNext;
> > Grav grav,gravNext;
> > const CreatureContext *cc;
> > Timer corpseTimer;
> > CreatureXdata *creatureXdata;
> > Boolean noCorpse;
> > Id killerId;
> > Boolean wasAttacked, wasAttackedNext;
> >};
> >typedef Creature *CreatureP;
> >
> >
> >
> >/*//////// Grounded
> >// Parent: Creature
> >Sticks to the ground only. Affected by gravity. Can't climb or jump. */
> >struct GroundedContext
> >{
> > int dummy;
> >};
> >
> >struct GroundedXdata {};
> >
> >class Grounded: public virtual Creature {
> > public:
> > Grounded(const GroundedContext &,GroundedXdata &);
> >
> > virtual Boolean is_grounded() {return True;}
> > virtual void act();
> >};
> >
> >
> >
> >////////// Hopping
> >// Parent: Creature
> >//
> >struct HoppingContext
> >{
> > int dummy;
> >};
> >
> >struct HoppingXdata {};
> >
> >class Hopping: public virtual Creature {
> > public:
> > Hopping(const HoppingContext &,HoppingXdata &);
> >
> > virtual void act();
> >};
> >
> >
> >
> >////////// User
> >// Parent: Creature
> >// Holds and uses items and weapons. The items and weapons are made to follow>
> >// the User.
> >struct UserContext
> >{
> > int dummy;
> >};
> >
> >struct UserXdata {};
> >
> >
> >class User: public virtual Creature {
> >public:
> > User(const UserContext &,UserXdata &);
> >
> > virtual Boolean is_user();
> >
> > virtual int get_weapons_num();
> > virtual int get_items_num();
> > /* NOTE: Returned value is not valid after current turn. */
> >
> > virtual PhysicalP get_weapon(int);
> > virtual PhysicalP get_item(int);
> > virtual PhysicalP get_weapon_current();
> > virtual PhysicalP get_item_current();
> > /* NOTE: Can return NULL. */
> >
> > virtual void set_mapped_next(Boolean val);
> > /* EFFECTS: Bring current weapon in/out of scope and then change mapped. */
> >
> > virtual void act();
> > virtual void _act();
> >
> > virtual void collide(PhysicalP other);
> > virtual Boolean _collide(PhysicalP);
> >
> > virtual void die();
> > virtual void _die();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> > protected:
> >#endif
> > Boolean has_weapon(Weapon **weapon,ClassId classId);
> > /* MODIFIES: weapon */
> > /* EFFECTS: Like has_weapon(ClassId) except will return the
> > weapon in weapon if not NULL. */
> >
> >
> >private:
> > int defaultable_weapon();
> > /* REQUIRES: weaponsNum and weapons are properly updated. */
> > /* EFFECTS: Returns the index of a wepon in weapons that is defaultable or
> > weaponsNum if there is none. */
> >
> >
> > Id weapons[PH_WEAPONS_MAX];
> > int weaponsNum;
> > int weaponCurrent; // weaponCurrent == weaponsNum if no selected weapon.
> > // Memory of previous weapon dir is now in ui.
> >
> > Id items[PH_ITEMS_MAX];
> > int itemsNum;
> > int itemCurrent; // itemCurrent == itemsNum if no selected item.
> >};
> >typedef User *UserP;
> >
> >
> >
> >////////// Fighter
> >// Parent: Creature
> >// Can attack in different directions.
> >struct FighterContext {
> > char *colorName;
> > int slide;
> > int jumpHorizontal;
> > int jumpVertical;
> > int damageStuck;
> > int damageFree;
> >
> > Size sizes[CO_DIR_MAX];
> > Size offsets[CO_DIR_MAX];
> > Size hotSpots[CO_DIR_MAX]; // Must add in offset to use.
> > char *pixmapBits[CO_DIR_MAX];
> > char *maskBits[CO_DIR_MAX];
> >};
> >
> >
> >class FighterXdata {
> >public:
> > FighterXdata() {valid = False;}
> >
> > Boolean valid;
> > Pixmap pixmaps[CO_DIR_MAX],
> > masks[CO_DIR_MAX];
> >};
> >
> >
> >class Fighter: public virtual Creature {
> >public:
> > Fighter(const FighterContext &f_c,FighterXdata &x_data);
> >
> > virtual Boolean is_fighter();
> >
> > virtual void get_pixmap_mask(Pixmap &pixmap,Pixmap &mask,
> > Dir dir,int animNum);
> >
> > virtual void get_size_offset_next(Size &size,Size &offset,Dir dirNext);
> >
> > virtual void act();
> > virtual void _act();
> >
> > virtual void update();
> > virtual void _update();
> >
> > virtual void collide(PhysicalP other);
> > virtual Boolean _collide(PhysicalP);
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > virtual void init_x(Xvars &);
> >
> >
> >private:
> > Attack dir_to_attack(Dir dir);
> >
> > void attack_stuck(Dir dir,Stance stance);
> > void attack_free_horizontal(Dir dir);
> > /* NOTE: Does not zero vertical velocity. */
> >
> > void attack_free_vertical(Dir dir);
> > /* NOTE: Vertical velocity only. */
> >
> > FighterXdata *fighterXdata;
> > const FighterContext *fc;
> > Attack attack, attackNext;
> > Timer stuckTimer;
> >};
> >
> >
> >
> >////////// Walking
> >// Parent: Creature
> >// Sticks to the ground only. Affected by gravity.
> >struct WalkingContext
> >{
> > int dummy;
> >};
> >
> >struct WalkingXdata {};
> >
> >class Walking: public virtual Creature {
> >public:
> > Walking(const WalkingContext &,WalkingXdata &);
> >
> > virtual Boolean is_walking() {return True;}
> >
> > virtual void act();
> > virtual void _act();
> >
> >
> >private:
> > Pos rawPosPrev;
> > Vel velPrev;
> >};
> >
> >
> >
> >////////// Sticky
> >// Parent: Creature
> >// Sticks to and walks on flat surfaces in four directions. Affected by
> >// gravity.
> >struct StickyContext
> >{
> > int dummy;
> >};
> >
> >struct StickyXdata {};
> >
> >class Sticky: public virtual Creature {
> >public:
> > Sticky(const StickyContext &,StickyXdata &);
> >
> > virtual Boolean is_sticky();
> >
> > virtual void act();
> > virtual void _act();
> >
> >
> >#ifndef PROTECTED_IS_PUBLIC
> >protected:
> >#endif
> > Boolean want_corner(const Corner &corner);
> > /* EFFECTS: Returns True if the object should go around the given corner,
> > False otherwise. corner is the initial, not final corner.*/
> >
> > Stance cornered_stance(const Hanging &h);
> > /* EFFECTS: Returns the stance to take in order to go around the corner
> > of h. */
> >
> > void set_want_corner(const Corner &c1)
> > {wantCorner1 = c1; wantCorner2 = CO_air;}
> > void set_want_corner(const Corner &c1,const Corner &c2)
> > {wantCorner1 = c1; wantCorner2 = c2;}
> > /* EFFECTS: Tell the object that it should go around a corner if possible.
> > The given values are in effect until changed. */
> > /* NOTE: set_want_corner(CO_air) should be used to disable cornering. */
> >
> >
> >private:
> > Corner wantCorner1,wantCorner2;
> >};
> >
> >
> >
> >////////// Flying
> >// Parent: Creature
> >// Floats around. Can walk on the ground.
> >struct FlyingContext
> >{
> > int airBrake;
> > int gravTime;
> >};
> >
> >struct FlyingXdata {};
> >
> >class Flying: public virtual Creature {
> >public:
> > Flying(const FlyingContext &,FlyingXdata &);
> >
> > virtual Boolean is_flying();
> >
> > virtual void act();
> > virtual void _act();
> >
> >
> >private:
> > Timer gravTimer;
> > const FlyingContext *context;
> >};
> >
> >#endif
> >
> >
> >
> >
> >;;;;;;;;;; "utils.hh"
> >// Misc. utilities. to be included by ALL files.
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >#ifndef UTILS_HH
> >#define UTILS_HH
> >
> >#pragma interface
> >
> >
> >
> >// Include Files
> >extern "C"
> >{
> >#include <math.h>
> >#include <stdlib.h>
> >#include <X11/X.h>
> >#include <X11/Xlib.h>
> >}
> >#include <assert.h>
> >
> >
> >
> >// Defines
> >#ifndef max
> >#define max(a,b) (a<b ? b : a)
> >#endif
> >#ifndef min
> >#define min(a,b) (a>b ? b : a)
> >#endif
> >
> >typedef char Boolean;
> >typedef unsigned long Pixel;
> >
> >typedef int ColorNum;
> >
> >
> >
> >
> >#ifdef RANDOM_NEEDS_PROTOTYPES
> >extern "C" {
> >long random();
> >void srandom(int);
> >}
> >#endif
> >
> >
> >
> >
> >// Data Structures
> >class Xvars {
> >public:
> > enum {HUMAN_COLORS_NUM = 5};
> >
> > Display *dpy;
> > Screen *scr_ptr;
> > int scr_num;
> > Window root;
> > Visual *visual;
> > int depth;
> > Colormap cmap;
> > Pixel white,black; /* Or background/foreground. */
> > Pixel red,green; /* Both default to black. */
> > Pixel humanColors[HUMAN_COLORS_NUM];
> > GC gc; /* Default except foreground is black, background is white, no
> > graphics exposures, font is set, stipple is suitable for drawing
> > insensitive areas, fill style is FillSolid */
> > XFontStruct *font;
> >};
> >
> >
> >
> >class Timer {
> > public:
> > Timer() {remaining = maxx = 0;}
> > // Starts out ready.
> > Timer(int t) {assert (t >= 0); maxx = t; remaining = 0;}
> > Boolean ready() {return remaining == 0;}
> > void set() {remaining = maxx;}
> > void set(int time) {remaining = time;}
> > void reset() {remaining = 0;}
> > void clock() {if (remaining) remaining--;}
> >
> > private:
> > int remaining;
> > int maxx;
> >};
> >
> >
> >
> >#define Utils_BACKGROUND "light grey"
> >class Utils {
> > public:
> > enum {HUMAN_COLORS_NUM = Xvars::HUMAN_COLORS_NUM};
> > static const char *humanColorNames[Utils::HUMAN_COLORS_NUM];
> >
> > static Pixel allocNamedColor(Xvars &xvars,const char *name,
> > Pixel def = (Pixel)-1);
> > /* EFFECTS: Tries to allocate the named color. Returns it if successful.
> > Otherwise, returns default. If called with only 2 arguments, default is >
> > white. If black and white display, returns default. */
> >
> >
> > static inline Boolean coinFlip()
> >#ifdef USE_RANDOM
> > {return (Boolean)(random() % 2);}
> >#else
> > { return (Boolean)(rand() % 2); }
> >#endif
> > /* EFFECTS: Randomly returns True or False; */
> >
> >
> > static inline int choose(int x)
> >#ifdef USE_RANDOM
> > {
> > assert (x > 0);
> > return (int)(random() % x);
> > }
> >#else
> > {
> > assert (x > 0);
> > return rand() % x;
> > }
> >#endif
> > /* EFFECTS: Randomly return a number from 0 to x - 1. */
> >
> > static void insertionSort(int arry[],int numElements);
> >
> > static void randomList(int arry[],int numElements);
> > /* EFFECTS: Fills arry the first numElements of arry with the numbers in
> > {0..(numElements-1)} in a random order. */
> >
> > static int minimum(int arry[],int size);
> > /* EFFECTS: Return the minimum value in the array arry of size size. */
> >
> > static int minimum(int arry[],Boolean oks[],int size);
> > /* EFFECTS: Return the minimum value in arry which is ok or -1 if none. */
> >};
> >#endif
> >
> >
> >
> >;;;;;;; "coord.hh"
> >// "coord.h" Coordinates and directions and the like.
> >// TAG: CO
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >#ifndef COORD_HH
> >#define COORD_HH
> >
> >#pragma interface
> >
> >
> >// Include Files
> >#include "utils.hh"
> >
> >
> >
> >// Defines
> >#define WSQUARE_WIDTH 16
> >#define WSQUARE_HEIGHT 16
> >#define WSQUARE_WIDTH_INV (1.0 / WSQUARE_WIDTH)
> >#define WSQUARE_HEIGHT_INV (1.0 / WSQUARE_HEIGHT)
> >
> >
> >// Order of directions IS guaranteed.
> >#define CO_center_R 0
> >#define CO_center_L 1
> >#define CO_air_R 2
> >#define CO_air_L 3
> >#define CO_air 4
> >#define CO_center 5
> >
> >#define CO_r 6
> >#define CO_r_DN 7
> >#define CO_r_UP 8
> >#define CO_dn 9
> >#define CO_dn_R 10
> >#define CO_dn_L 11
> >#define CO_l 12
> >#define CO_l_DN 13
> >#define CO_l_UP 14
> >#define CO_up 15
> >#define CO_up_R 16
> >#define CO_up_L 17
> >
> >#define CO_climb 18
> >#define CO_climb_DN 19
> >#define CO_climb_UP 20
> >#define CO_air_UP 21
> >#define CO_air_DN 22
> >#define CO_climb_R 23
> >#define CO_climb_L 24
> >
> >#define CO_R 25
> >#define CO_DN_R_R 26
> >#define CO_DN_R 27
> >#define CO_DN_DN_R 28
> >#define CO_DN 29
> >#define CO_DN_DN_L 30
> >#define CO_DN_L 31
> >#define CO_DN_L_L 32
> >#define CO_L 33
> >#define CO_UP_L_L 34
> >#define CO_UP_L 35
> >#define CO_UP_UP_L 36
> >#define CO_UP 37
> >#define CO_UP_UP_R 38
> >#define CO_UP_R 39
> >#define CO_UP_R_R 40
> >
> >#define CO_DIR_MAX 41
> >
> >#define CO_DIR_PURE 16 // "Pure" does not include CO_center. Use CO_air.
> >
> >typedef int ClassId;
> >typedef int Dir;
> >typedef int Touching;
> >typedef int Stance;
> >typedef int Corner;
> >typedef int Mass;
> >typedef int Health;
> >typedef int Frame;
> >typedef int Speed;
> >typedef long Quanta;
> >
> >// Data Structures
> >struct Pos {
> > Pos() {x = y = 0;}
> > Pos(int xx,int yy) {x = xx; y = yy;}
> >
> > int distance(const Pos &) const;
> > /* EFFECTS: Returns distance between two points. */
> >
> > int distance_2(const Pos&) const;
> > /* EFFECTS: Returns square of distance between two points. */
> >
> > int x; int y;
> >}; // In pixels
> >
> >
> >
> >struct Vel {
> > Vel() {dx = dy = 0.0;}
> > Vel(float x,float y) {dx = x; dy = y;}
> > void set_zero() {dx = dy = 0.0;}
> > Vel shrink(float k) const;
> > void damp(float k);
> > Boolean is_zero() const;
> > void limit(float k);
> > /* REQUIRES: k >= 0 */
> > /* EFFECTS: Force dx and dy to be <= k. */
> >
> > void get_dirs_4(Dir in[4],Dir out[4],int &inNum,int &outNum);
> > /* MODIFIES: in, out, inNum, outNum */
> > /* EFFECTS: Partitions {CO_R, CO_DN, CO_L, CO_UP} into in and out. inNum
> > and outNum are set to the sizes of the respective sets. */
> >
> > float dx; float dy;
> >};
> >
> >
> >
> >struct Size {
> > Dir get_dir();
> > /* EFFECTS: Returns one of {CO_R..CO_UP_R,CO_air}. */
> >
> > void get_dirs_4(Dir &d1,Dir &d2);
> > /* MODIFIES: d1, d2 */
> > /* EFFECTS: Gets the two directions of {CO_R,CO_DN,CO_L,CO_UP} that
> > correspond to *this. If there is only one, it is returned as d1 and
> > d2. If *this has zero size, d1 == d2 == CO_air on return. */
> >
> > float cross(const Vel &v);
> > /* EFFECTS: z component of the cross product of the size and the Vel. */
> >
> > void set_zero() {width = height = 0;}
> >
> > int abs_2() {return width*width + height*height;}
> >
> > int width; int height; // In pixels.
> >};
> >
> >
> >
> >// Constructors mess with TouchingList in area.hh
> >struct Loc {
> > int r,c; // In WSQUARES.
> >};
> >
> >
> >
> >struct Dim {
> > Dim() {rowMax = colMax = 0;}
> > Dim(int rm,int cm) {rowMax = rm; colMax = cm;}
> >
> > int rowMax, colMax; // In WSQUARES.
> >};
> >
> >
> >
> >struct Box {
> > Box() {};
> > Box(const Loc &l,const Dim &d) {loc = l; dim = d;}
> > Boolean overlap(const Loc &);
> >
> > Loc loc; Dim dim; // In WSQUARES.
> >};
> >
> >
> >
> >struct GLoc {
> > int vert, horiz;
> >};
> >
> >
> >
> >struct RoomIndex {int down; int across; }; // In rooms.
> >struct Rooms {
> > Rooms() {downMax = acrossMax = 0;}
> > Rooms(int dn,int acc) {downMax = dn; acrossMax = acc;}
> >
> > int downMax, acrossMax;
> >};
> >
> >
> >
> >struct Acc {
> > operator Vel()
> > {Vel ret(ddx,ddy); return ret;}
> > /* EFFECTS: Converts from an acceleration to velocity. Assumes initial
> > velocity is 0. */
> >
> > float ddx, ddy;
> >};
> >
> >
> >
> >struct Hanging {
> > Hanging() {corner = CO_air;}
> >
> > Corner corner;
> > Loc loc; // Not meaningful if corner == CO_air.
> >};
> >
> >
> >
> >typedef int Grav;
> >
> >enum Attack {attackNone, attackStuck, attackFree};
> >
> >
> >
> >// Function Prototypes
> >Boolean operator == (const Loc &l1, const Loc &l2);
> >Boolean operator == (const Pos &p1, const Pos &p2);
> >Boolean operator == (const Size &s1, const Size &s2);
> >Boolean operator == (const GLoc &,const GLoc &);
> >Boolean operator != (const GLoc &,const GLoc &);
> >Pos operator + (const Pos &pos,const Size &size);
> >Pos operator - (const Pos &pos,const Size &size);
> >Size operator - (const Pos &p1,const Pos &p2);
> >Pos operator + (const Pos &pos, const Vel &vel);
> >Size operator * (float k,const Size &size);
> >Vel operator + (const Vel &,const Vel &);
> >Vel operator + (const Vel &, const Acc &acc);
> >Vel operator * (float k,const Vel &vel);
> >Vel operator / (float k,const Vel &vel);
> >Vel operator + (float k,const Vel &vel);
> >Acc operator * (int k,const Acc &acc);
> >
> >
> >class Coord
> >{
> >public:
> > static Dir dir_opposite(Dir dir);
> >};
> >#endif
> >
> >
> >
> >;;;;;;; "area.hh"
> >// "area.hh"
> >// TAG: AR
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >#ifndef AREA_HH
> >#define AREA_HH
> >
> >#pragma interface
> >
> >
> >// Include Files
> >#include "utils.hh"
> >#include "coord.hh"
> >
> >
> >// Defines
> >#define AR_WSQUARES_MAX 20
> >enum ARshape {AR_RECT,AR_UNDEFINED};
> >enum ARsig {AR_NO_SIG, AR_CLOSE, AR_FAILURE, AR_BAD_SHAPE};
> >
> >
> >
> >// Data structures
> >struct TouchingListItem {
> > Loc list[AR_WSQUARES_MAX];
> > int num;
> >};
> >
> >struct TouchingList {
> > TouchingListItem r,dn,l,up;
> >};
> >
> >
> >class Area;
> >class Avoid;
> >
> >Size operator - (const Area &,const Area &);
> >/* EFFECTS: Subtract areas according to their upper left corners. */
> >
> >
> >// Class Declarations
> >class Area {
> > friend Size operator - (const Area &,const Area &);
> >
> > public:
> > Area() {shape = AR_UNDEFINED;}
> > /* EFFECTS: Create undefined area. */
> >
> > Area(ARshape c,const Pos &p,const Size &s);
> > /* REQUIRES: c is AR_RECT. */
> > /* EFFECTS: Creates a rectangle area at position p of size s. */
> >
> > void get_rect(Pos &p,Size &s) const;
> > /* MODIFIES: p,s */
> >
> > Box get_box() const;
> > /* EFFECTS: Returns the box of wsquares that contains the area. */
> >
> > void wsquares(Loc list[AR_WSQUARES_MAX],int &nitems) const;
> > /* MODIFIES: list, nitems */
> > /* EFFECTS: After completion, the first nitems of list contain the locations>
> > of all the wsquares covered by the area. The initial values of list
> > and nitems are ignored. wsquares are not necessarily inside the world. *>/
> >
> > Boolean overlap(const Area &) const;
> > /* EFFECTS: Returns True if *this overlaps with r, False otherwise. */
> >
> > Boolean overlap(const Loc &loc) const;
> > /* EFFECTS: Returns True if loc overlaps with any of the area. Returns
> > False otherwise. */
> >
> > Boolean overlap(const Box &box) const;
> > /* EFFECTS: Returns True if box overlaps with any of the area. Returns
> > False otherwise. */
> >
> > Boolean overlap(const Pos &pos) const;
> >
> > Loc middle_wsquare() const;
> > /* EFFECTS: Returns the location of the middle wsquare in the area. */
> >
> > ARsig avoid_wsquare(Avoid &avoid,const Loc &loc) const;
> > /* MODIFIES: avoid */
> > /* EFFECTS: Returns AR_NO_SIG if the wsquare at loc does not overlap with
> > the area. If loc overlaps in the area, but not in a nearby area, returns>
> > AR_CLOSE and sets avoid to be the offsets necessary to make the area no
> > longer touch the wsquare. */
> >
> > int avoid_wsquare_dir(const Loc &loc,Dir dir) const;
> > /* EFFECTS: Returns the amount *this will have to be shited in dir to avoid >
> > loc. */
> >
> > Size avoid(const Area &area) const;
> > /* EFFECTS: Returns the smallest offset necessary to move *this in order to
> > avoid area. */
> >
> > Size avoid_no_up(const Area &) const;
> > /* EFFECTS: Like avoid(), but will not avoid in the up direction. */
> >
> > Pos adjacent_rect(const Size &s,Dir dir) const;
> > /* EFFECTS: Return the upper left corner of the rectangle of size s that
> > touches *this such that the direction from *this to the rectangle is
> > dir. */
> >
> > Pos get_middle() const;
> > /* EFFECTS: Returns the middle of the area. */
> >
> > void touching_wsquares(TouchingList &list) const;
> > /* MODIFIES: list */
> > /* EFFECTS: Sets r,dn,l,up to be the lists of all wsquares that are exactly >
> > touching the area. The directions are set from the area to the touching >
> > wsquare. I.e. A loc listed under list.r would be touching the
> > right side of the area. The list are ordered such that the smallest
> > row and column indexes come first. I.e. top->bottom and left->right. */
> >
> > void shift(const Size &offset)
> > {assert(shape == AR_RECT); pos = pos + offset;}
> > /* EFFECTS: Shift the area by offset. */
> >
> > void set_middle(const Pos &pos);
> > /* EFFECTS: Move the area so that pos will be the middle. */
> >
> > Dir dir_to(const Pos &pos) const;
> > Dir dir_to(const Area &area) const;
> > /* EFFECTS: Returns the direction from this to pos or to area.
> > Will return one of {CO_R .. CO_UP_R, CO_air}. I.e. 8 directions or
> > CO_air. */
> >
> > Area combine(const Area &a) const;
> > /* EFFECTS: Returns minimum sized rectangular area that contains a and
> > this. */
> >
> >
> >public:
> > ARshape shape;
> > Pos pos;
> > Size size;
> >};
> >
> >
> >
> >class Avoid {
> >friend class Area;
> >
> >public:
> > void maximize(const Avoid &avoid);
> > /* EFFECTS: Set all directions of *this to be to max of *this and avoid. */
> >
> > Size offset_rank(int rank = 0) const;
> > /* REQUIRES: 0 <= rank < 4 */
> > /* EFFECTS: Return the offset corresponding to the rankth minimum direction
> > of *this using one dimensions. E.g. rank = 0 gives the minimum. rank
> > = 1 gives the second minimum, etc. */
> >
> > Size offset_dir(Dir d) const;
> > /* REQUIRES: d in {CO_R, CO_DN, CO_L, CO_UP} */
> > /* EFFECTS: Return the offset corresponding to d. */
> >
> > int get_dir(Dir d) const;
> > /* REQUIRES: d in {CO_R, CO_DN, CO_L, CO_UP} */
> > /* EFFECTS: Returns the offset in the specified direction. */
> >
> >
> >private:
> > /* Direction from area to wsquare. All are positive. r and dn are
> > therefore the negative of the corresponding offsets. */
> > int r,dn,l,up;
> >};
> >#endif
> >
> >
> >
> >;;;;;;;;;; "world.hh"
> >// "world.hh"
> >// TAG: W
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >/* Overview: A world object is a rectangular region composed of WSQUARES.
> > Internally, it is divided into rooms of constant size. It's upper left
> > corner is at WSQUARE (0,0).
> > World should be draw completely once before just drawing with changes. */
> >
> >#ifndef WORLD_HH
> >#define WORLD_HH
> >
> >#pragma interface
> >
> >
> >
> >// Include Files
> >#include "utils.hh"
> >#include "coord.hh"
> >#include "area.hh"
> >
> >
> >
> >// Defines.
> >// WSQUARES in a room.
> >#define W_ROOM_COL_MAX 40//36
> >#define W_ROOM_ROW_MAX 16//15
> >
> >/* Maximum rooms in world. World may actually be smaller. World starts out
> > at the size of the title screen. */
> >#define W_ACROSS_MAX_MAX 15
> >#define W_DOWN_MAX_MAX 15
> >
> >// WSQUARES in world.
> >#define W_COL_MAX_MAX (W_ROOM_COL_MAX * W_ACROSS_MAX_MAX)
> >#define W_ROW_MAX_MAX (W_ROOM_ROW_MAX * W_DOWN_MAX_MAX)
> >
> >/* The maximum number of wsquares that can be set changed/unchanged in one
> > clock cycle. */
> >#define W_CHANGES_MAX 5000
> >
> >/* The blocks composing the world. Represented as integers so that the world
> > map can be initialized easily. */
> >enum { Wempty, Wwall, Wladder, Woutside, Wsquanch, WupDown};
> >#define W_BLOCKS_NUM 6
> >
> >enum Wsig {W_NO_SIG, W_CLOSE, W_CLOSE_BAD, W_FAILURE};
> >typedef char Wmap[W_ROW_MAX_MAX][W_COL_MAX_MAX];
> >
> >#define W_POSTERS_NUM 6
> >
> >
> >
> >// Class Declarations
> >class World {
> > struct Wxdata {
> > Pixel background;
> > Pixmap pixmaps[W_BLOCKS_NUM];
> > // Array of pixmaps for a poster with columns changing fastest.
> > Pixmap *posterPixmaps[W_POSTERS_NUM];
> > };
> >
> > struct PosterSquare {
> > int poster;
> > Loc loc; // Inside poster.
> > };
> >
> >
> > public:
> > World(Boolean pol_correct);
> > /* EFFECTS: Create the title screen world. If politically correct,
> > there will be no posters and the title screen will be blank. */
> >
> > Size get_size() {return size;}
> > /* EFFECTS: Size of the world in pixels. */
> >
> > Dim get_dim() {return dim;}
> > /* EFFECTS: Dimensions of the world in wsquares. */
> >
> > Dim get_room_dim();
> > /* EFFECTS: Return the dimensions of a room in wsquares. */
> >
> > Size get_room_size();
> >
> > Rooms get_rooms() {return rooms;}
> > /* EFFECTS: The max number of rooms in across and down direction. */
> >
> > void set_rooms_next(const Rooms &r);
> > /* EFFECTS: After the next reset, the world will have as many rooms as r.
> > If r is bigger than the maximum, the min of the maximum size and r is
> > used. */
> >
> > void set_map_print(Boolean val) {mapPrint = val;}
> > /* EFFECTS: Sets whether to print each new map of the world at reset. */
> >
> > Boolean overlap(const Box &box);
> > /* EFFECTS: Does any of box overlap with the wsquares of the world. */
> >
> > void draw(Drawable buffer,Xvars &xv,const Box &box);
> > /* EFFECTS: Draw all of the box that is in the world. */
> >
> > void draw(Drawable buffer,Xvars &xv,const Area &area);
> > /* EFFECTS: Draw all of area that is in the world. */
> >
> > Boolean inside(const Loc &l)
> > {return l.r >= 0 && l.c >= 0 && l.r < dim.rowMax && l.c < dim.colMax;}
> > /* EFFECTS: Returns True if loc is a wsquare inside the world, otherwise
> > returns False. */
> >
> > Boolean open(const Loc &loc,Boolean laddersClosed = False,
> > Boolean postersClosed = False);
> > /* EFFECTS: Returns True if loc is an open square inside the world. Returns>
> > False otherwise. Note that wsquares outside the world are treated as if >
> > they were closed wsquares. */
> >
> > Boolean open(const Area &area,Boolean laddersClosed = False);
> > Boolean open(const Box &box,Boolean laddersClosed = False,
> > Boolean postersClosed = False);
> > /* EFFECTS: Is the portion of the world covered by area (or box) blocked?
> > laddersClosed implies that ladders and other non-walls are considered to >be
> > blocking. */
> >
> >
> >
> > Wsig open_offset(Size &offset,const Area &area,
> > const Vel &vel,Boolean laddersClosed = False);
> > /* MODIFIES: offset */
> > /* EFFECTS: Returns W_NO_SIG if the portion of the world covered by initial >
> > is open. prev is the previous area occupied before. If the area is
> > blocked, but a nearby area is not, returns
> > W_CLOSE_OK and sets offset to be the offset necessary to unblock initial.>
> > Retruns W_CLOSE_BLOCKED if a nearby area is blocked. Stills sets offset
> > for the nearby area. Returns W_FAILURE if initial and all nearby areas
> > are blocked. offset may be modified in any case. */
> >
> > void touchingHanging(Touching &touching, Hanging &hanging,
> > const Area &area);
> > /* REQUIRES: area is AR_RECT. */
> > /* MODIFIES: touching, hanging */
> > /* EFFECTS: If area is touching a blocked wsquare, sets touching to be the
> > direction from area to the wsquare. If the area is touching in both the
> > vertical and horizontal direction, the vertical takes precedence. Sets
> > touching to be CO_air if not touching in any direction. If the area is
> > hanging off of the edge of some blocked wsquares, sets hanging
> > appropriately. Otherwise, sets hanging.corner to be CO_air. */
> >
> > Boolean canClimb(const Loc &loc)
> > {return inside(loc) ? (map[loc.r][loc.c] == Wladder) : False;}
> > /* EFFECTS: Returns True if loc is a climable square inside the world. I.e.>
> > a ladder. False otherwise. */
> >
> > Pos empty_rect(const Size &size);
> > /* EFFECTS: Return the upper-left position of a randomly choosen empty
> > rectangle of size s. Ladders are not considered empty. */
> >
> > Pos empty_touching_rect(const Size &size);
> > /* EFFECTS: Like empty_rect except the returned rect will be touching the
> > ground. */
> >
> > Boolean empty_box(Loc &loc,const Dim &dim,Boolean laddersClosed,
> > Boolean postersClosed);
> > /* MODIFIES: loc */
> > /* EFFECTS: Returns True iff an empty box of dimension dim can be found and
> > returns its upper-left Loc. */
> >
> > void reset();
> > /* EFFECTS: Prepare the world for a new game. Create a new map. */
> >
> > void clock() {}
> >
> >
> > private:
> > Pixmap draw_square(Drawable buffer,Xvars &xvars,const Loc &loc,int x,int y);>
> >
> > /* EFFECTS: Draw the appropriate square from loc to (x,y) on buffer. */
> >
> > void dim_size_update();
> > /* EFFECTS: Updates dim and size from the current value of rooms. */
> >
> > void init_x(Xvars &);
> > /* EFFECTS: Initialize all x dependencies. */
> >
> > void title_map();
> >
> > void th_helper(Touching &touching,Hanging &hanging,
> > const TouchingListItem &item,
> > Boolean r_c,
> > int coord,int length,
> > int wsquare_length,
> > Touching iftouching,
> > Corner ifsmall, Corner iflarge);
> > /* MODIFIES: touching, hanging */
> > /* EFFECTS: Helper for World::touching. Does touching, hanging for one
> > side. */
> >
> > Boolean open_iter(Area &area,int &changed,Dir dir,Boolean laddersClosed);
> > /* MODIFIES: area, changed */
> > /* EFFECTS: Move area as much in dir as necessary to avoid all its wsquares.>
> > Increment changed by the distance moved. Return True if the original
> > area is open and nothing is changed.*/
> >
> > Size open_size(int offset,Dir dir);
> > Size open_size(int offset1,Dir dir1,int offset2,Dir dir2);
> > /* REQUIRES: dir is in {CO_R, CO_DN, CO_L, CO_UP} */
> > /* EFFECTS: Return the Size corresponding to an offset in one or two
> > directions. */
> >
> > Boolean open_try_dirs(Size &offset,const Area &area,const Dir dirs[4],
> > int dirsNum,Boolean laddersClosed);
> > /* MODIFIES: offset */
> > /* EFFECTS: Sets offset to be the minimum necessary to shift area to an
> > open area in one of the directions of dirs. Returns whether it
> > succeeded. offset may be changed in any case. */
> >
> > Boolean open_try_diagonals(Size &offset,const Area &area,
> > Boolean laddersClosed);
> > /* MODIFIES: offset */
> > /* EFFECTS: Set offset to shift area to a nearby open one. Returns whether
> > it succeeded. offset may be changed in any case. */
> >
> > Rooms rooms,roomsNext;
> > Size size; /* For convenience only. */
> > Dim dim; /* For convenience only. */
> >
> > Wmap map;
> > Boolean xValid;
> > Wxdata xdata;
> > Boolean mapPrint;
> > Dim posterDims[W_POSTERS_NUM];
> > PosterSquare *posterSquares[W_ROW_MAX_MAX][W_COL_MAX_MAX];
> > Boolean polCorrect;
> >
> > // Defined in world.bitmaps.
> > static unsigned char *posterPixmapBits[W_POSTERS_NUM];
> > static unsigned char *posterMaskBits[W_POSTERS_NUM];
> > static const Size posterSizes[W_POSTERS_NUM];
> > static const char *posterForegrounds[W_POSTERS_NUM];
> > static const char *posterBackgrounds[W_POSTERS_NUM];
> > static unsigned char *pixmapBits[W_BLOCKS_NUM];
> > static const char *colorNames[W_BLOCKS_NUM];
> >};
> >
> >
> >
> >// Typdefs
> > typedef World *WorldP;
> >#endif
> >
> >
> >
> >
> >;;;;;;;;;;;;;;; "id.hh"
> >// Object locator id.
> >// TAG: ID
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@escher.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >#ifndef ID_HH
> >#define ID_HH
> >
> >// No '#pragma interface' because there is no "id.cc".
> >
> >
> >class Locator;
> >class Id {
> > friend class Locator;
> >
> > public:
> > Id() {index = INVALID;}
> > Boolean operator == (const Id &other) const
> > {return (other.index == index) && (other.unique == unique);}
> > Boolean operator != (const Id &other) const
> > {return (other.index != index) || (other.unique != unique);}
> >
> > private:
> > enum {INVALID = -1};
> > int index;
> > int unique;
> >};
> >
> >#endif
> >
> >
> >
> >;;;;;;;;;; "intel.hh"
> >// "intel.hh"
> >// TAG: IT
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >#ifndef INTEL_HH
> >#define INTEL_HH
> >
> >#pragma interface
> >
> >
> >// Include Files
> >#include "utils.hh"
> >#include "coord.hh"
> >#include "id.hh"
> >#include "locator.hh"
> >#include "world.hh"
> >
> >
> >
> >// Defines
> >#define IT_STRING_LENGTH 80
> >
> >
> >
> >class Physical;
> >typedef Physical *PhysicalP;
> >
> >
> >/* Possible commands to be given to objects.
> > Order of directions is guaranteed. (See ui.hh and game.cc) */
> > enum ITcommand {
> > IT_CENTER,
> > IT_R, IT_DN_R, IT_DN, IT_DN_L,
> > IT_L, IT_UP_L, IT_UP, IT_UP_R,
> > IT_WEAPON_CENTER,IT_WEAPON_CHANGE,IT_WEAPON_DROP,
> > IT_ITEM_USE,IT_ITEM_CHANGE,IT_ITEM_DROP,
> >
> > IT_WEAPON_R,IT_WEAPON_DN_R,IT_WEAPON_DN,IT_WEAPON_DN_L,
> > IT_WEAPON_L,IT_WEAPON_UP_L,IT_WEAPON_UP,IT_WEAPON_UP_R,
> >
> > IT_NO_COMMAND};
> >#define IT_COMMAND_MAX IT_NO_COMMAND
> >
> >
> >
> >// IntelOptions
> >typedef unsigned long ITmask;
> >#define ITnone 0L
> >#define ITharmless (1L<<0)
> >#define ITclassFriends (1L<<1)
> >
> >struct IntelOptions {
> > Boolean classFriends;
> > Boolean harmless;
> >};
> >
> >
> >
> >// IntelStatus used by ui.
> >// Remember Intel::die
> >struct IntelStatus {
> > // strings and ClassIds must be kept consistent.
> >
> > char name[IT_STRING_LENGTH];
> > ClassId classId;
> > char clas[IT_STRING_LENGTH];
> > Health health; // -1 means dead.
> > Mass mass;
> > ClassId weaponClassId;
> > char weapon[IT_STRING_LENGTH];
> > Boolean weaponReady;
> > int ammo;
> > ClassId itemClassId;
> > char item[IT_STRING_LENGTH];
> > int lives;
> > int kills;
> >};
> >
> >
> >
> >// Class Definitions.
> >class Intel {
> > public:
> > Intel(WorldP w,LocatorP l,char *name,int lives,
> > const IntelOptions *ops,ITmask opMask);
> > /* EFFECTS: Create a new intel with the options specified in opMakse that ar>e
> > in ops. ops will never be referenced if opMask is ITnone. lives are
> > decremented as human is created. */
> >
> > virtual Boolean is_human() {return False;}
> >
> > Boolean alive() {return living;}
> > WorldP get_world() {return world;}
> > LocatorP get_locator() {return locator;}
> >
> > const Id &get_id() {return id;}
> > /* NOTE: If dead, return an invalid id. */
> >
> > Boolean reincarnate_me() {return !living && (intelStatus.lives > 0);}
> > /* EFFECTS: Should *this be reincarnated. */
> >
> > Boolean intel_status_changed() {return intelStatusChanged;}
> >
> > const IntelStatus *get_intel_status()
> > {intelStatusChanged = False; return &intelStatus;}
> >
> > const char *get_name() {return intelStatus.name;}
> > int get_lives() {return intelStatus.lives;}
> > int get_kills() {return intelStatus.kills;}
> > /* NOTE: Could achieve the same thing with get_intel_status. Convenience
> > functions. */
> >
> > void set_id(const Id &i) {id = i;}
> > /* REQUIRES: i is valid. */
> > /* NOTE: Only needed for Physical::set_intel. id is updated on every
> > clock. */
> >
> > void add_kill() {intelStatusChanged = True; intelStatus.kills++;}
> >
> > static ITcommand dir_to_command(Dir dir);
> > /* REQUIRES: dir is a "pure" direction or CO_air. */
> > /* NOTE: CO_air -> IT_CENTER. */
> >
> > static ITcommand dir_to_command_weapon(Dir dir);
> >
> > static Dir command_weapon_to_dir_4(ITcommand);
> >
> > static Boolean is_command_weapon(ITcommand command)
> > {return (command >= IT_WEAPON_R && command <= IT_WEAPON_UP_R) ||
> > command == IT_WEAPON_CENTER;}
> >
> > static ITcommand center_pos_to_command(const Pos &pos);
> > /* EFFECTS: Returns the command corresponding to the direction from (0,0) to>
> > pos. */
> > /* NOTE: pos can have negative components. */
> >
> >
> > void die();
> > /* EFFECTS: Tell *this that it no longer has anything clocking it. */
> > /* NOTE: This MUST be called at death. Game requires it to refill machine
> > players. */
> >
> > void reincarnate();
> > /* EFFECTS: Tell *this that it will be clocked again. */
> >
> > virtual void clock(PhysicalP p);
> >
> >
> > protected:
> > const IntelOptions &get_intel_options() {return intelOptions;}
> >
> > void set_lives(int lives)
> > {intelStatus.lives = lives; intelStatusChanged = True;}
> >
> >
> > private:
> > IntelStatus intelStatus;
> > Boolean intelStatusChanged; // Since last get_intel_status.
> > Boolean living;
> > WorldP world;
> > LocatorP locator;
> > Id id;
> > IntelOptions intelOptions;
> >
> > const static IntelOptions intelOptionsDefault;
> >};
> >typedef Intel *IntelP;
> >
> >
> >
> >// Simply buffers input from a user interface.
> >class Human: public Intel {
> > public:
> > Human(WorldP w,LocatorP l,char *name,int lives,ColorNum colorNum);
> > /* NOTE: Uses all default options. intelOptions should be meaningless for
> > a human. */
> >
> > ColorNum get_color_num() {return colorNum;}
> >
> > virtual Boolean is_human() {return True;}
> >
> > virtual void clock(PhysicalP p);
> > /* EFFECTS: Sets the command for p. */
> >
> > void set_command(ITcommand c) {command = c;}
> > /* EFFECTS: Asynchronously set the command for the current turn to be c.
> > Overrides previous settings. */
> >
> > void set_lives(int lives) {Intel::set_lives(lives);}
> >
> >
> > private:
> > ITcommand command;
> > ColorNum colorNum;
> >};
> >typedef Human *HumanP;
> >
> >
> >
> >class Machine: public Intel {
> > enum Strategy {doNothing, toTarget, awayTarget, toPos};
> >
> >public:
> > Machine(WorldP w,LocatorP l,char *name,
> > const IntelOptions *ops,ITmask opMask);
> >
> > virtual void clock(PhysicalP);
> >
> >
> >private:
> > PhysicalP new_target_id(Boolean &isEnemy,PhysicalP p);
> > /* MODIFIES: isItem */
> > /* EFFECTS: Get a new target for p. Sets targetId, sets isEnemy to True iff>
> > returned pointer is an enemy (as opposed to an item).
> > Returns NULL if no suitable target found. */
> >
> > void attack_target(PhysicalP p,PhysicalP target);
> >
> > void move_target(PhysicalP p,PhysicalP target);
> > /* EFFECTS: Sets the command for p to move toward target. */
> >
> > void away_target(PhysicalP p,PhysicalP target);
> > /* EFFECTS: Sets the command for p to move away from target. */
> >
> > void move_pos(PhysicalP p);
> > /* EFFECTS: Sets the command for p to move toward targetPos. */
> >
> > void move_dir(PhysicalP p,Dir d);
> > /* REQUIRES: d is an element of {CO_R..CO_UP_R,CO_air} */
> > /* EFFECTS: Sets the command for p to move in specified direction. */
> >
> > Boolean has_gun(PhysicalP);
> > Boolean has_cutter(PhysicalP);
> > Boolean has_item(PhysicalP,ClassId);
> >
> > Boolean weapon_current_is_gun(PhysicalP);
> > Boolean weapon_current_is_cutter(PhysicalP);
> >
> >
> > Boolean commandSet;
> > Strategy strategy;
> > Pos targetPos;
> > Id targetId;
> > Timer strategyChange;
> > Timer reflexes;
> > Timer shotTimer;
> > Timer ladderJump; // don't get back on ladder immediately after jumping off.>
> >};
> >typedef Machine *MachineP;
> >#endif
> >
> >
> >
> >
> >;;;;;;;;; "locator.hh"
> >// "locator.hh" The object locator.
> >// TAG: OL
> >
> >/* Copyright (C) 1994 Steve Hardt
> >
> > 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> >
> > Steve Hardt
> > hardts@athena.mit.edu (or hardts@r4002.3dem.bioch.bcm.tmc.edu)
> > 2043 McClendon
> > Houston, TX 77030
> >*/
> >
> >/* Overview:
> >The locator can be seen as the collection of all physical objects in
> >the game. It draws all objects with the draw method. The clock
> >method goes through all the phases of one turn for all objects. This
> >is the only entity in the game that has a list of all the objects.
> >Objects can be mapped and/or collidable. An unmapped object is
> >neither drawn nor collided. An uncollidable object is drawn (if
> >mapped) but not collided. There is a message queue that objects can
> >use to communicate with the ui object. The locator does not need to
> >be clocked for the queue to work.
> >The locator grid is the maximum size of the world. I.e. it can be larger than>
> >the world. */
> >
> >
> >#ifndef LOCATOR_HH
> >#define LOCATOR_HH
> >
> >#pragma interface
> >
> >
> >// Include Files
> >#include <iostream.h>
> >
> >#include "utils.hh"
> >#include "coord.hh"
> >#include "id.hh"
> >#include "world.hh"
> >
> >class Physical;
> >typedef Physical *PhysicalP;
> >class Human;
> >typedef Human *HumanP;
> >class Machine;
> >typedef Machine *MachineP;
> >
> >
> >// Defines
> >#define OL_LIST_MAX 1000
> >#define OL_NEARBY_MAX OL_LIST_MAX
> >#define OL_MESSAGES_MAX 300
> >
> >#define OL_GRID_COL_MAX 4
> >#define OL_GRID_ROW_MAX 4
> >#define OL_GRID_WIDTH (OL_GRID_COL_MAX * WSQUARE_WIDTH) // In pixels.
> >#define OL_GRID_HEIGHT (OL_GRID_ROW_MAX * WSQUARE_HEIGHT) // In pixels.
> >#define OL_GRID_SIZE_MAX (max(OL_GRID_WIDTH,OL_GRID_HEIGHT))
> >#define OL_GRID_HORIZ_MAX (W_COL_MAX_MAX / OL_GRID_COL_MAX + 1)// grid squares>.
> >#define OL_GRID_VERT_MAX (W_ROW_MAX_MAX / OL_GRID_ROW_MAX + 1) // grid squares>.
> >
> >#define OL_DRAWING_LEVELS 2
> >
> >// Data Structures.
> >enum OLsig {OL_NO_SIG, OL_ALREADY_MANAGED, OL_NOT_FOUND};
> >
> >
> >
> >// Class Declarations
> >class Locator;
> >class OLgridEntry;
> >class OLshadowEntry;
> >
> >
> >class OLentry {
> > friend class Locator;
> > friend class OLgridEntry;
> > friend class OLshadowEntry;
> >
> > OLgridEntry *gridEntry; /* Only valid if mapped. */
> > GLoc gloc; /* Set by OLgridEntry::insert. Not nec. valid. */
> > OLshadowEntry *shadowEntry; /* Only valid if mapped. */
> > GLoc shadowGloc; /* Set by OLshadowEntry::insert. Not nec. valid. */
> >
> >
> > Boolean valid;
> > Boolean reserved; // Meaningful when !valid.
> > PhysicalP physical; // Set when reserved.
> >
> > Boolean collided;
> > Boolean mapped; // Redundant. Must be same as in object.
> > Boolean collidable;
> >};
> >
> >
> >
> >class OLgridEntry {
> > public:
> > OLgridEntry(OLentry *e) {entry = e; prev = next = NULL;}
> >
> > PhysicalP get_physical() {return entry->physical;}
> > Boolean get_collided() {return entry->collided;}
> > Boolean get_mapped() {return entry->mapped;}
> > OLshadowEntry *get_shadow_entry() {return entry->shadowEntry;}
> > const Area &get_area();
> >
> > int get_drawing_level();
> >
> > Boolean get_collidable() {return entry->collidable;}
> > OLgridEntry *get_next() {return next;}
> >
> > void set_collided(Boolean val) {entry->collided = val;}
> >
> > void insert(OLgridEntry *grid[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX],
> > const GLoc &gl);
> > /* NOTE: gl does not have to be valid. */
> > void remove();
> >
> >
> > private:
> > OLgridEntry *prev, *next;
> > OLentry *entry;
> >};
> >// This typedef not always used. OLgridEntry::insert
> >typedef OLgridEntry *OLgrid[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX];
> >
> >
> >
> >class OLshadowEntry {
> > public:
> > OLshadowEntry() {entry = NULL; prev = next = NULL; orphaned = False;}
> > OLshadowEntry(const Area &a,OLentry *e)
> > {area = a; entry = e; prev = next = NULL; orphaned = False;}
> > Boolean get_orphaned() {return orphaned;}
> >
> > OLentry *get_entry() {assert(entry); return entry;}
> > OLgridEntry *get_grid_entry() {assert(entry); return entry->gridEntry;}
> > const Area &get_area() {return area;}
> > Boolean draw_self() {return drawSelf;}
> > OLshadowEntry *get_next() {return next;}
> > /* NOTE: Several require that the shadowEntry is not orphaned. */
> >
> > void set_area(const Area &a) {area = a;}
> > void set_draw_self(Boolean val) {drawSelf = val;}
> > void set_orphaned() {orphaned = True; entry = NULL;}
> >
> >
> > void insert(OLshadowEntry *shadows[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX],
> > const GLoc &gl);
> > void remove();
> >
> >
> > private:
> > Boolean orphaned;
> > Area area;
> > Boolean drawSelf;
> > OLentry *entry;
> > OLshadowEntry *prev, *next;
> >};
> >typedef OLshadowEntry *OLshadows[OL_GRID_VERT_MAX][OL_GRID_HORIZ_MAX];
> >
> >
> >
> >class Locator {
> > struct OLxdata
> > {
> > Pixmap roomBuffer; // When changing rooms.
> > Pixmap buffer;
> > };
> >
> >
> > // Iterator to extract all humans to be reincarnated.
> > class Incarnator {
> > public:
> > Incarnator::Incarnator(Locator &l) {n = 0; locator = &l;}
> >
> > HumanP operator () ();
> > /* EFFECTS: Extract next object to be reincarnated. Return NULL if none.
> > The returned HumanP can only be extracted once. */
> >
> > private:
> > int n;
> > Locator *locator;
> > };
> >
> >friend class Locator::Incarnator;
> >
> >
> > public:
> > enum { HUMANS_MAX = Utils::HUMAN_COLORS_NUM, // <= UI_VIEWPORTS_MAX.
> > MACHINES_MAX = 200,
> > GENERATORS_MAX = 30,
> > };
> >
> > Locator();
> > /* EFFECTS: Create a new object locator with no managed objects. */
> >
> > static Boolean valid(const GLoc &gl)
> > {return ((gl.vert >= 0) && (gl.horiz >= 0) &&
> > (gl.vert < OL_GRID_VERT_MAX) && (gl.horiz < OL_GRID_HORIZ_MAX));}
> > /* EFFECTS: Is gl a loc in the grid. */
> >
> > void add(PhysicalP p);
> > /* REQUIRES: p is not already managed. */
> > /* EFFECTS: p will be added to the list of managed physicals at the beginnin>g
> > of the next clock. p is initially mapped. canCollide is set from p.
> > If called inside clock, object will not be added until beginning of next
> > clock. You should not add something twice. */
> >
> > void get_nearby(PhysicalP nearby[OL_NEARBY_MAX],int &nitems,
> > PhysicalP p,int radius);
> > /* MODIFIES: nearby,nitems. */
> > /* EFFECTS: Returns all objects that have their middles within radius of
> > p's middle. (I.e <= ) */
> > /* NOTE: Expensive. */
> >
> > OLsig lookup(PhysicalP &p, const Id &id);
> > /* MODIFIES: p */
> > /* EFFECTS: Set p to be the object corresponding to id if it is managed
> > and return OL_NO_SIG. Otherwise return OL_NOT_FOUND. */
> >
> > PhysicalP lookup(const Id &id);
> > /* EFFECTS: Same as above except return NULL iff not found. */
> >
> > void draw(WorldP world,Drawable window,Xvars &xvars,const Box &box);
> > /* REQUIRES: win is the same size as Box. (Adjusted for size of WSQUAREs.) *>/
> >
> > void reset();
> >
> > void clock();
> >
> >
> > // Message service.
> > void message_enq(char *msg);
> > /* EFFECTS: Enqueue msg in the queue of messages for the ui. The ui will
> > free msg when it is done with it. */
> >
> > char *message_deq();
> > /* EFFECTS: Dequeue the next message of the message queue or return NULL if
> > the queue is empty. */
> >
> >
> > // Player registry service. Takes responsibility for reincarnation.
> > void register_human(HumanP); // Kept until reset.
> > void register_machine(MachineP); // Deleted as needed.
> > void register_generator(const Id &); // Id is kept until reset.
> >
> > int humans_playing();
> > int machines_alive();
> > int generators_alive();
> >
> > HumanP get_human(int n) {assert(n < humansNum); return humans[n];}
> > /* REQUIRES: n < the number of humans registered */
> >
> >
> > private:
> > enum { REINCARNATE_TIME = 70 };
> >
> > void add_now(PhysicalP);
> > void del_now(PhysicalP);
> >
> > void allign_mapped(int n);
> > /* EFFECTS: Checks to see if physical n has changed its mapped attribute. I>f
> > so, adjust the mapped attribute in *this. */
> > /* REQUIRES: n is a valid list index. */
> >
> > void init_x(WorldP,Xvars &);
> > /* NOTES: world just for roomSize. */
> >
> > Id reserve_list_entry(PhysicalP p);
> > /* EFFECTS: Reserve an entry in the list for p and return an Id for the
> > entry. */
> >
> > void collision_checks();
> > /* EFFECTS: Do collision checks between all registered objects. */
> >
> > GLoc compute_gloc(PhysicalP);
> > GLoc compute_gloc(const Area &);
> > /* EFFECTS: Compute the location in the grid for a physical or an area. */
> > /* NOTE: Ok to return invalid gloc. */
> >
> > void draw_area(WorldP world,Drawable window,Xvars &xvars,const Box &room,
> > const Area &area,const GLoc &gloc);
> > /* REQUIRES: area is centered at gloc. window is the size of room*/
> > /* EFFECTS: Draws world and all objects overlapping area. */
> > /* NOTE: box does not have to be valid. */
> >
> > void reincarnate_clock();
> >
> >
> > // Data.
> > int uniqueGen;
> > int listMax; // All valid entries in the list have index < listMax.
> > OLentry list[OL_LIST_MAX];
> > OLgrid grid;
> >
> > OLshadows shadows;
> > OLshadowEntry *shadowDelList[OL_LIST_MAX];
> > int shadowDelNum;
> >
> > PhysicalP addList[OL_LIST_MAX];
> > int addNum;
> >
> > Boolean xValid;
> > OLxdata xdata;
> >
> > // Message service.
> > char *messages[OL_MESSAGES_MAX];
> > int head,tail;
> >
> > // Player registry service.
> > HumanP humans[HUMANS_MAX];
> > MachineP machines[MACHINES_MAX];
> > Id generators[GENERATORS_MAX];
> > int humansNum;
> > int machinesNum;
> > int generatorsNum;
> > Boolean reincarnating[HUMANS_MAX]; // Just for humans.
> > Timer reincarnateTimers[HUMANS_MAX]; // Just for humans.
> >};
> >typedef Locator *LocatorP;
> >#endif
> >
EOF_EOF_EOF
------- End of Forwarded Message