diff --git a/README.md b/README.md index d37dd4a..7bb6a4e 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/include/Sprite/Coords.hpp b/include/Sprite/Coords.hpp new file mode 100644 index 0000000..13f7e69 --- /dev/null +++ b/include/Sprite/Coords.hpp @@ -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 \ No newline at end of file diff --git a/include/Sprite/DummySpriteGroup.hpp b/include/Sprite/DummySpriteGroup.hpp new file mode 100644 index 0000000..ba9050a --- /dev/null +++ b/include/Sprite/DummySpriteGroup.hpp @@ -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 +#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 \ No newline at end of file diff --git a/include/Sprite/RotSprite.hpp b/include/Sprite/RotSprite.hpp new file mode 100644 index 0000000..792dba2 --- /dev/null +++ b/include/Sprite/RotSprite.hpp @@ -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 \ No newline at end of file diff --git a/include/Sprite/Sprite.hpp b/include/Sprite/Sprite.hpp new file mode 100644 index 0000000..280ec45 --- /dev/null +++ b/include/Sprite/Sprite.hpp @@ -0,0 +1,147 @@ +#ifndef _SPRITE_HPP + +#define _SPRITE_HPP + +#include +#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 \ No newline at end of file diff --git a/include/Sprite/SpriteArray.hpp b/include/Sprite/SpriteArray.hpp new file mode 100644 index 0000000..c8968c7 --- /dev/null +++ b/include/Sprite/SpriteArray.hpp @@ -0,0 +1,81 @@ +#ifndef _SPRITEARRAY_HPP + +#define _SPRITEARRAY_HPP + +#include +#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 \ No newline at end of file diff --git a/include/Sprite/SpriteGroup.hpp b/include/Sprite/SpriteGroup.hpp new file mode 100644 index 0000000..5ffe2b5 --- /dev/null +++ b/include/Sprite/SpriteGroup.hpp @@ -0,0 +1,63 @@ +#ifndef _SPRITEGROUP_HPP + +#define _SPRITEGROUP_HPP + +#include +#include "Sprite.hpp" +#include "Coords.hpp" +#include "Tile.hpp" + +class Sprite; +class TileArray; + +// SpriteGroup - A collection of sprites to which common actions can be applied or collisions detected + +class SpriteGroup { + int num_elements = 0; // Number of elements + int sg_x0, sg_y0; // View port - top left + int sg_x1, sg_y1; // View port - bottom right +public: + friend class Sprite; + friend class SpriteList; + friend class SpriteArray; + + // Constuctors + + SpriteGroup( int x0, int y0, int x1, int y1 ); // New SpriteGroup with view port + + // Elements + + int num_elem() { return num_elements; } + virtual Sprite *remove( Sprite *s ) = 0; // Remove Sprite from SpriteGroup - but don't delete it + + // Required for iterators + + virtual Sprite *begin() = 0; // First element + virtual Sprite *next() = 0; // Next element + + // Actions - performned on all SpriteGroup members + + void move_by( int dx, int dy ); + void next_frame(); + void prev_frame(); + void next_step(); + void prev_step(); + void next_iter(); + void prev_iter(); + void hide(); + void show(); + + // Collisions + + void is_hit( Sprite *s ); // Trigger events on members of Sprite group hit by Sprite + void hit( Sprite *s ); + void hit( SpriteGroup *sg ); + void hit( TileArray *ta ); + + // Debugging + + void dump(); +}; + + +#endif \ No newline at end of file diff --git a/include/Sprite/SpriteList.hpp b/include/Sprite/SpriteList.hpp new file mode 100644 index 0000000..ff39f71 --- /dev/null +++ b/include/Sprite/SpriteList.hpp @@ -0,0 +1,43 @@ +#ifndef _SPRITELIST_HPP + +#define _SPRITELIST_HPP + +#include +#include "Sprite.hpp" +#include "SpriteGroup.hpp" + +class Sprite; + +// SpriteList - A SpriteGroup consisting of a linked list of Sprites + +class SpriteListElem { + Sprite *sprite; + SpriteListElem *next = NULL; + SpriteListElem( Sprite *s ) { sprite = s; }; +public: + friend class SpriteList; +}; + +class SpriteList : public SpriteGroup { + SpriteListElem *first = NULL; // Linked list pointer to first element + SpriteListElem *last = NULL; // Pointer to last element - so easy to add new elements + SpriteListElem *current = NULL; // Current element in iteration +public: + friend class Sprite; + + // Constuctors + + SpriteList( int x0, int y0, int x1, int y1 ); + + // Required Iterator for anything derived from SpriteGroup + + Sprite *begin(); + Sprite *next(); + + // Elements + + void add( Sprite *sprite ); + Sprite *remove( Sprite *s ); +}; + +#endif \ No newline at end of file diff --git a/include/Sprite/Tile.hpp b/include/Sprite/Tile.hpp new file mode 100644 index 0000000..0dd4266 --- /dev/null +++ b/include/Sprite/Tile.hpp @@ -0,0 +1,80 @@ +#ifndef _TILE_HPP + +#define _TILE_HPP + +#include +#include "Coords.hpp" +#include "Sprite.hpp" +#include "SpriteGroup.hpp" + +class Sprite; +class TileArray; + +/* Class to represent a graphics tile + + Use bitmaps to draw the image + Compared to simple bitmaps adds: + - manages the display of the bitmaps on the screen + - collision detection + - update of bitmap +*/ + +class Tile { + int t_x, t_y; // top left of tile + int t_w, t_h; // size of tile + int t_bitmap; // bitmap to use (-1 = blank) + +public: + friend class TileArray; + + // Constructors + Tile() {}; + Tile( int xcoord, int ycoord, int width = 0, int height = 0, int bitmap = 0 ); + + // Functions + + void set_bitmap( int bitmap ); + void draw(); + void blank( int blank_bitmap ); // Sets tile to blank (can reset it by set_bitmap()) + + // Events + + virtual void hit_by( int blank_bitmap, Sprite *s ); + +}; + +// Array of graphics tiles - adjacent to each other with same sizes + +class TileArray { + int ta_rows, ta_cols; // Number of tiles (rows, cols) + int ta_x, ta_y; // Position of top left of TileArray + int ta_w, ta_h; // Size of each tile (rows, cols) + int ta_blank_bitmap; + Tile *array; // Elements of array + +public: + // Constructors + + TileArray( int c, int r, int xcoord = 0, int ycoord = 0, int width = 0, int height = 0, + int bitmap = 0, int blank_bitmap = 0 ); + + // Functions + + Tile *elem( int c, int r ); + void set_bitmap( int bitmap ); + void draw(); + void clear( int c0, int r0, int c1, int r1 ); // Clear a section before drawing + + // Collision / hit functions + // - collide does generate events + // - hit functions generate events + + Tile *collide( int xcoord, int ycoord ); // Returns tile hit at (xcoord, ycoord) or NULL + Tile *collide( Coords coords ) { return collide( coords.x, coords.y ); } + + void is_hit( Sprite *s ); // Call hit_by() event for all tiles hit + void is_hit( SpriteGroup *sg ); + +}; + +#endif \ No newline at end of file diff --git a/include/vdp_key.h b/include/agon/vdp_key.h similarity index 100% rename from include/vdp_key.h rename to include/agon/vdp_key.h diff --git a/include/vdp_vdu.h b/include/agon/vdp_vdu.h similarity index 100% rename from include/vdp_vdu.h rename to include/agon/vdp_vdu.h diff --git a/sprite-demos/invaders/README.md b/sprite-demos/invaders/README.md new file mode 100644 index 0000000..179a7c2 --- /dev/null +++ b/sprite-demos/invaders/README.md @@ -0,0 +1,11 @@ +# Space Invaders demo of Sprite C++ Library + +Compile in the normal way + +Copy the files: + +- invaders.bin + +- bitmaps/*.rgba + +To the installation directory on Agon diff --git a/sprite-demos/invaders/bitmaps/gal-red0.rgba b/sprite-demos/invaders/bitmaps/gal-red0.rgba new file mode 100644 index 0000000..cee2eb7 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/gal-red0.rgba differ diff --git a/sprite-demos/invaders/bitmaps/gal-red1.rgba b/sprite-demos/invaders/bitmaps/gal-red1.rgba new file mode 100644 index 0000000..bf92b7d Binary files /dev/null and b/sprite-demos/invaders/bitmaps/gal-red1.rgba differ diff --git a/sprite-demos/invaders/bitmaps/gal-red2.rgba b/sprite-demos/invaders/bitmaps/gal-red2.rgba new file mode 100644 index 0000000..07c3f2c Binary files /dev/null and b/sprite-demos/invaders/bitmaps/gal-red2.rgba differ diff --git a/sprite-demos/invaders/bitmaps/gal-red3.rgba b/sprite-demos/invaders/bitmaps/gal-red3.rgba new file mode 100644 index 0000000..09d2b58 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/gal-red3.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship00.rgba b/sprite-demos/invaders/bitmaps/ship00.rgba new file mode 100644 index 0000000..7a884d0 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship00.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship01.rgba b/sprite-demos/invaders/bitmaps/ship01.rgba new file mode 100644 index 0000000..d7498fa Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship01.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship02.rgba b/sprite-demos/invaders/bitmaps/ship02.rgba new file mode 100644 index 0000000..51b344c Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship02.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship03.rgba b/sprite-demos/invaders/bitmaps/ship03.rgba new file mode 100644 index 0000000..06b57c2 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship03.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship04.rgba b/sprite-demos/invaders/bitmaps/ship04.rgba new file mode 100644 index 0000000..eed10f0 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship04.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship05.rgba b/sprite-demos/invaders/bitmaps/ship05.rgba new file mode 100644 index 0000000..c3d62c0 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship05.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship06.rgba b/sprite-demos/invaders/bitmaps/ship06.rgba new file mode 100644 index 0000000..3f589f8 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship06.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship07.rgba b/sprite-demos/invaders/bitmaps/ship07.rgba new file mode 100644 index 0000000..a77f3d3 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship07.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship08.rgba b/sprite-demos/invaders/bitmaps/ship08.rgba new file mode 100644 index 0000000..c20b42f Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship08.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship09.rgba b/sprite-demos/invaders/bitmaps/ship09.rgba new file mode 100644 index 0000000..db0d0aa Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship09.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship10.rgba b/sprite-demos/invaders/bitmaps/ship10.rgba new file mode 100644 index 0000000..6d30ed3 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship10.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship11.rgba b/sprite-demos/invaders/bitmaps/ship11.rgba new file mode 100644 index 0000000..3efc1d8 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship11.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship12.rgba b/sprite-demos/invaders/bitmaps/ship12.rgba new file mode 100644 index 0000000..472ae16 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship12.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship13.rgba b/sprite-demos/invaders/bitmaps/ship13.rgba new file mode 100644 index 0000000..682b711 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship13.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship14.rgba b/sprite-demos/invaders/bitmaps/ship14.rgba new file mode 100644 index 0000000..a1344f7 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship14.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship15.rgba b/sprite-demos/invaders/bitmaps/ship15.rgba new file mode 100644 index 0000000..934b373 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship15.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship16.rgba b/sprite-demos/invaders/bitmaps/ship16.rgba new file mode 100644 index 0000000..9d41d5b Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship16.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship17.rgba b/sprite-demos/invaders/bitmaps/ship17.rgba new file mode 100644 index 0000000..11cd353 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship17.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship18.rgba b/sprite-demos/invaders/bitmaps/ship18.rgba new file mode 100644 index 0000000..4932fd3 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship18.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship19.rgba b/sprite-demos/invaders/bitmaps/ship19.rgba new file mode 100644 index 0000000..a3f9c5d Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship19.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship20.rgba b/sprite-demos/invaders/bitmaps/ship20.rgba new file mode 100644 index 0000000..299d905 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship20.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship21.rgba b/sprite-demos/invaders/bitmaps/ship21.rgba new file mode 100644 index 0000000..4c1923b Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship21.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship22.rgba b/sprite-demos/invaders/bitmaps/ship22.rgba new file mode 100644 index 0000000..1a8e274 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship22.rgba differ diff --git a/sprite-demos/invaders/bitmaps/ship23.rgba b/sprite-demos/invaders/bitmaps/ship23.rgba new file mode 100644 index 0000000..4c79b15 Binary files /dev/null and b/sprite-demos/invaders/bitmaps/ship23.rgba differ diff --git a/sprite-demos/invaders/img-src/Galaxian.png b/sprite-demos/invaders/img-src/Galaxian.png new file mode 100644 index 0000000..10b8d3c Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian1.png b/sprite-demos/invaders/img-src/Galaxian1.png new file mode 100644 index 0000000..591f909 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian1.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian10.png b/sprite-demos/invaders/img-src/Galaxian10.png new file mode 100644 index 0000000..45094a5 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian10.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian11.png b/sprite-demos/invaders/img-src/Galaxian11.png new file mode 100644 index 0000000..a2a6a15 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian11.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian12.png b/sprite-demos/invaders/img-src/Galaxian12.png new file mode 100644 index 0000000..acf0c0a Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian12.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian13.png b/sprite-demos/invaders/img-src/Galaxian13.png new file mode 100644 index 0000000..2f9f5b6 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian13.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian14.png b/sprite-demos/invaders/img-src/Galaxian14.png new file mode 100644 index 0000000..b60482f Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian14.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian15.png b/sprite-demos/invaders/img-src/Galaxian15.png new file mode 100644 index 0000000..90f1e87 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian15.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian16.png b/sprite-demos/invaders/img-src/Galaxian16.png new file mode 100644 index 0000000..d6e4b60 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian16.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian17.png b/sprite-demos/invaders/img-src/Galaxian17.png new file mode 100644 index 0000000..d0a62e8 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian17.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian18.png b/sprite-demos/invaders/img-src/Galaxian18.png new file mode 100644 index 0000000..94392d8 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian18.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian19.png b/sprite-demos/invaders/img-src/Galaxian19.png new file mode 100644 index 0000000..f737d87 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian19.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian2.png b/sprite-demos/invaders/img-src/Galaxian2.png new file mode 100644 index 0000000..c4c4222 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian2.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian20.png b/sprite-demos/invaders/img-src/Galaxian20.png new file mode 100644 index 0000000..2f8ca45 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian20.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian21.png b/sprite-demos/invaders/img-src/Galaxian21.png new file mode 100644 index 0000000..e9b8da3 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian21.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian22.png b/sprite-demos/invaders/img-src/Galaxian22.png new file mode 100644 index 0000000..6ef2fc7 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian22.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian23.png b/sprite-demos/invaders/img-src/Galaxian23.png new file mode 100644 index 0000000..9c91eed Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian23.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian24.png b/sprite-demos/invaders/img-src/Galaxian24.png new file mode 100644 index 0000000..6cf5d15 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian24.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian25.png b/sprite-demos/invaders/img-src/Galaxian25.png new file mode 100644 index 0000000..8698ff5 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian25.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian26.png b/sprite-demos/invaders/img-src/Galaxian26.png new file mode 100644 index 0000000..8697f3e Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian26.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian27.png b/sprite-demos/invaders/img-src/Galaxian27.png new file mode 100644 index 0000000..46ce89c Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian27.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian28.png b/sprite-demos/invaders/img-src/Galaxian28.png new file mode 100644 index 0000000..12be346 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian28.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian29.png b/sprite-demos/invaders/img-src/Galaxian29.png new file mode 100644 index 0000000..3ea1ed8 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian29.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian3.png b/sprite-demos/invaders/img-src/Galaxian3.png new file mode 100644 index 0000000..61ad351 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian3.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian30.png b/sprite-demos/invaders/img-src/Galaxian30.png new file mode 100644 index 0000000..12d8dcd Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian30.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian31.png b/sprite-demos/invaders/img-src/Galaxian31.png new file mode 100644 index 0000000..9a1cde5 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian31.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian32.png b/sprite-demos/invaders/img-src/Galaxian32.png new file mode 100644 index 0000000..2036656 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian32.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian33.png b/sprite-demos/invaders/img-src/Galaxian33.png new file mode 100644 index 0000000..17f0126 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian33.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian34.png b/sprite-demos/invaders/img-src/Galaxian34.png new file mode 100644 index 0000000..f22bc2e Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian34.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian35.png b/sprite-demos/invaders/img-src/Galaxian35.png new file mode 100644 index 0000000..eb2e334 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian35.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian36.png b/sprite-demos/invaders/img-src/Galaxian36.png new file mode 100644 index 0000000..6ed4f7b Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian36.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian37.png b/sprite-demos/invaders/img-src/Galaxian37.png new file mode 100644 index 0000000..8735964 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian37.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian38.png b/sprite-demos/invaders/img-src/Galaxian38.png new file mode 100644 index 0000000..1aab58c Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian38.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian39.png b/sprite-demos/invaders/img-src/Galaxian39.png new file mode 100644 index 0000000..a4ef35a Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian39.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian4.png b/sprite-demos/invaders/img-src/Galaxian4.png new file mode 100644 index 0000000..99f573e Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian4.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian40.png b/sprite-demos/invaders/img-src/Galaxian40.png new file mode 100644 index 0000000..f4b9cde Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian40.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian41.png b/sprite-demos/invaders/img-src/Galaxian41.png new file mode 100644 index 0000000..cd7ac61 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian41.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian42.png b/sprite-demos/invaders/img-src/Galaxian42.png new file mode 100644 index 0000000..a03375c Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian42.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian43.png b/sprite-demos/invaders/img-src/Galaxian43.png new file mode 100644 index 0000000..b4ec530 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian43.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian49.png b/sprite-demos/invaders/img-src/Galaxian49.png new file mode 100644 index 0000000..790365d Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian49.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian5.png b/sprite-demos/invaders/img-src/Galaxian5.png new file mode 100644 index 0000000..1810b5d Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian5.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian50.png b/sprite-demos/invaders/img-src/Galaxian50.png new file mode 100644 index 0000000..704494c Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian50.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian6.png b/sprite-demos/invaders/img-src/Galaxian6.png new file mode 100644 index 0000000..b438b48 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian6.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian7.png b/sprite-demos/invaders/img-src/Galaxian7.png new file mode 100644 index 0000000..7a6c66d Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian7.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian8.png b/sprite-demos/invaders/img-src/Galaxian8.png new file mode 100644 index 0000000..741f858 Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian8.png differ diff --git a/sprite-demos/invaders/img-src/Galaxian9.png b/sprite-demos/invaders/img-src/Galaxian9.png new file mode 100644 index 0000000..767054f Binary files /dev/null and b/sprite-demos/invaders/img-src/Galaxian9.png differ diff --git a/sprite-demos/invaders/img-src/bitmaps/gal-red0.rgba b/sprite-demos/invaders/img-src/bitmaps/gal-red0.rgba new file mode 100644 index 0000000..cee2eb7 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/gal-red0.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/gal-red1.rgba b/sprite-demos/invaders/img-src/bitmaps/gal-red1.rgba new file mode 100644 index 0000000..bf92b7d Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/gal-red1.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/gal-red2.rgba b/sprite-demos/invaders/img-src/bitmaps/gal-red2.rgba new file mode 100644 index 0000000..07c3f2c Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/gal-red2.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/gal-red3.rgba b/sprite-demos/invaders/img-src/bitmaps/gal-red3.rgba new file mode 100644 index 0000000..09d2b58 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/gal-red3.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship00.rgba b/sprite-demos/invaders/img-src/bitmaps/ship00.rgba new file mode 100644 index 0000000..7a884d0 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship00.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship01.rgba b/sprite-demos/invaders/img-src/bitmaps/ship01.rgba new file mode 100644 index 0000000..d7498fa Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship01.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship02.rgba b/sprite-demos/invaders/img-src/bitmaps/ship02.rgba new file mode 100644 index 0000000..51b344c Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship02.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship03.rgba b/sprite-demos/invaders/img-src/bitmaps/ship03.rgba new file mode 100644 index 0000000..06b57c2 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship03.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship04.rgba b/sprite-demos/invaders/img-src/bitmaps/ship04.rgba new file mode 100644 index 0000000..eed10f0 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship04.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship05.rgba b/sprite-demos/invaders/img-src/bitmaps/ship05.rgba new file mode 100644 index 0000000..c3d62c0 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship05.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship06.rgba b/sprite-demos/invaders/img-src/bitmaps/ship06.rgba new file mode 100644 index 0000000..3f589f8 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship06.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship07.rgba b/sprite-demos/invaders/img-src/bitmaps/ship07.rgba new file mode 100644 index 0000000..a77f3d3 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship07.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship08.rgba b/sprite-demos/invaders/img-src/bitmaps/ship08.rgba new file mode 100644 index 0000000..c20b42f Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship08.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship09.rgba b/sprite-demos/invaders/img-src/bitmaps/ship09.rgba new file mode 100644 index 0000000..db0d0aa Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship09.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship10.rgba b/sprite-demos/invaders/img-src/bitmaps/ship10.rgba new file mode 100644 index 0000000..6d30ed3 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship10.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship11.rgba b/sprite-demos/invaders/img-src/bitmaps/ship11.rgba new file mode 100644 index 0000000..3efc1d8 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship11.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship12.rgba b/sprite-demos/invaders/img-src/bitmaps/ship12.rgba new file mode 100644 index 0000000..472ae16 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship12.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship13.rgba b/sprite-demos/invaders/img-src/bitmaps/ship13.rgba new file mode 100644 index 0000000..682b711 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship13.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship14.rgba b/sprite-demos/invaders/img-src/bitmaps/ship14.rgba new file mode 100644 index 0000000..a1344f7 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship14.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship15.rgba b/sprite-demos/invaders/img-src/bitmaps/ship15.rgba new file mode 100644 index 0000000..934b373 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship15.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship16.rgba b/sprite-demos/invaders/img-src/bitmaps/ship16.rgba new file mode 100644 index 0000000..9d41d5b Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship16.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship17.rgba b/sprite-demos/invaders/img-src/bitmaps/ship17.rgba new file mode 100644 index 0000000..11cd353 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship17.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship18.rgba b/sprite-demos/invaders/img-src/bitmaps/ship18.rgba new file mode 100644 index 0000000..4932fd3 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship18.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship19.rgba b/sprite-demos/invaders/img-src/bitmaps/ship19.rgba new file mode 100644 index 0000000..a3f9c5d Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship19.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship20.rgba b/sprite-demos/invaders/img-src/bitmaps/ship20.rgba new file mode 100644 index 0000000..299d905 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship20.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship21.rgba b/sprite-demos/invaders/img-src/bitmaps/ship21.rgba new file mode 100644 index 0000000..4c1923b Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship21.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship22.rgba b/sprite-demos/invaders/img-src/bitmaps/ship22.rgba new file mode 100644 index 0000000..1a8e274 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship22.rgba differ diff --git a/sprite-demos/invaders/img-src/bitmaps/ship23.rgba b/sprite-demos/invaders/img-src/bitmaps/ship23.rgba new file mode 100644 index 0000000..4c79b15 Binary files /dev/null and b/sprite-demos/invaders/img-src/bitmaps/ship23.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-explode/Galaxian52.png b/sprite-demos/invaders/img-src/gal-explode/Galaxian52.png new file mode 100644 index 0000000..9d870e3 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/Galaxian52.png differ diff --git a/sprite-demos/invaders/img-src/gal-explode/Galaxian53.png b/sprite-demos/invaders/img-src/gal-explode/Galaxian53.png new file mode 100644 index 0000000..fe3df14 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/Galaxian53.png differ diff --git a/sprite-demos/invaders/img-src/gal-explode/Galaxian54.png b/sprite-demos/invaders/img-src/gal-explode/Galaxian54.png new file mode 100644 index 0000000..7609b6a Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/Galaxian54.png differ diff --git a/sprite-demos/invaders/img-src/gal-explode/Galaxian55.png b/sprite-demos/invaders/img-src/gal-explode/Galaxian55.png new file mode 100644 index 0000000..97f1a53 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/Galaxian55.png differ diff --git a/sprite-demos/invaders/img-src/gal-explode/gal-explode00.rgba b/sprite-demos/invaders/img-src/gal-explode/gal-explode00.rgba new file mode 100644 index 0000000..decb229 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/gal-explode00.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-explode/gal-explode01.rgba b/sprite-demos/invaders/img-src/gal-explode/gal-explode01.rgba new file mode 100644 index 0000000..70dd974 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/gal-explode01.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-explode/gal-explode02.rgba b/sprite-demos/invaders/img-src/gal-explode/gal-explode02.rgba new file mode 100644 index 0000000..a2b41da Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/gal-explode02.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-explode/gal-explode03.rgba b/sprite-demos/invaders/img-src/gal-explode/gal-explode03.rgba new file mode 100644 index 0000000..fcb6cb4 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-explode/gal-explode03.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-red0.rgba b/sprite-demos/invaders/img-src/gal-red0.rgba new file mode 100644 index 0000000..cee2eb7 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-red0.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-red1.rgba b/sprite-demos/invaders/img-src/gal-red1.rgba new file mode 100644 index 0000000..bf92b7d Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-red1.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-red2.rgba b/sprite-demos/invaders/img-src/gal-red2.rgba new file mode 100644 index 0000000..07c3f2c Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-red2.rgba differ diff --git a/sprite-demos/invaders/img-src/gal-red3.rgba b/sprite-demos/invaders/img-src/gal-red3.rgba new file mode 100644 index 0000000..09d2b58 Binary files /dev/null and b/sprite-demos/invaders/img-src/gal-red3.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian37.png b/sprite-demos/invaders/img-src/ship/Galaxian37.png new file mode 100644 index 0000000..b4ec530 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian37.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian38.png b/sprite-demos/invaders/img-src/ship/Galaxian38.png new file mode 100644 index 0000000..b7e2cac Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian38.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian39.png b/sprite-demos/invaders/img-src/ship/Galaxian39.png new file mode 100644 index 0000000..0cfefe8 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian39.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian40.png b/sprite-demos/invaders/img-src/ship/Galaxian40.png new file mode 100644 index 0000000..b9550f7 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian40.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian41.png b/sprite-demos/invaders/img-src/ship/Galaxian41.png new file mode 100644 index 0000000..7e0efb0 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian41.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian42.png b/sprite-demos/invaders/img-src/ship/Galaxian42.png new file mode 100644 index 0000000..9a775f3 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian42.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian43.png b/sprite-demos/invaders/img-src/ship/Galaxian43.png new file mode 100644 index 0000000..a9042d5 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian43.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian44.png b/sprite-demos/invaders/img-src/ship/Galaxian44.png new file mode 100644 index 0000000..0f50f1f Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian44.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian45.png b/sprite-demos/invaders/img-src/ship/Galaxian45.png new file mode 100644 index 0000000..817a5be Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian45.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian46.png b/sprite-demos/invaders/img-src/ship/Galaxian46.png new file mode 100644 index 0000000..f356630 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian46.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian47.png b/sprite-demos/invaders/img-src/ship/Galaxian47.png new file mode 100644 index 0000000..f94a26a Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian47.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian48.png b/sprite-demos/invaders/img-src/ship/Galaxian48.png new file mode 100644 index 0000000..f869d28 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian48.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian49.png b/sprite-demos/invaders/img-src/ship/Galaxian49.png new file mode 100644 index 0000000..4dc340d Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian49.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian50.png b/sprite-demos/invaders/img-src/ship/Galaxian50.png new file mode 100644 index 0000000..2a93dbb Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian50.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian51.png b/sprite-demos/invaders/img-src/ship/Galaxian51.png new file mode 100644 index 0000000..8b5901d Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian51.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian52.png b/sprite-demos/invaders/img-src/ship/Galaxian52.png new file mode 100644 index 0000000..bd7bad7 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian52.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian53.png b/sprite-demos/invaders/img-src/ship/Galaxian53.png new file mode 100644 index 0000000..f2f1244 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian53.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian54.png b/sprite-demos/invaders/img-src/ship/Galaxian54.png new file mode 100644 index 0000000..fa28388 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian54.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian55.png b/sprite-demos/invaders/img-src/ship/Galaxian55.png new file mode 100644 index 0000000..8735964 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian55.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian56.png b/sprite-demos/invaders/img-src/ship/Galaxian56.png new file mode 100644 index 0000000..1aab58c Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian56.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian57.png b/sprite-demos/invaders/img-src/ship/Galaxian57.png new file mode 100644 index 0000000..a4ef35a Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian57.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian58.png b/sprite-demos/invaders/img-src/ship/Galaxian58.png new file mode 100644 index 0000000..f4b9cde Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian58.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian59.png b/sprite-demos/invaders/img-src/ship/Galaxian59.png new file mode 100644 index 0000000..cd7ac61 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian59.png differ diff --git a/sprite-demos/invaders/img-src/ship/Galaxian60.png b/sprite-demos/invaders/img-src/ship/Galaxian60.png new file mode 100644 index 0000000..a03375c Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/Galaxian60.png differ diff --git a/sprite-demos/invaders/img-src/ship/ship00.rgba b/sprite-demos/invaders/img-src/ship/ship00.rgba new file mode 100644 index 0000000..7a884d0 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship00.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship01.rgba b/sprite-demos/invaders/img-src/ship/ship01.rgba new file mode 100644 index 0000000..d7498fa Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship01.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship02.rgba b/sprite-demos/invaders/img-src/ship/ship02.rgba new file mode 100644 index 0000000..51b344c Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship02.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship03.rgba b/sprite-demos/invaders/img-src/ship/ship03.rgba new file mode 100644 index 0000000..06b57c2 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship03.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship04.rgba b/sprite-demos/invaders/img-src/ship/ship04.rgba new file mode 100644 index 0000000..eed10f0 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship04.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship05.rgba b/sprite-demos/invaders/img-src/ship/ship05.rgba new file mode 100644 index 0000000..c3d62c0 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship05.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship06.rgba b/sprite-demos/invaders/img-src/ship/ship06.rgba new file mode 100644 index 0000000..3f589f8 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship06.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship07.rgba b/sprite-demos/invaders/img-src/ship/ship07.rgba new file mode 100644 index 0000000..a77f3d3 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship07.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship08.rgba b/sprite-demos/invaders/img-src/ship/ship08.rgba new file mode 100644 index 0000000..c20b42f Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship08.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship09.rgba b/sprite-demos/invaders/img-src/ship/ship09.rgba new file mode 100644 index 0000000..db0d0aa Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship09.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship10.rgba b/sprite-demos/invaders/img-src/ship/ship10.rgba new file mode 100644 index 0000000..6d30ed3 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship10.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship11.rgba b/sprite-demos/invaders/img-src/ship/ship11.rgba new file mode 100644 index 0000000..3efc1d8 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship11.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship12.rgba b/sprite-demos/invaders/img-src/ship/ship12.rgba new file mode 100644 index 0000000..472ae16 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship12.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship13.rgba b/sprite-demos/invaders/img-src/ship/ship13.rgba new file mode 100644 index 0000000..682b711 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship13.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship14.rgba b/sprite-demos/invaders/img-src/ship/ship14.rgba new file mode 100644 index 0000000..a1344f7 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship14.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship15.rgba b/sprite-demos/invaders/img-src/ship/ship15.rgba new file mode 100644 index 0000000..934b373 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship15.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship16.rgba b/sprite-demos/invaders/img-src/ship/ship16.rgba new file mode 100644 index 0000000..9d41d5b Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship16.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship17.rgba b/sprite-demos/invaders/img-src/ship/ship17.rgba new file mode 100644 index 0000000..11cd353 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship17.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship18.rgba b/sprite-demos/invaders/img-src/ship/ship18.rgba new file mode 100644 index 0000000..4932fd3 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship18.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship19.rgba b/sprite-demos/invaders/img-src/ship/ship19.rgba new file mode 100644 index 0000000..a3f9c5d Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship19.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship20.rgba b/sprite-demos/invaders/img-src/ship/ship20.rgba new file mode 100644 index 0000000..299d905 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship20.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship21.rgba b/sprite-demos/invaders/img-src/ship/ship21.rgba new file mode 100644 index 0000000..4c1923b Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship21.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship22.rgba b/sprite-demos/invaders/img-src/ship/ship22.rgba new file mode 100644 index 0000000..1a8e274 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship22.rgba differ diff --git a/sprite-demos/invaders/img-src/ship/ship23.rgba b/sprite-demos/invaders/img-src/ship/ship23.rgba new file mode 100644 index 0000000..4c79b15 Binary files /dev/null and b/sprite-demos/invaders/img-src/ship/ship23.rgba differ diff --git a/sprite-demos/invaders/makefile b/sprite-demos/invaders/makefile new file mode 100644 index 0000000..631b7dc --- /dev/null +++ b/sprite-demos/invaders/makefile @@ -0,0 +1,20 @@ +# ---------------------------- +# Makefile Options +# ---------------------------- + +NAME = invader +DESCRIPTION = "Ag C Toolchain Demo" +COMPRESSED = NO +LDHAS_ARG_PROCESSING = 0 + +BSSHEAP_LOW = 060000 +BSSHEAP_HIGH = 09FFFF + +CFLAGS = -Wall -Wextra -Oz +CXXFLAGS = -Wall -Wextra -Oz + +#LOCAL_LIBS_SCRIPT = local_libs_script + +# ---------------------------- + +include $(shell cedev-config --makefile) diff --git a/sprite-demos/invaders/src/Alien.cpp b/sprite-demos/invaders/src/Alien.cpp new file mode 100644 index 0000000..5423a21 --- /dev/null +++ b/sprite-demos/invaders/src/Alien.cpp @@ -0,0 +1,88 @@ +#include "Alien.hpp" +#include "config.hpp" +#include + +SpriteArray *aliens; + +void alien_init() +{ + // Red galaxians - load bitmaps, create SpriteList and Sprites + + vdp_load_sprite_bitmaps( ALIEN_FNAME_PREFIX, ALIEN_FNAME_FORMAT, + ALIEN_WIDTH, ALIEN_HEIGHT, + ALIEN_BITMAP_ID_START, ALIEN_BITMAP_ID_NUM ); + vdp_load_sprite_bitmaps( EXPLODE_FNAME_PREFIX, EXPLODE_FNAME_FORMAT, + EXPLODE_WIDTH, EXPLODE_HEIGHT, + EXPLODE_BITMAP_ID_START, EXPLODE_BITMAP_ID_NUM ); + + aliens = new AlienArray( ALIEN_COLS, ALIEN_ROWS, ALIEN_X_SPACING, ALIEN_Y_SPACING, + ALIEN_X, ALIEN_Y, ALIEN_SPEED, 0, + 0, 0, SC_WIDTH + ALIEN_X_SPACING - ALIEN_WIDTH, SC_HEIGHT ); + // Note - Adjust the size of the viewport to allow for the space at right or array + + int x = ALIEN_X, y = ALIEN_Y; + + for ( int c = 0; c < ALIEN_COLS; c++ ) { + for ( int r = 0; r < ALIEN_ROWS; r++ ) { + Alien *a = new Alien( x, y, ALIEN_SPEED, 0, ALIEN_WIDTH, ALIEN_HEIGHT, ALIEN_BORDER ); + a->add_bitmaps(ALIEN_BITMAP_ID_START, ALIEN_BITMAP_ID_NUM, 0); // add regular bitmaps + a->add_bitmaps(EXPLODE_BITMAP_ID_START, EXPLODE_BITMAP_ID_NUM, 1); // add die frame bitmaps + a->show(); + aliens->set_elem(c, r, a); + y += ALIEN_Y_SPACING; + } + x += ALIEN_X_SPACING; + y = ALIEN_Y; + } +} + +// Alien member functions ///////////// + +// Events + +Alien *Alien::hit_by( Sprite *s ) +{ + die(); + return this; +} + +Alien *Alien::dead() +{ + delete this; + score += 1; + return NULL; +} + +Alien *Alien::at_left() +{ + s_dx = -s_dx; + move_to( s_x + s_dx, s_y + ALIEN_STEP ); + return this; +} + +Alien *Alien::at_right() +{ + s_dx = -s_dx; + move_to( s_x + s_dx, s_y + ALIEN_STEP ); + return this; +} + +// AlienArray member functions /////////////////// + +void AlienArray::at_left() +{ + Coords pos = get_pos(); + Coords speed = get_speed(); + set_speed( -speed.x, speed.y ); + for ( Sprite *s = begin(); s; s = next() ) move_by( 0, ALIEN_STEP ); + set_pos( pos.x, pos.y + ALIEN_STEP); +} + +void AlienArray::at_right() +{ + Coords pos = get_pos(); + Coords speed = get_speed(); + set_speed( -speed.x, speed.y ); + for ( Sprite *s = begin(); s; s = next() ) move_by( 0, ALIEN_STEP ); + set_pos( pos.x, pos.y + ALIEN_STEP); +} diff --git a/sprite-demos/invaders/src/Alien.hpp b/sprite-demos/invaders/src/Alien.hpp new file mode 100644 index 0000000..68e58bc --- /dev/null +++ b/sprite-demos/invaders/src/Alien.hpp @@ -0,0 +1,45 @@ +#ifndef _ALIEN_HPP + +#define _ALIEN_HPP + +#include +#include + +void alien_init(); + +class Alien : public Sprite { +public: + // Constructors & Destructors + + Alien( 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( x, y, dx, dy, w, h, brd, bitmap ) {} + Alien( Coords coords, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 ) + : Sprite( coords, dx, dy, w, h, brd, bitmap ) {} + ~Alien() {}; + + // Events + + Alien *hit_by( Sprite *s ); + Alien *dead(); + Alien *at_left(); + Alien *at_right(); + +}; + +class AlienArray : public SpriteArray { +public: + // Constructor + + AlienArray( 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 + : SpriteArray( cols, rows, col_w, row_h, x, y, dx, dy, x0, y0, x1, y1 ) {}; + + // Events + + void at_left(); + void at_right(); + +}; + +#endif diff --git a/sprite-demos/invaders/src/Bomb.cpp b/sprite-demos/invaders/src/Bomb.cpp new file mode 100644 index 0000000..ebf6b9d --- /dev/null +++ b/sprite-demos/invaders/src/Bomb.cpp @@ -0,0 +1,40 @@ +#include "Bomb.hpp" +#include +#include "config.hpp" +#include + +SpriteList *bombs; + +void bomb_init() +{ + // Bombs - create bitmap and create SpriteList - Bullet Sprites will be created later + + vdp_select_bitmap( BOMB_BITMAP ); + vdp_solid_bitmap( BOMB_WIDTH, BOMB_HEIGHT, + BOMB_COLOUR_R, BOMB_COLOUR_G, BOMB_COLOUR_B, BOMB_COLOUR_A ); + + bombs = new SpriteList( 0, 0, SC_WIDTH, SC_HEIGHT ); +} + +// Bomb member functions ////////////////// + +// Events + +Bomb *Bomb::at_bottom() +{ + delete this; // Removal from SpriteGroup is handled in the base class destructor + return NULL; +} + +Bomb *Bomb::hitting( Sprite *s ) +{ + delete this; + return NULL; +} + + +Bomb *Bomb::hitting( TileArray *ta ) +{ + delete this; + return NULL; +} \ No newline at end of file diff --git a/sprite-demos/invaders/src/Bomb.hpp b/sprite-demos/invaders/src/Bomb.hpp new file mode 100644 index 0000000..71f03ad --- /dev/null +++ b/sprite-demos/invaders/src/Bomb.hpp @@ -0,0 +1,26 @@ +#ifndef _BOMB_HPP + +#define _BOMB_HPP + +#include + +void bomb_init(); + +class Bomb : public Sprite { +public: + // Constructors and Destructor + + Bomb( 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( x, y, dx, dy, w, h, brd, bitmap ) {} + Bomb( Coords coords, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 ) + : Sprite( coords, dx, dy, w, h, brd, bitmap ) {} + ~Bomb() {}; + + // Events + + Bomb *at_bottom(); + Bomb *hitting( Sprite *s ); + Bomb *hitting( TileArray *ta ); +}; + +#endif \ No newline at end of file diff --git a/sprite-demos/invaders/src/Bullet.cpp b/sprite-demos/invaders/src/Bullet.cpp new file mode 100644 index 0000000..8fac456 --- /dev/null +++ b/sprite-demos/invaders/src/Bullet.cpp @@ -0,0 +1,41 @@ +#include "Bullet.hpp" +#include +#include "config.hpp" +#include + +SpriteList *bullets; + +void bullet_init() +{ + // Bullets - create bitmap and create SpriteList - Bullet Sprites will be created later + + vdp_select_bitmap( BULLET_BITMAP ); + vdp_solid_bitmap( BULLET_WIDTH, BULLET_HEIGHT, + BULLET_COLOUR_R, BULLET_COLOUR_G, BULLET_COLOUR_B, BULLET_COLOUR_A ); + + bullets = new SpriteList( 0, 0, SC_WIDTH, SC_HEIGHT ); +} + + +// Bullet member functions ////////////////// + +// Events + +Bullet *Bullet::at_top() +{ + delete this; // Removal from SpriteGroup is handled in the base class destructor + return NULL; +} + +Bullet *Bullet::hitting( Sprite *s ) +{ + delete this; + return NULL; +} + + +Bullet *Bullet::hitting( TileArray *ta ) +{ + delete this; + return NULL; +} \ No newline at end of file diff --git a/sprite-demos/invaders/src/Bullet.hpp b/sprite-demos/invaders/src/Bullet.hpp new file mode 100644 index 0000000..3965aeb --- /dev/null +++ b/sprite-demos/invaders/src/Bullet.hpp @@ -0,0 +1,27 @@ +#ifndef _BULLET_HPP + +#define _BULLET_HPP + +#include + + +void bullet_init(); + +class Bullet : public Sprite { +public: + // Constuctors & Destuctors + + Bullet( 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( x, y, dx, dy, w, h, brd, bitmap ) {} + Bullet( Coords coords, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 ) + : Sprite( coords, dx, dy, w, h, brd, bitmap ) {} + ~Bullet() {}; + + // Events + + Bullet *at_top(); + Bullet *hitting( Sprite *s ); + Bullet *hitting( TileArray *ta ); +}; + +#endif \ No newline at end of file diff --git a/sprite-demos/invaders/src/Ship.cpp b/sprite-demos/invaders/src/Ship.cpp new file mode 100644 index 0000000..c9d87e7 --- /dev/null +++ b/sprite-demos/invaders/src/Ship.cpp @@ -0,0 +1,95 @@ +#include "Ship.hpp" +#include +#include "config.hpp" +#include +#include +#include + +static ROT_TABLE rot_ship[] = { + { 0, 0, -4, 6 }, + { 15, 1, -4, 7 }, + { 30, 2, -4, 8 }, + { 45, 3, -3, 9 }, + { 60, 4, -2, 10 }, + { 75, 4, -1, 11 }, + { 90, 4, 0, 12 }, + { 105, 4, 1, 13 }, + { 120, 4, 2, 14 }, + { 135, 3, 3, 15 }, + { 150, 2, 4, 16 }, + { 165, 1, 4, 17 }, + { 180, 0, 4, 18 }, + { 195, -1, 4, 19 }, + { 210, -2, 4, 20 }, + { 225, -3, 3, 21 }, + { 240, -4, 2, 22 }, + { 255, -4, 1, 23 }, + { 270, -4, 0, 0 }, + { 285, -4, -1, 1 }, + { 300, -4, -2, 2 }, + { 315, -3, -3, 3 }, + { 330, -2, -4, 4 }, + { 345, -1, -4, 5 } +}; + +Ship *ship; +static DummySpriteGroup *viewport; + +// Ship initialisation +// - load bitmaps and create Ship Sprite +// - create DummySpriteGroup to provide a viewport + +void ship_init() +{ + vdp_load_sprite_bitmaps( SHIP_FNAME_PREFIX, SHIP_FNAME_FORMAT, + SHIP_WIDTH, SHIP_HEIGHT, + SHIP_BITMAP_ID_NUM, SHIP_BITMAP_ID_START ); + + ship = new Ship( SHIP_X, SHIP_Y, 0, 0, SHIP_WIDTH, SHIP_HEIGHT, SHIP_BORDER ); + ship->add_bitmaps( SHIP_BITMAP_ID_START, SHIP_BITMAP_ID_NUM ); + ship->add_bitmaps(4, 4, 1); // add die frame bitmaps + + ship->add_rotations( rot_ship, SHIP_NUM_ROT, 0, true ); + ship->show(); + + viewport = new DummySpriteGroup( 0, 0, SC_WIDTH, SC_HEIGHT ); + viewport->add( ship ); +} + +// Ship members functions //////////// + +// Events + +Ship *Ship::hit_by( Sprite *s ) +{ + die(); + return this; +} + +Ship *Ship::dead() +{ + printf( "\n\nGame over\nScore: %04d\n", score ); + vdp_cursor_enable( true ); + exit( 0 ); +} + +// Movement + +void Ship::move_by( int dx, int dy ) +{ + int vp_x0, vp_y0; + int vp_x1, vp_y1; + + if ( get_viewport( &vp_x0, &vp_y0, &vp_x1, &vp_y1) ) { + if ( s_x + s_w + dx >= vp_x1 ) dx = 0; + else if ( s_x + dx < vp_x0 ) dx = 0; + + if ( s_y + s_h + dy >= vp_y1 ) dy = 0; + else if ( s_y + dy < vp_y0 ) dy = 0; + } + s_x += dx; + s_y += dy; + + vdp_select_sprite( s_vdp_id ); + vdp_move_sprite_by( dx, dy ); +} diff --git a/sprite-demos/invaders/src/Ship.hpp b/sprite-demos/invaders/src/Ship.hpp new file mode 100644 index 0000000..2a1c948 --- /dev/null +++ b/sprite-demos/invaders/src/Ship.hpp @@ -0,0 +1,30 @@ +#ifndef _SHIP_HPP + +#define _SHIP_HPP + +#include + + +void ship_init(); + +class Ship : public RotSprite { +public: + // Constructors & destructors + + Ship( 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( x, y, dx, dy, w, h, brd, bitmap ) {} + Ship( Coords coords, int dx = 0, int dy = 0, int w = 0, int h = 0, int brd = 0, int bitmap = -1 ) + : RotSprite( coords, dx, dy, w, h, brd, bitmap ) {} + ~Ship() {}; + + // Events + + Ship *hit_by( Sprite *s ); + Ship *dead(); + + // Postioning + + void move_by( int dx, int dy ); +}; + +#endif diff --git a/sprite-demos/invaders/src/Sprite/RotSprite.cpp b/sprite-demos/invaders/src/Sprite/RotSprite.cpp new file mode 100644 index 0000000..0f4bca0 --- /dev/null +++ b/sprite-demos/invaders/src/Sprite/RotSprite.cpp @@ -0,0 +1,69 @@ +#include +#include + +RotSprite::RotSprite( int x, int y, int dx, int dy, int w, int h, int brd, int bitmap ) + : Sprite( x, y, dx, dy, w, h, brd, bitmap ) +{} + +RotSprite::RotSprite( Coords coords, int dx, int dy, int w, int h, int brd, int bitmap ) + : Sprite( coords, dx, dy, w, h, brd, bitmap ) +{} + +// Rotation table handling + +void RotSprite::add_rotations( ROT_TABLE *rot_table, int num_rot, int cur_rot, bool circular ) { + rs_rot_table = rot_table; + rs_num_rot = num_rot; + rs_cur_rot = cur_rot; + rs_circular = circular; + + set_frame( rs_rot_table[rs_cur_rot].frame ); +} + +// Gettters + +Coords RotSprite::get_dir_vec() +{ + return Coords( rs_rot_table[rs_cur_rot].vec_x, rs_rot_table[rs_cur_rot].vec_y ); +} + +// Frames + +void RotSprite::next_frame() +{ + vdp_select_sprite( s_vdp_id ); + switch( state ) + { + case ALIVE: + break; + case DYING: + if ( ++cur_frame >= frames + die_frames ) dead(); + else vdp_nth_sprite_frame( cur_frame ); + break; + case DEAD: + break; + } +} + +// Sprite Events - overridden from Sprite base class + + +// RotSprite Events - that can be overriden in derived classes + +int RotSprite::rot_c_wise() +{ + if ( ++rs_cur_rot >= rs_num_rot && !rs_circular ) { --rs_cur_rot; return -1; } + + if ( rs_cur_rot >= rs_num_rot ) rs_cur_rot = 0; + set_frame( rs_rot_table[rs_cur_rot].frame ); + return rs_cur_rot; +} + +int RotSprite::rot_ac_wise() +{ + if ( --rs_cur_rot < 0 && !rs_circular ) { ++rs_cur_rot; return -1; } + + if ( rs_cur_rot < 0 ) rs_cur_rot = rs_num_rot-1; + set_frame( rs_rot_table[rs_cur_rot].frame ); + return rs_cur_rot; +} diff --git a/sprite-demos/invaders/src/Sprite/Sprite.cpp b/sprite-demos/invaders/src/Sprite/Sprite.cpp new file mode 100644 index 0000000..607eded --- /dev/null +++ b/sprite-demos/invaders/src/Sprite/Sprite.cpp @@ -0,0 +1,382 @@ +#include +#include +#include +#include +#include + + +//////////////// Sprite Class /////////////////// + +// static int num_vdp_sprites = 0; // Number of VDP sprites used + // At the moment do dumb allocation of next id with no reclaim + +// Static members + +int Sprite::sprites_max_num = 0; +int Sprite::sprites_num = 0; +int Sprite::sprites_next_free = 0; +Sprite **Sprite::sprites_vdp = NULL; + +// Constructors, destructors & associated helper functions + +int Sprite::init( int num_sprites ) +{ + if ( num_sprites > 255 ) return 0; + sprites_max_num = num_sprites; + + if ( !(sprites_vdp = (Sprite **)calloc( sprites_max_num, sizeof(Sprite *) )) ) return 0; + return sprites_max_num; +} + +Sprite::Sprite( int x, int y, int dx, int dy, int width, int height, int border, int bitmap ) +{ + set_details( x, y, dx, dy, width, height, border, bitmap ); +} + +Sprite::Sprite( Coords coords, int dx, int dy, int width, int height, int border, int bitmap ) +{ + set_details( coords.x, coords.y, dx, dy, width, height, border, bitmap ); +} + +int Sprite::get_free_sprite_id() +{ + int cnt = sprites_max_num; + while ( cnt-- > 0 ) { + if ( !sprites_vdp[sprites_next_free] ) return sprites_next_free; + sprites_next_free++; + if ( sprites_next_free >= sprites_max_num ) sprites_next_free = 0; + } + return -1; +} + +void Sprite::set_details( int x, int y, int dx, int dy, int width, int height, int border, int bitmap ) +{ + if ( sprites_num > sprites_max_num ) { + printf( "Too many sprites %d out of %d\n used", sprites_num, sprites_max_num ); + vdp_cursor_enable( true ); + exit( 1 ); // For the moment exit, really should throw exception + } + if ( ( s_vdp_id = get_free_sprite_id() ) < 0 ) { + printf( "Failed to find free sprite id, %d\n", s_vdp_id ); + vdp_cursor_enable( true ); + exit( 1 ); + } + sprites_vdp[s_vdp_id] = this; + sprites_num++; + + s_x = x; s_y = y; + s_w = width; s_h = height; + s_dx = dx; s_dy = dy; + s_brd = border; + visible = false; + sprite_grp = NULL; + vdp_select_sprite( s_vdp_id ); + vdp_clear_sprite(); + vdp_move_sprite_to( x, y ); + + if ( bitmap >= 0 ) { // And single bit map if one specified + add_bitmap( bitmap ); + vdp_show_sprite(); + visible = true; + } else vdp_hide_sprite(); // Hide the sprite as has no bitmaps + + vdp_activate_sprites( sprites_max_num ); // Update GPU with total no. of sprites +} + +Sprite::~Sprite() +{ + vdp_select_sprite( s_vdp_id ); + vdp_clear_sprite(); + vdp_hide_sprite(); + if ( sprite_grp ) { // If in SpriteList + sprite_grp->remove( this ); + } + sprites_vdp[s_vdp_id] = NULL; // Clear it from the vdp table + sprites_num--; +} + +// Getters + +Coords Sprite::get_centre() +{ + return Coords( s_x + s_w/2, s_y + s_h/2 ); +} + +Coords Sprite::get_top_middle() +{ + return Coords( s_x + s_w/2, s_y + s_brd ); +} + +Coords Sprite::get_bottom_middle() +{ + return Coords( s_x + s_w/2, s_y + s_h - s_brd ); +} + +Coords Sprite::get_left_middle() +{ + return Coords( s_x + s_brd, s_y + s_h/2 ); +} + +Coords Sprite::get_right_middle() +{ + return Coords( s_x + s_w - s_brd, s_y + s_h/2 ); +} + +Coords Sprite::get_top_left() +{ + return Coords( s_x + s_brd, s_y + s_brd ); +} + +Coords Sprite::get_bottom_right() +{ + return Coords( s_x + s_w - s_brd, s_y + s_h - s_brd ); +} + +bool Sprite::get_viewport( int *x0, int *y0, int *x1, int *y1 ) +{ + if ( !sprite_grp ) return false; + *x0 = sprite_grp->sg_x0; *y0 = sprite_grp->sg_y0; + *x1 = sprite_grp->sg_x1; *y1 = sprite_grp->sg_y1; + return true; +} + +// Bitmap handling + +void Sprite::add_bitmap( int bitmap_id, int die ) +{ + vdp_select_sprite( s_vdp_id ); + vdp_add_sprite_bitmap( bitmap_id ); + if ( !die ) frames++; + else die_frames++; +} + +void Sprite::add_bitmaps( int bitmap_id, int num, int die ) +{ + vdp_select_sprite( s_vdp_id ); + for ( int i = 0; i < num; i++ ) vdp_add_sprite_bitmap( bitmap_id++ ); + if ( !die ) frames += num; + else die_frames += num; +} + +// Visibility + +void Sprite::show() +{ + if ( !visible ) { + vdp_select_sprite( s_vdp_id ); + vdp_show_sprite(); + visible = true; + } +} + +void Sprite::hide() +{ + if ( visible ) { + vdp_select_sprite( s_vdp_id ); + vdp_hide_sprite(); + visible = false; + } +} + +// Positioning + +void Sprite::move_to( int xcoord, int ycoord ) +{ + s_x = xcoord; + s_y = ycoord; + vdp_select_sprite( s_vdp_id ); + vdp_move_sprite_to( xcoord, ycoord ); +} + +void Sprite::move_by( int dx, int dy ) +{ + s_x += dx; + if ( sprite_grp ) { + if ( s_x + s_w >= sprite_grp->sg_x1 ) at_right(); + else if ( s_x < sprite_grp->sg_x0 ) at_left(); + } + s_y += dy; + if ( sprite_grp ) { + if ( s_y + s_h >= sprite_grp->sg_y1 ) at_bottom(); + else if ( s_y < sprite_grp->sg_y0 ) at_top(); + } + vdp_select_sprite( s_vdp_id ); + vdp_move_sprite_by( dx, dy ); +} + +// Frames + +void Sprite::next_frame() +{ + vdp_select_sprite( s_vdp_id ); + switch( state ) + { + case ALIVE: + if ( ++cur_frame >= frames ) cur_frame = 0; + vdp_nth_sprite_frame( cur_frame ); + break; + case DYING: + if ( ++cur_frame >= frames + die_frames ) dead(); + else vdp_nth_sprite_frame( cur_frame ); + break; + case DEAD: + break; + } +} + +void Sprite::prev_frame() +{ + vdp_select_sprite( s_vdp_id ); + if ( --cur_frame < 0 ) cur_frame = frames - 1; + vdp_nth_sprite_frame( cur_frame ); +} + +void Sprite::set_frame( int n ) +{ + vdp_select_sprite( s_vdp_id ); + cur_frame = n; + vdp_nth_sprite_frame( cur_frame ); +} + +// Iterations (steps + frames) + +void Sprite::next_iter() +{ + next_step(); + next_frame(); +} + +void Sprite::prev_iter() +{ + prev_step(); + prev_frame(); +} + +// Collisions + +int Sprite::collide( Sprite *s ) +{ + if ( s->state != ALIVE ) return 0; + + int x0 = s_x + s_brd, y0 = s_y + s_brd; + int x1 = s_x + s_w - s_brd, y1 = s_y + s_h - s_brd; + int xs0 = s->s_x + s->s_brd, ys0 = s->s_y + s->s_brd; + int xs1 = s->s_x + s->s_w - s->s_brd, ys1 = s->s_y + s->s_h - s->s_brd; +/* + printf( "Bouding rectangles: ((%d, %d) (%d, %d)) ((%d, %d) (%d, %d))\n", + x0, y0, x1, y1, + xs0, ys0, xs1, ys1 ); +*/ + int overlap_x = 0, overlap_y = 0; + if ( xs0 < x1 && xs1 > x0 ) overlap_x = 1; + if ( ys0 < y1 && ys1 > y0 ) overlap_y = 1; + +// printf ( "Overlap x %d, overap y %d\n", overlap_x, overlap_y ); + + return overlap_x & overlap_y; +} + +int Sprite::hit( Sprite *s ) +{ + if ( collide( s ) ) { + s->hit_by( this ); + hitting( s ); + return 1; + } + return 0; +} + +void Sprite::hit( SpriteGroup *sg ) +{ + sg->is_hit( this ); +} + +int Sprite::is_hit( Sprite *s ) +{ + if ( collide( s ) ) { + hit_by( s ); + s->hitting( this ); + return 1; + } + return 0; +} + + +// Events + +Sprite *Sprite::at_left() +{ + s_dx = -s_dx; + s_x += s_dx; + return this; +} + +Sprite *Sprite::at_right() +{ + s_dx = -s_dx; + s_x += s_dx; + return this; +} + +Sprite *Sprite::at_top() +{ + s_dy = -s_dy; + s_y += s_dy; + return this; +} + +Sprite *Sprite::at_bottom() +{ + s_dy = -s_dy; + s_y += s_dy; + return this; +} + +Sprite *Sprite::hit_by( Sprite *s ) +{ + return this; +} + +Sprite *Sprite::hitting( Sprite *s ) +{ + return this; +} + +Sprite *Sprite::hitting( TileArray *ta ) +{ + return this; +} + +Sprite *Sprite::die() +{ + vdp_select_sprite( s_vdp_id ); + cur_frame = frames; // set to first die frame + if ( die_frames > 0 ) { + vdp_nth_sprite_frame( cur_frame ); + state = DYING; + } + else dead(); + return this; +} + +Sprite *Sprite::dead() +{ + vdp_select_sprite( s_vdp_id ); + vdp_hide_sprite(); + state = DEAD; + return this; +} + +// Debugging + +void Sprite::dump() +{ +// printf( "x %d, y %d, w %d, h %d, brd %d, dx %d, dy %d\n", s_x, s_y, s_w, s_h, s_brd, s_dx, s_dy ); + printf( "Sprite normal %d, die %d, current %d, state %d\n", frames, die_frames, cur_frame, state ); +} + +void Sprite::debug() +{ + printf( "Number of sprites %d\n", sprites_num ); +} + diff --git a/sprite-demos/invaders/src/Sprite/SpriteArray.cpp b/sprite-demos/invaders/src/Sprite/SpriteArray.cpp new file mode 100644 index 0000000..7232f3f --- /dev/null +++ b/sprite-demos/invaders/src/Sprite/SpriteArray.cpp @@ -0,0 +1,155 @@ +#include +#include + +////////////// SpriteArray Class - derived from SpriteGroup ////////////// + +// Constructor + +SpriteArray::SpriteArray( int cols, int rows, int col_w, int row_h, int x, int y, int dx, int dy, + int x0, int y0, int x1, int y1 ) + : SpriteGroup( x0, y0, x1, y1 ) +{ + array_size = rows * cols; + num_cols = cols; num_rows = rows; + sa_col_w = col_w; sa_row_h = row_h; + + array = new Sprite *[array_size]; + + sa_x = x; sa_y = y; + sa_dx = dx; sa_dy = dy; + + col_num_remain = new int[cols]; + for ( int c = 0; c < cols; c++ ) col_num_remain[c] = rows; + col_min = 0; + col_max = cols - 1; + + row_num_remain = new int[rows]; + for ( int r = 0; r < rows; r++ ) row_num_remain[r] = cols; + row_min = 0; + row_max = rows - 1; +} + +// Elements + +Sprite *SpriteArray::elem( int col, int row ) +{ + return array[row + col*num_rows]; +} + +void SpriteArray::set_elem( int col, int row, Sprite *s ) +{ + array[row + col*num_rows] = s; + s->sprite_grp = this; + num_elements++; +} + +Sprite *SpriteArray::remove( Sprite *s ) // Removes element & returns it or NULL if not found +{ + Sprite **spp = array; + + for ( int c = 0; c < num_cols; c ++ ) + for ( int r = 0; r < num_rows; r++, spp++ ) + if ( *spp == s ) { + *spp = NULL; + num_elements--; + update_min_max_col( c ); + update_min_max_row( r ); + return s; + } + return NULL; +} + +void SpriteArray::update_min_max_col( int c ) { + if ( !--col_num_remain[c] ) { + if ( c == col_min ) { + col_min++; + while ( !col_num_remain[col_min] && col_min < col_max ) col_min++; + } + else if ( c == col_max ) { + col_max--; + while ( !col_num_remain[col_max] && col_max > col_min ) col_max--; + } + } +} + + +void SpriteArray::update_min_max_row( int r ) { + if ( !--row_num_remain[r] ) { + if ( r == row_min ) { + row_min++; + while ( !row_num_remain[row_min] && row_min < row_max ) row_min++; + } + else if ( r == row_max ) { + row_max--; + while ( !row_num_remain[row_max] && row_max > row_min ) row_max--; + } + } +} + + +// Required for iterators + +Sprite *SpriteArray::begin() +{ + if ( !(cur_elem = array) ) return NULL; // Return NULL if not initialised + + while ( cur_elem < array + array_size ) // Return element skipping over any blanks + if ( *cur_elem ) return *cur_elem; + else cur_elem++; + return NULL; +} + +Sprite *SpriteArray::next() +{ + while ( ++cur_elem < array + array_size ) + if ( *cur_elem ) return *cur_elem; + return NULL; +} + +// Movement + +void SpriteArray::next_iter() +{ + next_step(); + next_frame(); +} + + +void SpriteArray::next_step() +{ + // Check if about to move off the edge of the viewport (left & right) + if ( sa_x + col_min*sa_col_w + sa_dx < sg_x0 ) at_left(); + if ( sa_x + (col_max+1)*sa_col_w + sa_dx >= sg_x1 ) at_right(); + + for ( Sprite *s = begin(); s; s = next() ) { + s->set_speed( sa_dx, sa_dy ); + s->next_step(); + } + sa_x += sa_dx; sa_y += sa_dy; +} + +// Events + +void SpriteArray::at_left() +{ + sa_dx = -sa_dx; +} + +void SpriteArray::at_right() +{ + sa_dx = -sa_dx; +} + + +// Debugging + +void SpriteArray::dump() +{ + printf( "Alien columns [%d to %d]: ", col_min, col_max ); + for ( int c = 0; c <= col_max; c++ ) + printf( " %d", col_num_remain[c] ); + printf( "\nAlien rows [%d to %d]: ", row_min, row_max ); + for ( int r = 0; r <= row_max; r++ ) + printf( " %d", row_num_remain[r] ); + printf( "\n" ); +} diff --git a/sprite-demos/invaders/src/Sprite/SpriteGroup.cpp b/sprite-demos/invaders/src/Sprite/SpriteGroup.cpp new file mode 100644 index 0000000..4afeab9 --- /dev/null +++ b/sprite-demos/invaders/src/Sprite/SpriteGroup.cpp @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +////////////// Sprite Group Class ////////////// + +// Constructor + +SpriteGroup::SpriteGroup( int x0, int y0, int x1, int y1 ) +{ + sg_x0 = x0; sg_y0 = y0; + sg_x1 = x1; sg_y1 = y1; +} + +// Actions + +void SpriteGroup::move_by( int dx, int dy ) +{ + for ( Sprite *s = begin(); s; s = next() ) s->move_by( dx, dy ); +} + +void SpriteGroup::next_frame() +{ + for ( Sprite *s = begin(); s; s = next() ) s->next_frame(); +} + +void SpriteGroup::prev_frame() +{ + for ( Sprite *s = begin(); s; s = next() ) s->prev_frame(); +} + +void SpriteGroup::next_step() +{ + for ( Sprite *s = begin(); s; s = next() ) s->next_step(); +} + +void SpriteGroup::prev_step() +{ + for ( Sprite *s = begin(); s; s = next() ) s->prev_step(); +} + +void SpriteGroup::next_iter() +{ + for ( Sprite *s = begin(); s; s = next() ) s->next_iter(); +} + +void SpriteGroup::prev_iter() +{ + for ( Sprite *s = begin(); s; s = next() ) s->prev_iter(); +} + +void SpriteGroup::hide() +{ + for ( Sprite *s = begin(); s; s = next() ) s->hide(); +} + +void SpriteGroup::show() +{ + for ( Sprite *s = begin(); s; s = next() ) s->show(); +} + +// Collisions //////////////////////////////////////// + +// If Sprite s hits member of SpriteGroup, sp +// - trigger hit_by() events on sp and hitting() events on s +// - repeat for all memembers of the SpriteGroup - i.e. s may hit multiple SpriteGroup members +// - note that s and/or sp may be deleted as a result in the event handler +// - so explicitly check wether s becomes NULL as part of the for loop condition + +void SpriteGroup::is_hit( Sprite *s ) +{ + for ( Sprite *sp = begin(); s && sp; sp = next() ) s->hit( sp ); +} + +// If member of SpriteGroup sp hits member of Sprite s +// - trigger hittting() events on sp and hit_by() events on s +// - repeat for all memembers of the SpriteGroup +// - note that s and/or sp may be deleted as a result in the event handler +// - so explicitly check wether s becomes NULL as part of the for loop condition + +void SpriteGroup::hit( Sprite *s ) +{ + for ( Sprite *sp = begin(); s && sp; sp = next() ) sp->hit( s ); +} + +// If member of SpriteGroup sp hits member of SpriteGroup sg +// - trigger hitting() events on sp and hit_by() events on the member of sg +// - repeat for all memembers of the SpriteGroup +// - note that members of either SpriteGroup maybe deleted as a result of events +// - this dealt with by the called routines - don't need to explicitly handle here + +void SpriteGroup::hit( SpriteGroup *sg ) +{ + for ( Sprite *sp = begin(); sp; sp = next() ) sg->is_hit( sp ); +} + +// If members of SpriteList sp hits elements of TileArray ta +// - trigger hitting() events on sp and hit_by() events on the elements of ta +// - repeat for all memembers of the SpriteGroup +// - note that members of the SpriteGroup or TileArray maybe deleted as a result of events +// - this dealt with by the called routines - don't need to explicitly handle here + +void SpriteGroup::hit( TileArray *ta ) +{ + for ( Sprite *sp = begin(); sp; sp = next() ) ta->is_hit( sp ); +} + +// Debugging + +void SpriteGroup::dump() +{ + printf( "SpriteGroup Elements: %d\n", num_elements ); + int i = 0; + for ( Sprite *s = begin(); i <= num_elements; s = next(), i++ ) + printf( "Sprite[%d] at %p\n", i, s ); +} diff --git a/sprite-demos/invaders/src/Sprite/SpriteList.cpp b/sprite-demos/invaders/src/Sprite/SpriteList.cpp new file mode 100644 index 0000000..7e61cc2 --- /dev/null +++ b/sprite-demos/invaders/src/Sprite/SpriteList.cpp @@ -0,0 +1,64 @@ +#include + +////////////// SpriteList Class - derived from SpriteGroup ////////////// + +// Constructor + +SpriteList::SpriteList( int x0, int y0, int x1, int y1 ) + : SpriteGroup( x0, y0, x1, y1 ) +{} + +// Elements + + +void SpriteList::add( Sprite *s ) +{ + SpriteListElem *sge = new SpriteListElem( s ); + if ( !first ) { // If currently no elements + first = sge; + last = sge; + } else { + last->next = sge; // Point last enter to new final element + last = sge; // Update last pointer to new final element + } + num_elements++; + s->sprite_grp = this; +} + +Sprite *SpriteList::remove( Sprite *s ) // Removes element & returns it or NULL if not found +{ + SpriteListElem *sge = first; + SpriteListElem *prev = NULL; + while ( sge ) { + if ( sge->sprite == s ) { + if ( !prev ) { // Remove the element if first + first = sge->next; + } else { // or subsequent + prev->next = sge->next; + } + + if ( sge == last ) { // If last element update last + last = prev; + } + + num_elements--; // decrease the number of elements + return sge->sprite; // and return the removed element + } + prev = sge; + sge = sge->next; // Move on to next element & iterate + } + return NULL; // Reached end of list & not found +} + +Sprite *SpriteList::begin() +{ + if ( (current = first) ) return current->sprite; + return NULL; +} + +Sprite *SpriteList::next() +{ + if ( (current = current->next) ) return current->sprite; + return NULL; +} + diff --git a/sprite-demos/invaders/src/Sprite/Tile.cpp b/sprite-demos/invaders/src/Sprite/Tile.cpp new file mode 100644 index 0000000..60d89b0 --- /dev/null +++ b/sprite-demos/invaders/src/Sprite/Tile.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#include + +////////////// Tile Class ////////////// + +// Constructor + +Tile::Tile( int xcoord, int ycoord, int width, int height, int bitmap ) +{ + t_x = xcoord; t_y = ycoord; + t_w = width; t_h = height; + t_bitmap = bitmap; +} + +// Member functions + +void Tile::set_bitmap( int bitmap ) +{ + t_bitmap = bitmap; +} + +void Tile::draw() +{ + if ( t_bitmap > 0 ) { // Draw if not blank + vdp_select_bitmap( t_bitmap ); + vdp_draw_bitmap( t_x, t_y ); + } +} + +void Tile::blank( int blank_bitmap ) +{ + t_bitmap = -1; + vdp_select_bitmap( blank_bitmap ); + vdp_draw_bitmap( t_x, t_y ); +} + +// Events + +void Tile::hit_by( int blank_bitmap, Sprite *s ) +{ + blank( blank_bitmap ); +} + +////////////// TileArray Class ////////////// + +// Constructor + +TileArray::TileArray( int c, int r, int xcoord, int ycoord, int width, int height, + int bitmap, int blank_bitmap ) +{ + ta_rows = r, ta_cols = c; + ta_x = xcoord; ta_y = ycoord; + ta_w = width; ta_h = height; + ta_blank_bitmap = blank_bitmap; + + if ( !(array = new Tile[ta_rows*ta_cols]) ) { + printf( "Can't allocated memory for TileArray.\n" ); + exit( 1 ); + } + + Tile *tp = array; + for ( c = 0; c < ta_cols; c++ ) { + ycoord = ta_y; + for ( r = 0; r < ta_rows; r++, tp++ ) { + tp->t_x = xcoord; tp->t_y = ycoord; + tp->t_w = width; tp->t_h = height; + tp->t_bitmap = bitmap; + ycoord += height; + } + xcoord += width; + } +} + +Tile *TileArray::elem( int c, int r ) +{ + return array + r + c*ta_rows; +} + +void TileArray::set_bitmap( int bitmap ) +{ + int r, c; + for ( r = 0; r < ta_rows; r ++ ) + for ( c = 0; c < ta_cols; c++ ) + elem(c, r)->t_bitmap = bitmap; +} + +void TileArray::clear( int c0, int r0, int c1, int r1 ) +{ + + if ( c1 < 0 || r1 < 0 ) return; + + if ( c0 >= ta_cols || r0 >= ta_rows ) return; + + if ( c0 < 0 ) c0 = 0; + if ( r0 < 0 ) r0 = 0; + if ( c1 >= ta_cols ) c1 = ta_cols-1; + if ( r1 >= ta_rows ) r1 = ta_rows-1; + + for ( int c = c0; c <= c1; c++ ) + for ( int r = r0; r <= r1; r++ ) + elem(c, r)->t_bitmap = -1; +} + +void TileArray::draw() +{ + int r, c; + for ( r = 0; r < ta_rows; r ++ ) + for ( c = 0; c < ta_cols; c++ ) + elem(c, r)->draw(); +} + +Tile *TileArray::collide( int x, int y ) +{ + x -= ta_x; + y -= ta_y; + if ( x < 0 || y < 0) return NULL; + + int c = x / ta_w; + int r = y / ta_h; + if ( c >= ta_cols || r >= ta_rows ) return NULL; + + if ( elem(c, r)->t_bitmap > 0 ) return elem(c, r); // check if not blank + else return NULL; +} + +void TileArray::is_hit( Sprite *s ) +{ + Coords coord0 = s->get_top_left(); + Coords coord1 = s->get_bottom_right(); + + int x0 = coord0.x - ta_x, y0 = coord0.y - ta_y; + int x1 = coord1.x - ta_x, y1 = coord1.y - ta_y; + + if ( x1 < 0 || y1 < 0 ) return; + + int c0 = x0 / ta_w, r0 = y0 / ta_h; + int c1 = x1 / ta_w, r1 = y1 / ta_h; + + if ( c0 >= ta_cols || r0 >= ta_rows ) return; + + if ( c0 < 0 ) c0 = 0; + if ( r0 < 0 ) r0 = 0; + if ( c1 >= ta_cols ) c1 = ta_cols-1; + if ( r1 >= ta_rows ) r1 = ta_rows-1; +/* + printf( "Sprite rel coords (%03d, %03d)-(%03d, %03d)", x0, y0, x1, y1 ); + printf( " c/r (%02d,%02d)-(%02d,%02d)\n", c0, r0, c1, r1 ); + printf( "TileArray c/r (%02d,%02d) w/h (%02d,%02d)\n", ta_cols, ta_rows, ta_w, ta_h ); +*/ + int hit = 0; + for ( int c = c0; c <= c1; c++ ) + for ( int r = r0; r <= r1; r++ ) + if ( elem(c, r)->t_bitmap > 0 ) { + elem(c, r)->hit_by( ta_blank_bitmap, s ); + hit = 1; + } + if ( hit ) s->hitting( this ); +} + +void TileArray::is_hit( SpriteGroup *sg ) +{ + for ( Sprite *s = sg->begin(); s; s = sg->next() ) is_hit( s ); +} + diff --git a/sprite-demos/invaders/src/barrier.cpp b/sprite-demos/invaders/src/barrier.cpp new file mode 100644 index 0000000..dfdd596 --- /dev/null +++ b/sprite-demos/invaders/src/barrier.cpp @@ -0,0 +1,25 @@ +#include "barrier.hpp" +#include +#include "config.hpp" +#include + +TileArray *barrier[BARRIER_NUM]; + +void barrier_init() +{ + vdp_select_bitmap( SOLID_BITMAP ); + vdp_solid_bitmap( BARRIER_BLOCK_W, BARRIER_BLOCK_H, 255, 255, 255, 255 ); + vdp_select_bitmap( BLANK_BITMAP ); + vdp_solid_bitmap( BARRIER_BLOCK_W, BARRIER_BLOCK_H, 0, 0, 0, 255 ); + + + int b_x = BARRIER_X; + for ( int b = 0; b < BARRIER_NUM; b++ ) + { + barrier[b] = new TileArray( BARRIER_COLS, BARRIER_ROWS, b_x, BARRIER_Y, + BARRIER_BLOCK_W, BARRIER_BLOCK_H, SOLID_BITMAP, BLANK_BITMAP ); + barrier[b]->clear( BARRIER_CLEAR_C0, BARRIER_CLEAR_R0, BARRIER_CLEAR_C1, BARRIER_CLEAR_C1 ); + barrier[b]->draw(); + b_x += BARRIER_SPACING; + } +} \ No newline at end of file diff --git a/sprite-demos/invaders/src/barrier.hpp b/sprite-demos/invaders/src/barrier.hpp new file mode 100644 index 0000000..ef1fa48 --- /dev/null +++ b/sprite-demos/invaders/src/barrier.hpp @@ -0,0 +1,7 @@ +#ifndef _BARRIER_HPP + +#define _BARRIER_HPP + +void barrier_init(); + +#endif \ No newline at end of file diff --git a/sprite-demos/invaders/src/config.hpp b/sprite-demos/invaders/src/config.hpp new file mode 100644 index 0000000..02c19a4 --- /dev/null +++ b/sprite-demos/invaders/src/config.hpp @@ -0,0 +1,108 @@ +#ifndef _CONFIG_HPP + +#define _CONFIG_HPP + +// Overall configuration constants + +#define SC_MODE 1 +#define SC_WIDTH 512 +#define SC_HEIGHT 384 + +#define MAX_SPRITES 255 // Maximum number of simultaneous sprites + +// Bitmap allocation +// 0-3 Alien +// 4-7 Alien explosion (this is also used for ship explosion) +// 8-31 Ship rotations +// 252 Bomb bitmap +// 253 Bullet bitmap +// 254 Solid bitmap +// 255 blank bitmap + +// Definitions for ship + +#define SHIP_FNAME_PREFIX "bitmaps/ship" +#define SHIP_FNAME_FORMAT "%s%02d.rgba" +#define SHIP_WIDTH 16 +#define SHIP_HEIGHT 16 +#define SHIP_BITMAP_ID_START 8 +#define SHIP_BITMAP_ID_NUM 24 + +#define SHIP_X 256 // Top left corner (x) +#define SHIP_Y 300 // Top left corner (y) +#define SHIP_BORDER 3 // Border within sprite for collision detection + +#define SHIP_NUM_ROT 24 + +// Definitions for aliens + +#define ALIEN_FNAME_PREFIX "bitmaps/gal-red" +#define ALIEN_FNAME_FORMAT "%s%1d.rgba" +#define ALIEN_WIDTH 16 +#define ALIEN_HEIGHT 16 +#define ALIEN_BITMAP_ID_START 0 +#define ALIEN_BITMAP_ID_NUM 4 + +#define ALIEN_COLS 10 +#define ALIEN_ROWS 5 +#define NUM_ALIENS 50 +#define ALIEN_X 64 // Top left corner (x) of 1st alien +#define ALIEN_Y 64 // Top left corner (y) of first alien +#define ALIEN_X_SPACING 32 // Spacing between aliens (x) +#define ALIEN_Y_SPACING 32 // Spacing between aliens (y) +#define ALIEN_SPEED 2 // Horizontal step / speed +#define ALIEN_STEP 16 // Vrtical step when reaches end of line +#define ALIEN_BORDER 3 // Border within sprite for collision detection + +#define EXPLODE_FNAME_PREFIX "bitmaps/gal-explode" +#define EXPLODE_FNAME_FORMAT "%s%1d.rgba" +#define EXPLODE_WIDTH 16 +#define EXPLODE_HEIGHT 16 +#define EXPLODE_BITMAP_ID_START 4 +#define EXPLODE_BITMAP_ID_NUM 4 + +// Definitions for bombs + +#define BOMB_BITMAP 252 +#define BOMB_WIDTH 2 +#define BOMB_HEIGHT 2 +#define BOMB_STEP 2 + +#define BOMB_COLOUR_R 0 +#define BOMB_COLOUR_G 255 +#define BOMB_COLOUR_B 255 +#define BOMB_COLOUR_A 255 + +// Definitions for bullets + +#define BULLET_BITMAP 253 +#define BULLET_WIDTH 2 +#define BULLET_HEIGHT 4 +#define BULLET_STEP -4 + +#define BULLET_COLOUR_R 255 +#define BULLET_COLOUR_G 255 +#define BULLET_COLOUR_B 0 +#define BULLET_COLOUR_A 255 + +// Definitions for barrier / bases + +#define BLANK_BITMAP 255 +#define SOLID_BITMAP 254 +#define BARRIER_X 48 +#define BARRIER_Y 240 +#define BARRIER_BLOCK_W 1 +#define BARRIER_BLOCK_H 1 +#define BARRIER_ROWS 24 +#define BARRIER_COLS 32 +#define BARRIER_SPACING 64 +#define BARRIER_NUM 7 + +#define BARRIER_CLEAR_C0 8 +#define BARRIER_CLEAR_R0 12 +#define BARRIER_CLEAR_C1 23 +#define BARRIER_CLEAR_R1 24 + +extern int score; + +#endif \ No newline at end of file diff --git a/sprite-demos/invaders/src/main.cpp b/sprite-demos/invaders/src/main.cpp new file mode 100644 index 0000000..932e25a --- /dev/null +++ b/sprite-demos/invaders/src/main.cpp @@ -0,0 +1,216 @@ +// VDU commands + +#include +#include +#include +#include +#include +#include +#include +#include "config.hpp" +#include +#include +#include +#include "Bullet.hpp" +#include "Alien.hpp" +#include "Bomb.hpp" +#include "Ship.hpp" +#include "barrier.hpp" + + +void game_loop(); +void key_event_handler( KEY_EVENT key_event ); +void wait_cnt( int cnt ); +void wait_tick(); + +extern AlienArray *aliens; +extern SpriteList *bombs; +extern SpriteList *bullets; + +extern Ship *ship; +extern TileArray *barrier[]; + +int score; + +static volatile SYSVAR *sv; + +int main() +{ + // Initialisation of vdp_vdu, vdp_key and Sprites + + sv = vdp_vdu_init(); + if ( vdp_key_init() == -1 ) return 1; + + if ( Sprite::init( MAX_SPRITES ) != MAX_SPRITES ) return 1; + + vdp_mode( SC_MODE ); + vdp_clear_screen(); + vdp_logical_scr_dims( false ); + vdp_cursor_enable( false ); + + barrier_init(); + alien_init(); // Do this one first at ship borrows the same explosion bitmaps + ship_init(); + bullet_init(); + bomb_init(); + + // Get ready for game loop & enter game loop + + vdp_set_key_event_handler( key_event_handler ); + + score = 0; + game_loop(); // Actually this never returns - exit via event handler + + vdp_cursor_enable( true ); + + return 0; +} + +void game_loop() +{ + Bomb *bomb; + + while ( true ) { +// printf( "Press any key..." ); getchar(); + aliens->next_iter(); + ship->next_frame(); + for ( int s = 0; s < 4; s++ ) { + int dx = 0, dy = 0; + if ( vdp_check_key_press( 0x9c ) ) dx = 3; // right + if ( vdp_check_key_press( 0x9a ) ) dx -= 3; // left + if ( vdp_check_key_press( 0x96 ) ) dy = -3; // up + if ( vdp_check_key_press( 0x98 ) ) dy += 3; // down + ship->move_by( dx, dy ); + + bullets->hit( aliens ); + bullets->hit( ship ); + aliens->hit( ship ); + bombs->hit( ship ); + for ( int b = 0; b < BARRIER_NUM; b++ ) { + barrier[b]->is_hit( aliens ); + barrier[b]->is_hit( ship ); + } + + for ( int c = 0; c < ALIEN_COLS; c++ ) + for ( int r = ALIEN_ROWS-1; r >=0; r-- ) + if ( aliens->elem(c,r) ) { + if ( rand() <= RAND_MAX / 20 ) { + bomb = new Bomb( aliens->elem(c,r)->get_bottom_middle(), + 0, 2, BOMB_WIDTH, BOMB_HEIGHT, 0, BOMB_BITMAP ); + bombs->add( bomb ); + } + break; + } + + vdp_cursor_tab( 0, 0 ); + printf( "Score: %04d\n", score ); + for ( int w = 0; w < 2; w++ ) { + bullets->next_step(); + bombs->next_step(); + for ( int b = 0; b < BARRIER_NUM; b++ ) { + bombs->hit( barrier[b] ); + bullets->hit( barrier[b] ); + } + wait_cnt( 50 ); + } + } + } +} + +static int bullets_visible = 1; + +static KEY_EVENT prev_key_event = { 0 }; + +void key_event_handler( KEY_EVENT key_event ) +{ + if ( key_event.key_data == prev_key_event.key_data ) return; + prev_key_event = key_event; + + if ( key_event.code == 0x7d ) { // Exit program if esc key pressed + vdp_cursor_enable( true ); + exit( 1 ); + } + + Bullet *b; + Coords b_vec; + Coords b_pos; + + if ( key_event.down ) // If key has just been pressed + switch ( key_event.code ) { + case 0x01: // Space - fire bullet + b_vec = ship->get_dir_vec(); + b_pos = ship->get_centre(); + b = new Bullet( b_pos.x + b_vec.x*3 , b_pos.y + b_vec.y*3, b_vec.x, b_vec.y, + BULLET_WIDTH, BULLET_HEIGHT, 0, BULLET_BITMAP ); + bullets->add( b ); + break; + case 0x2f: + ship->rot_ac_wise(); // 'z' - rotate ship anticlockwise + break; + case 0x2d: + ship->rot_c_wise(); // 'x' - rotate ship clockwise + break; + + // Debug stuff + + case 0x1d: // 'h' - toggle hiding of ship + if ( ship->is_visible() ) { + ship->hide(); + } + else ship->show(); + if ( bullets_visible ) { + bullets->hide(); + aliens->hide(); + } + else { + bullets->show(); + aliens->show(); + } + bullets_visible = 1 - bullets_visible; + break; + case 0x19: // 'd' - print debug info + aliens->dump(); +// aliens->elem(0,5)->dump(); +// Sprite::debug(); +// printf( "Ship: " ); ship->dump(); +// printf( "Bullets:-\n" ); bullets->dump(); +// printf( "Alien[0,0]: "); alien.elem(0,0)->dump(); +// ship->hit( aliens ); // Check if aliens hit by ship +// printf( "Collision: %d\n", ship->collide( alien[0] ) ); + +// vdp_cursor_tab( 0, 0 ); +// barrier->is_hit( ship ); +/* + Tile *hit; + if ( (hit = barrier->hit( ship->get_centre() )) ) { + printf( "Hit tile.\n "); + hit->set_bitmap( 254 ); + hit->draw(); + } +*/ + break; + } + +/* Debug info for key pressed bit table + + vdp_cursor_tab( 0, 0 ); +// printf( "Modifier %02x, key-code %02x, up/down %02x\n", +// key_event.mods, key_event.code, key_event.down ); + for ( int i = 31; i >= 0; i-- ) printf( "%02x", vdp_key_bits[i] ); + return; +*/ +} + +void wait_cnt( int cnt ) +{ + for ( int c = 0; c < cnt; c++ ) vdp_update_key_state(); +} + +void wait_tick() +{ + long tick = sv->time & 0x02; // Get bit 2 of time which toggles every vblank + + do { + vdp_update_key_state(); + } while ( (sv->time & 0x02) == tick ); +}