home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
gnu
/
gchsrc31.lzh
/
INCLUDE
/
SPRITE.H
< prev
Wrap
C/C++ Source or Header
|
1992-04-27
|
10KB
|
365 lines
//////////////////////////////////////////////////////////////////////////////
//
// This file is part of the Atari Machine Specific Library,
// and is Copyright 1992 by Warwick W. Allison.
//
// You are free to copy and modify these sources, provided you acknoledge
// the origin by retaining this notice, and adhere to the conditions
// described in the file COPYING.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef _Sprite_h
#define _Sprite_h
//////////////////////////////////////////////////////////////////////////////
//
// Sprites
// -------
//
// Small objects, double buffered.
//
// Sprites have position (x,y), and shape (an index into a list of
// Incarnations). They can be drawn, wiped, moved and reshaped.
//
// Incarnations are positionless images that can be drawn and wiped.
// They come in many forms, each tuned to give certain qualities:
//
// class Incarnation
// Base class from which others are derived.
//
// class MonochromeIncarnation
// 16 pixels wide (any height), monochrome image (For STHigh and TTHigh).
//
// class PreshiftedMonochromeIncarnation
// 16 pixels wide, Faster than regular images, but use 32x memory.
//
// class WideMonochromeIncarnation
// 32 pixels wide, monochrome image.
//
// class ColourIncarnation
// 16 pixels wide, 16 colour (for STLow and TTMedium).
//
// class PreshiftedColourIncarnation
// 16 pixels wide, Faster than regular colour sprites.
//
// class WideColourIncarnation
// 32 pixels wide.
//
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <bool.h>
#include "DoubleBuffer.h"
class Incarnation
{
public:
// Set hot spot (default (0,0))
void SetHotSpot(short x, short y);
// I/O
virtual int fput(FILE *fp);
// Draw/Wipe image from double buffer page. Coordinates are in pixels.
virtual void Draw(short x, short y, long *Store)=0;
virtual int TouchDraw(short x, short y, long *Store)=0; // not implemented
virtual void Wipe(long *Store)=0;
// Take the area at (x,y) on the given screen as the image.
// x must be multiple of 16.
virtual void GetImage(Screen&, int x, int y)=0;
// Return width and height of the incarnation.
// Width is actual pixel width from the left.
short Width() { return width; }
short Height() { return height; }
// Words of backing store used by the incarnmation (used by Sprite)
int BackingRequired() { return Backing; }
protected:
Incarnation(FILE *fp);
Incarnation(short h, int b);
short width,height; // In pixels
short HotX=0,HotY=0;
int Backing;
};
class Sprite
{
public:
// Constructors:
// A sprite with one shape.
Sprite(Incarnation *OnlyOne);
// A sprite with an array of shapes.
Sprite(Incarnation **ListOfThem,int Count);
// A sprite with a list of (undefined) shapes.
Sprite(short maxinca);
// A sprite with the same shapes as another sprite.
Sprite(Sprite& Copy);
// A sprite from a file.
Sprite(const char *filename);
Sprite(FILE *);
// Destructor
~Sprite();
// I/O
int Load(const char *filename);
int Save(const char *filename);
int fput(FILE *);
int fget(FILE *);
// Draw on current page
void Draw();
int TouchDraw(); // not implemented
// Remove from page. If already wiped, does nothing.
void Wipe();
// Choose incarnation, starting from 0.
void ShapeTo(short);
// Scale of pixels to coords. Coord = 2**Scale * Pixel
// All values below are scaled by this amount
void Scale(short s) { Shift=s; }
// Move
void MoveTo(int x, int y);
void MoveBy(int x, int y);
// Set one of the possible shapes to a given Incarnation
void SetImage(int i, Incarnation* In);
// Inspectors
int X() { return x; }
int Y() { return y; }
int Shape() { return shape; }
int Width() { return Inca[shape]->Width() << Shift; }
int Height() { return Inca[shape]->Height() << Shift; }
protected:
int x,y;
short shape;
short Shift=0;
long *BackingStore[2];
unsigned int BackingSize;
char *OverlayMask;
short MaxInca;
Incarnation **Inca; // Dynamically allocated array of *Incarnation
private:
bool ExternalInca;
};
//
// Mobile Sprite - an experimental derived class of Sprite.
//
enum BoundaryEffect {Bounce, Wrap, Stop, Watch};
const int HitNorth=1;
const int HitSouth=2;
const int HitEast=4;
const int HitWest=8;
class MobileSprite : public Sprite
{
public:
MobileSprite(Incarnation **Them,int Count) : Sprite(Them,Count) {}
MobileSprite(Incarnation *OnlyOne) : Sprite(OnlyOne) {}
MobileSprite(short maxinca) : Sprite(maxinca) {}
MobileSprite(const char *filename) : Sprite(filename) {}
void Accelerate(int, int);
bool Stationary() { return (!xi && !yi); }
void Speed(int, int);
void XSpeed(int);
void YSpeed(int);
int XSpeed();
int YSpeed();
void Range(int, int, int, int);
short Move(); // Efftected Edges returned
void Unmove(); // Just undo the move
void Rebound(short Walls); // Undo and rebound against given walls
void Frictate(short fric);
void AtBoundary(BoundaryEffect, short Bouncy=256);
void AtBoundary(BoundaryEffect North,
BoundaryEffect South,
BoundaryEffect East,
BoundaryEffect West, short Bouncy=256);
private:
int xi=0,yi=0;
int Bounciness=256;
int MinX= -10000;
int MinY= -10000;
int MaxX= +10000;
int MaxY= +10000;
BoundaryEffect AtEdge[4]={Watch,Watch,Watch,Watch};
};
/////////////////////////////
//
// Below are all the derived Incarnations,
// see main comment for details.
//
/////////////////////////////
class MonochromeIncarnation : public Incarnation
{
public:
MonochromeIncarnation(int height);
virtual ~MonochromeIncarnation();
virtual void Draw(short x, short y, long *Store);
virtual int TouchDraw(short x, short y, long* Store);
virtual void Wipe(long *Store);
virtual int fput(FILE *fp);
virtual void GetImage(Screen&, int x, int y);
private:
friend Incarnation* IncarnationReader(FILE *fp);
MonochromeIncarnation(FILE*);
short unsigned *Data,*Mask;
};
class WideMonochromeIncarnation : public Incarnation
{
public:
WideMonochromeIncarnation(int height);
virtual ~WideMonochromeIncarnation();
virtual void Draw(short x, short y, long *Store);
virtual int TouchDraw(short x, short y, long* Store);
virtual void Wipe(long *Store);
virtual int fput(FILE *fp);
virtual void GetImage(Screen&, int x, int y);
private:
friend Incarnation* IncarnationReader(FILE *fp);
WideMonochromeIncarnation(FILE*);
unsigned long *Data,*Mask;
};
class PreshiftedMonochromeIncarnation : public Incarnation
{
public:
PreshiftedMonochromeIncarnation(int height);
virtual ~PreshiftedMonochromeIncarnation();
virtual void Draw(short x, short y, long *Store);
virtual int TouchDraw(short x, short y, long* Store);
virtual void Wipe(long *Store);
virtual int fput(FILE *fp);
virtual void GetImage(Screen&, int x, int y);
private:
friend Incarnation* IncarnationReader(FILE *fp);
PreshiftedMonochromeIncarnation(FILE*);
unsigned long *Data[16],*Mask[16];
};
class WideColourIncarnation : public Incarnation
{
public:
WideColourIncarnation(int height);
virtual ~WideColourIncarnation();
virtual void Draw(short x, short y, long *Store);
virtual int TouchDraw(short x, short y, long* Store);
virtual void Wipe(long *Store);
virtual int fput(FILE *fp);
virtual void GetImage(Screen&, int x, int y);
private:
friend Incarnation* IncarnationReader(FILE *fp);
WideColourIncarnation(FILE*);
long unsigned *Data,*Mask;
};
class ColourIncarnation : public Incarnation
{
public:
ColourIncarnation(int height);
virtual ~ColourIncarnation();
virtual void Draw(short x, short y, long *Store);
virtual int TouchDraw(short x, short y, long* Store);
virtual void Wipe(long *Store);
virtual int fput(FILE *fp);
virtual void GetImage(Screen&, int x, int y);
private:
friend Incarnation* IncarnationReader(FILE *fp);
ColourIncarnation(FILE*);
short unsigned *Data,*Mask;
};
class PreshiftedColourIncarnation : public Incarnation
{
public:
PreshiftedColourIncarnation(int height);
virtual ~PreshiftedColourIncarnation();
virtual void Draw(short x, short y, long *Store);
virtual int TouchDraw(short x, short y, long* Store);
virtual void Wipe(long *Store);
virtual int fput(FILE *fp);
virtual void GetImage(Screen&, int x, int y);
private:
friend Incarnation* IncarnationReader(FILE *fp);
PreshiftedColourIncarnation(FILE*);
short unsigned *Data[16],*Mask[16];
};
// Some inlines for efficiency...
inline void Sprite::MoveTo(int X, int Y) { x=X; y=Y; }
inline void Sprite::MoveBy(int X, int Y) { x+=X; y+=Y; }
inline void Sprite::ShapeTo(short s) { shape=s; }
inline void MobileSprite::Range(int minx, int miny, int maxx, int maxy)
{ MinX=minx; MaxX=maxx; MinY=miny; MaxY=maxy; }
inline void MobileSprite::Speed(int x, int y) { xi=x; yi=y; }
inline void MobileSprite::XSpeed(int x) { xi=x; }
inline void MobileSprite::YSpeed(int y) { yi=y; }
inline int MobileSprite::XSpeed() { return xi; }
inline int MobileSprite::YSpeed() { return yi; }
inline void MobileSprite::Accelerate(int x, int y) { xi+=x; yi+=y; }
inline void MobileSprite::Unmove() { MoveBy(-xi,-yi); }
inline void MobileSprite::Frictate(short f) { f=256-f; xi=xi*f/256; yi=yi*f/256; }
#endif // !Sprite_h