Skip to content

Commit

Permalink
Sprite C++ library & demo added
Browse files Browse the repository at this point in the history
  • Loading branch information
pcawte committed Aug 17, 2023
1 parent 345e98d commit 0733de5
Show file tree
Hide file tree
Showing 193 changed files with 2,259 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,18 @@ In the relevant: example, test or any other directory created at the same level.

- zx0 & zx7 compression: okay

16/08/2023

- Corrected typo in this file

17/08/2023

- `vdp_key.h` and `vdp_vdu.h` moved to `agon` subdirectory in `include` folder

- Sprite C++ library header files stored in `Sprite` subdirectory in `include` folder

- `sprite-demos` folder added with `invaders` demo

### To-Do / Known Issues:

- Testing / validation
Expand Down
15 changes: 15 additions & 0 deletions include/Sprite/Coords.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef _COORDS_HPP

#define _COORDS_HPP


// Simple class to represent coordinates

class Coords {
public:
int x, y;
Coords() {}
Coords( int xcoord, int ycoord ) { x=xcoord; y=ycoord; }
};

#endif
28 changes: 28 additions & 0 deletions include/Sprite/DummySpriteGroup.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef _DUMMYSPRITEGROUP_HPP

#define _DUMMYSPRITEGROUP_HPP

// Dummy Sprite Group doesn't do anything - but allows "members" to access functionality such as viewport
// Doesn't actually store anything related to its members

#include <stddef.h>
#include "Sprite.hpp"
#include "SpriteGroup.hpp"

class DummySpriteGroup : public SpriteGroup {
public:
friend class Sprite;

// Constructor
DummySpriteGroup( int x0, int y0, int x1, int y1 ) : SpriteGroup( x0, y0, x1, y1 ) {}

// Elements
void add( Sprite *s ) { s->sprite_grp = this; }
Sprite *remove( Sprite *s ) { return NULL; }

// Required by iterators
Sprite *begin() { return NULL; }
Sprite *next() { return NULL; }
};

#endif
57 changes: 57 additions & 0 deletions include/Sprite/RotSprite.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef _ROT_SPRITE_HPP

#define _ROT_SPRITE_HPP


#include "Sprite.hpp"

typedef struct
{
int angle;
int vec_x;
int vec_y;
int frame;
} ROT_TABLE;



class RotSprite : public Sprite {
ROT_TABLE *rs_rot_table = NULL;
int rs_cur_rot = 0;
int rs_num_rot = 0;
int rs_circular = 0;


public:

// Constructors, Destructors

RotSprite( int x = 0, int y = 0, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 );
RotSprite( Coords coords, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 );
~RotSprite() {};

// Rotation table handling

void add_rotations( ROT_TABLE *rot_table, int num_rot, int cur_rot = 0, bool circular = 0 );

// Getters

Coords get_dir_vec(); // get direction represented as a pair of coords

// Functions

void next_frame();


// Sprite Events - can overridded from base class to customise behaviour


// RotSprite Events - that can be overriden in derived classes

virtual int rot_c_wise(); // returns rotation or -1 if can't rotate further (if not circular)
virtual int rot_ac_wise(); // reutrns rotation of -1 if can't rotate further (if not circular)


};

#endif
147 changes: 147 additions & 0 deletions include/Sprite/Sprite.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#ifndef _SPRITE_HPP

#define _SPRITE_HPP

#include <stddef.h>
#include "Coords.hpp"
#include "Tile.hpp"
#include "SpriteGroup.hpp"

/* Class to represent a sprite
These make use of VDP sprite engine for drawing, animation (frames) and movement
- automatically iterates through frames
- there are "normal frames" - potentially want to have different normal sequences
- and "die" frames
- automatically move
Adds:
- collision detection
- concept of state & dying
*/

class Sprite {
protected:
int s_vdp_id; // VDP sprite ID (0-255)
int s_x, s_y; // Coordinates (top left)
int s_w, s_h; // normal sprite size
int s_brd; // reduces size for collision detection
int s_dx, s_dy; // Delta x and delta y for sprite movement
bool visible = false; // Flag for visibility
int frames = 0; // number of normal frames
int die_frames = 0; // number of frames for dieing animation
int cur_frame = 0; // Current frame
enum { ALIVE, DYING, DEAD } state = ALIVE;
SpriteGroup *sprite_grp; // SpriteGroup (NULL if none)

// Static data (i.e. for the whole class)

static int sprites_max_num; // Maximum sprites
static int sprites_num; // Number of active sprites
static int sprites_next_free; // Next free sprite
static Sprite **sprites_vdp; // Table of sprite usage

private:
void set_details( int x, int y, int dx, int dy, int w, int h, int brd, int bitmap );
static int get_free_sprite_id(); // Returns id of next free sprite or -1

public:
friend class SpriteList;
friend class SpriteArray;
friend class DummySpriteGroup;

// Constructors, Destructors

Sprite( int x = 0, int y = 0, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 );
Sprite( Coords coords, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 );
virtual ~Sprite();

static int init( int num_sprites ); // Returns no of sprites or zero if failed

// Bitmap handling

void add_bitmap( int bitmap_id, int die = 0 );
void add_bitmaps( int bitmap_id, int num, int die = 0 );

// Getters

// - position getters - take consideration of the boundary

Coords get_centre();
Coords get_top_middle();
Coords get_bottom_middle();
Coords get_left_middle();
Coords get_right_middle();
Coords get_top_left();
Coords get_bottom_right();
bool is_visible() { return visible; };
bool get_viewport( int *x0, int *y0, int *x1, int *y1 );

// Setters

void set_speed( int dx, int dy ) { s_dx = dx; s_dy = dy; };

// Visibility

void show();
void hide();

// Positioning

void move_to( int x, int y );
void move_by( int dx, int dy );

// Frames

void set_frame( int n );
void next_frame();
void prev_frame();

// Steps (movement)

void next_step() { move_by( s_dx, s_dy ); };
void prev_step() { move_by( -s_dx, -s_dy ); };

// Iterations (steps + frames)

void next_iter();
void prev_iter();

// Collisions

int collide( Sprite *s ); // TODO return location - does not trigger events
int hit( Sprite *s ); // Triggers hit & hitting events if collision
int is_hit( Sprite *s ); // Same as above but events reversed
void hit( SpriteGroup *sg );

// Events - these should be customised by overriding in a derived class
// - should return a point to themselves
// - or if they delete themselves NULL

// Movement events are called by move_by() after coordinates has been changed, but not drawn
// - default is reflection
// - function may be overloaded in a derived class - this may delete the Sprite

virtual Sprite *at_left();
virtual Sprite *at_right();
virtual Sprite *at_top();
virtual Sprite *at_bottom();

// Dying & dead actions

virtual Sprite *die(); // Trigger at beginnng of dying sequence
virtual Sprite *dead(); // Trigger at end of dying sequence

// Collision events
// - default is to do nothing

virtual Sprite *hit_by( Sprite *s ); // Object of hitting
virtual Sprite *hitting( Sprite *s ); // Subject of hitting
virtual Sprite *hitting( TileArray *ta );

// Debugging

void dump();
static void debug();
};

#endif
81 changes: 81 additions & 0 deletions include/Sprite/SpriteArray.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef _SPRITEARRAY_HPP

#define _SPRITEARRAY_HPP

#include <stddef.h>
#include "Sprite.hpp"
#include "SpriteGroup.hpp"
#include "Coords.hpp"

class Sprite;

// SpriteArray - A SpriteGroup consisting of an [c][r] array of Sprites
// - can be sparsely populated with Sprites

class SpriteArray : public SpriteGroup {
Sprite **array = NULL; // Pointer to array of pointers to Sprites
int num_cols = 0; // Number of columns in the array
int num_rows = 0; // Number of rows in the array
int array_size = 0;
Sprite **cur_elem = NULL; // Pointer to current element for iteration

int sa_x, sa_y; // Top left corner
int sa_dx, sa_dy; // Speed (increment for next step)
int sa_col_w, sa_row_h; // Column width & row height (spacing between Sprites)
int *col_num_remain; // Array for number of aliens remaining per column
int col_min, col_max; // Section of array with non-zero columns
int *row_num_remain; // Array for number of aliens remaining per row
int row_min, row_max; // Section of array with non-zero rows

public:
friend class Sprite;

// Constuctors

SpriteArray( int cols, int rows, int col_w, int row_h, // Size of array and spacing of Sprites
int x, int y, int dx, int dy, // Top left corner & speed (indepdent of sprite positions)
int x0, int y0, int x1, int y1 ); // Viewport

// Required Iterator for anything derived from SpriteGroup

Sprite *begin();
Sprite *next();

// Elements

Sprite *elem( int col, int row );
void set_elem( int col, int row, Sprite *s );
Sprite *remove( Sprite *s );

// Getters

Coords get_pos() { return Coords( sa_x, sa_y); }
Coords get_speed() { return Coords( sa_dx, sa_dy ); }

// Setters

void set_pos( int x, int y ) { sa_x = x; sa_y = y; }
void set_speed( int x, int y ) { sa_dx = x; sa_dy = y; }

// Movement

void next_iter();
void next_step();

private:
void update_min_max_col( int c );
void update_min_max_row( int r );

public:

// Events - maybe overridden in derived classes

virtual void at_left(); // Default is just to reflect of the edge
virtual void at_right(); // Default is just to reflect of the edge

// Debugging

void dump();
};

#endif
Loading

0 comments on commit 0733de5

Please sign in to comment.