From 0733de55c52a880beefee220731ffb690ee0630a Mon Sep 17 00:00:00 2001 From: pcawte Date: Thu, 17 Aug 2023 10:45:01 +0700 Subject: [PATCH] Sprite C++ library & demo added --- README.md | 12 + include/Sprite/Coords.hpp | 15 + include/Sprite/DummySpriteGroup.hpp | 28 ++ include/Sprite/RotSprite.hpp | 57 +++ include/Sprite/Sprite.hpp | 147 +++++++ include/Sprite/SpriteArray.hpp | 81 ++++ include/Sprite/SpriteGroup.hpp | 63 +++ include/Sprite/SpriteList.hpp | 43 ++ include/Sprite/Tile.hpp | 80 ++++ include/{ => agon}/vdp_key.h | 0 include/{ => agon}/vdp_vdu.h | 0 sprite-demos/invaders/README.md | 11 + sprite-demos/invaders/bitmaps/gal-red0.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/gal-red1.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/gal-red2.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/gal-red3.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship00.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship01.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship02.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship03.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship04.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship05.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship06.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship07.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship08.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship09.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship10.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship11.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship12.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship13.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship14.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship15.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship16.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship17.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship18.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship19.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship20.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship21.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship22.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/bitmaps/ship23.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/img-src/Galaxian.png | Bin 0 -> 7299 bytes sprite-demos/invaders/img-src/Galaxian1.png | Bin 0 -> 1171 bytes sprite-demos/invaders/img-src/Galaxian10.png | Bin 0 -> 1174 bytes sprite-demos/invaders/img-src/Galaxian11.png | Bin 0 -> 1178 bytes sprite-demos/invaders/img-src/Galaxian12.png | Bin 0 -> 1176 bytes sprite-demos/invaders/img-src/Galaxian13.png | Bin 0 -> 1171 bytes sprite-demos/invaders/img-src/Galaxian14.png | Bin 0 -> 1174 bytes sprite-demos/invaders/img-src/Galaxian15.png | Bin 0 -> 1173 bytes sprite-demos/invaders/img-src/Galaxian16.png | Bin 0 -> 1175 bytes sprite-demos/invaders/img-src/Galaxian17.png | Bin 0 -> 1176 bytes sprite-demos/invaders/img-src/Galaxian18.png | Bin 0 -> 1179 bytes sprite-demos/invaders/img-src/Galaxian19.png | Bin 0 -> 1181 bytes sprite-demos/invaders/img-src/Galaxian2.png | Bin 0 -> 1174 bytes sprite-demos/invaders/img-src/Galaxian20.png | Bin 0 -> 1180 bytes sprite-demos/invaders/img-src/Galaxian21.png | Bin 0 -> 1179 bytes sprite-demos/invaders/img-src/Galaxian22.png | Bin 0 -> 1174 bytes sprite-demos/invaders/img-src/Galaxian23.png | Bin 0 -> 1178 bytes sprite-demos/invaders/img-src/Galaxian24.png | Bin 0 -> 1176 bytes sprite-demos/invaders/img-src/Galaxian25.png | Bin 0 -> 1171 bytes sprite-demos/invaders/img-src/Galaxian26.png | Bin 0 -> 1174 bytes sprite-demos/invaders/img-src/Galaxian27.png | Bin 0 -> 1173 bytes sprite-demos/invaders/img-src/Galaxian28.png | Bin 0 -> 1175 bytes sprite-demos/invaders/img-src/Galaxian29.png | Bin 0 -> 1176 bytes sprite-demos/invaders/img-src/Galaxian3.png | Bin 0 -> 1173 bytes sprite-demos/invaders/img-src/Galaxian30.png | Bin 0 -> 1179 bytes sprite-demos/invaders/img-src/Galaxian31.png | Bin 0 -> 1180 bytes sprite-demos/invaders/img-src/Galaxian32.png | Bin 0 -> 1180 bytes sprite-demos/invaders/img-src/Galaxian33.png | Bin 0 -> 1179 bytes sprite-demos/invaders/img-src/Galaxian34.png | Bin 0 -> 1174 bytes sprite-demos/invaders/img-src/Galaxian35.png | Bin 0 -> 1202 bytes sprite-demos/invaders/img-src/Galaxian36.png | Bin 0 -> 1198 bytes sprite-demos/invaders/img-src/Galaxian37.png | Bin 0 -> 1192 bytes sprite-demos/invaders/img-src/Galaxian38.png | Bin 0 -> 1190 bytes sprite-demos/invaders/img-src/Galaxian39.png | Bin 0 -> 1188 bytes sprite-demos/invaders/img-src/Galaxian4.png | Bin 0 -> 1175 bytes sprite-demos/invaders/img-src/Galaxian40.png | Bin 0 -> 1182 bytes sprite-demos/invaders/img-src/Galaxian41.png | Bin 0 -> 1182 bytes sprite-demos/invaders/img-src/Galaxian42.png | Bin 0 -> 1180 bytes sprite-demos/invaders/img-src/Galaxian43.png | Bin 0 -> 1171 bytes sprite-demos/invaders/img-src/Galaxian49.png | Bin 0 -> 1200 bytes sprite-demos/invaders/img-src/Galaxian5.png | Bin 0 -> 1176 bytes sprite-demos/invaders/img-src/Galaxian50.png | Bin 0 -> 1188 bytes sprite-demos/invaders/img-src/Galaxian6.png | Bin 0 -> 1179 bytes sprite-demos/invaders/img-src/Galaxian7.png | Bin 0 -> 1181 bytes sprite-demos/invaders/img-src/Galaxian8.png | Bin 0 -> 1180 bytes sprite-demos/invaders/img-src/Galaxian9.png | Bin 0 -> 1179 bytes .../invaders/img-src/bitmaps/gal-red0.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/gal-red1.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/gal-red2.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/gal-red3.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship00.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship01.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship02.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship03.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship04.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship05.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship06.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship07.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship08.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship09.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship10.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship11.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship12.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship13.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship14.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship15.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship16.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship17.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship18.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship19.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship20.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship21.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship22.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/bitmaps/ship23.rgba | Bin 0 -> 1024 bytes .../img-src/gal-explode/Galaxian52.png | Bin 0 -> 1196 bytes .../img-src/gal-explode/Galaxian53.png | Bin 0 -> 1179 bytes .../img-src/gal-explode/Galaxian54.png | Bin 0 -> 1199 bytes .../img-src/gal-explode/Galaxian55.png | Bin 0 -> 1208 bytes .../img-src/gal-explode/gal-explode00.rgba | Bin 0 -> 1024 bytes .../img-src/gal-explode/gal-explode01.rgba | Bin 0 -> 1024 bytes .../img-src/gal-explode/gal-explode02.rgba | Bin 0 -> 1024 bytes .../img-src/gal-explode/gal-explode03.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/img-src/gal-red0.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/img-src/gal-red1.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/img-src/gal-red2.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/img-src/gal-red3.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/Galaxian37.png | Bin 0 -> 1171 bytes .../invaders/img-src/ship/Galaxian38.png | Bin 0 -> 1185 bytes .../invaders/img-src/ship/Galaxian39.png | Bin 0 -> 1181 bytes .../invaders/img-src/ship/Galaxian40.png | Bin 0 -> 1186 bytes .../invaders/img-src/ship/Galaxian41.png | Bin 0 -> 1190 bytes .../invaders/img-src/ship/Galaxian42.png | Bin 0 -> 1188 bytes .../invaders/img-src/ship/Galaxian43.png | Bin 0 -> 1186 bytes .../invaders/img-src/ship/Galaxian44.png | Bin 0 -> 1187 bytes .../invaders/img-src/ship/Galaxian45.png | Bin 0 -> 1188 bytes .../invaders/img-src/ship/Galaxian46.png | Bin 0 -> 1181 bytes .../invaders/img-src/ship/Galaxian47.png | Bin 0 -> 1184 bytes .../invaders/img-src/ship/Galaxian48.png | Bin 0 -> 1178 bytes .../invaders/img-src/ship/Galaxian49.png | Bin 0 -> 1171 bytes .../invaders/img-src/ship/Galaxian50.png | Bin 0 -> 1183 bytes .../invaders/img-src/ship/Galaxian51.png | Bin 0 -> 1184 bytes .../invaders/img-src/ship/Galaxian52.png | Bin 0 -> 1180 bytes .../invaders/img-src/ship/Galaxian53.png | Bin 0 -> 1190 bytes .../invaders/img-src/ship/Galaxian54.png | Bin 0 -> 1189 bytes .../invaders/img-src/ship/Galaxian55.png | Bin 0 -> 1192 bytes .../invaders/img-src/ship/Galaxian56.png | Bin 0 -> 1190 bytes .../invaders/img-src/ship/Galaxian57.png | Bin 0 -> 1188 bytes .../invaders/img-src/ship/Galaxian58.png | Bin 0 -> 1182 bytes .../invaders/img-src/ship/Galaxian59.png | Bin 0 -> 1182 bytes .../invaders/img-src/ship/Galaxian60.png | Bin 0 -> 1180 bytes .../invaders/img-src/ship/ship00.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship01.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship02.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship03.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship04.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship05.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship06.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship07.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship08.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship09.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship10.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship11.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship12.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship13.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship14.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship15.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship16.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship17.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship18.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship19.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship20.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship21.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship22.rgba | Bin 0 -> 1024 bytes .../invaders/img-src/ship/ship23.rgba | Bin 0 -> 1024 bytes sprite-demos/invaders/makefile | 20 + sprite-demos/invaders/src/Alien.cpp | 88 ++++ sprite-demos/invaders/src/Alien.hpp | 45 +++ sprite-demos/invaders/src/Bomb.cpp | 40 ++ sprite-demos/invaders/src/Bomb.hpp | 26 ++ sprite-demos/invaders/src/Bullet.cpp | 41 ++ sprite-demos/invaders/src/Bullet.hpp | 27 ++ sprite-demos/invaders/src/Ship.cpp | 95 +++++ sprite-demos/invaders/src/Ship.hpp | 30 ++ .../invaders/src/Sprite/RotSprite.cpp | 69 ++++ sprite-demos/invaders/src/Sprite/Sprite.cpp | 382 ++++++++++++++++++ .../invaders/src/Sprite/SpriteArray.cpp | 155 +++++++ .../invaders/src/Sprite/SpriteGroup.cpp | 118 ++++++ .../invaders/src/Sprite/SpriteList.cpp | 64 +++ sprite-demos/invaders/src/Sprite/Tile.cpp | 166 ++++++++ sprite-demos/invaders/src/barrier.cpp | 25 ++ sprite-demos/invaders/src/barrier.hpp | 7 + sprite-demos/invaders/src/config.hpp | 108 +++++ sprite-demos/invaders/src/main.cpp | 216 ++++++++++ 193 files changed, 2259 insertions(+) create mode 100644 include/Sprite/Coords.hpp create mode 100644 include/Sprite/DummySpriteGroup.hpp create mode 100644 include/Sprite/RotSprite.hpp create mode 100644 include/Sprite/Sprite.hpp create mode 100644 include/Sprite/SpriteArray.hpp create mode 100644 include/Sprite/SpriteGroup.hpp create mode 100644 include/Sprite/SpriteList.hpp create mode 100644 include/Sprite/Tile.hpp rename include/{ => agon}/vdp_key.h (100%) rename include/{ => agon}/vdp_vdu.h (100%) create mode 100644 sprite-demos/invaders/README.md create mode 100644 sprite-demos/invaders/bitmaps/gal-red0.rgba create mode 100644 sprite-demos/invaders/bitmaps/gal-red1.rgba create mode 100644 sprite-demos/invaders/bitmaps/gal-red2.rgba create mode 100644 sprite-demos/invaders/bitmaps/gal-red3.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship00.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship01.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship02.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship03.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship04.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship05.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship06.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship07.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship08.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship09.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship10.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship11.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship12.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship13.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship14.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship15.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship16.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship17.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship18.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship19.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship20.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship21.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship22.rgba create mode 100644 sprite-demos/invaders/bitmaps/ship23.rgba create mode 100644 sprite-demos/invaders/img-src/Galaxian.png create mode 100644 sprite-demos/invaders/img-src/Galaxian1.png create mode 100644 sprite-demos/invaders/img-src/Galaxian10.png create mode 100644 sprite-demos/invaders/img-src/Galaxian11.png create mode 100644 sprite-demos/invaders/img-src/Galaxian12.png create mode 100644 sprite-demos/invaders/img-src/Galaxian13.png create mode 100644 sprite-demos/invaders/img-src/Galaxian14.png create mode 100644 sprite-demos/invaders/img-src/Galaxian15.png create mode 100644 sprite-demos/invaders/img-src/Galaxian16.png create mode 100644 sprite-demos/invaders/img-src/Galaxian17.png create mode 100644 sprite-demos/invaders/img-src/Galaxian18.png create mode 100644 sprite-demos/invaders/img-src/Galaxian19.png create mode 100644 sprite-demos/invaders/img-src/Galaxian2.png create mode 100644 sprite-demos/invaders/img-src/Galaxian20.png create mode 100644 sprite-demos/invaders/img-src/Galaxian21.png create mode 100644 sprite-demos/invaders/img-src/Galaxian22.png create mode 100644 sprite-demos/invaders/img-src/Galaxian23.png create mode 100644 sprite-demos/invaders/img-src/Galaxian24.png create mode 100644 sprite-demos/invaders/img-src/Galaxian25.png create mode 100644 sprite-demos/invaders/img-src/Galaxian26.png create mode 100644 sprite-demos/invaders/img-src/Galaxian27.png create mode 100644 sprite-demos/invaders/img-src/Galaxian28.png create mode 100644 sprite-demos/invaders/img-src/Galaxian29.png create mode 100644 sprite-demos/invaders/img-src/Galaxian3.png create mode 100644 sprite-demos/invaders/img-src/Galaxian30.png create mode 100644 sprite-demos/invaders/img-src/Galaxian31.png create mode 100644 sprite-demos/invaders/img-src/Galaxian32.png create mode 100644 sprite-demos/invaders/img-src/Galaxian33.png create mode 100644 sprite-demos/invaders/img-src/Galaxian34.png create mode 100644 sprite-demos/invaders/img-src/Galaxian35.png create mode 100644 sprite-demos/invaders/img-src/Galaxian36.png create mode 100644 sprite-demos/invaders/img-src/Galaxian37.png create mode 100644 sprite-demos/invaders/img-src/Galaxian38.png create mode 100644 sprite-demos/invaders/img-src/Galaxian39.png create mode 100644 sprite-demos/invaders/img-src/Galaxian4.png create mode 100644 sprite-demos/invaders/img-src/Galaxian40.png create mode 100644 sprite-demos/invaders/img-src/Galaxian41.png create mode 100644 sprite-demos/invaders/img-src/Galaxian42.png create mode 100644 sprite-demos/invaders/img-src/Galaxian43.png create mode 100644 sprite-demos/invaders/img-src/Galaxian49.png create mode 100644 sprite-demos/invaders/img-src/Galaxian5.png create mode 100644 sprite-demos/invaders/img-src/Galaxian50.png create mode 100644 sprite-demos/invaders/img-src/Galaxian6.png create mode 100644 sprite-demos/invaders/img-src/Galaxian7.png create mode 100644 sprite-demos/invaders/img-src/Galaxian8.png create mode 100644 sprite-demos/invaders/img-src/Galaxian9.png create mode 100644 sprite-demos/invaders/img-src/bitmaps/gal-red0.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/gal-red1.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/gal-red2.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/gal-red3.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship00.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship01.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship02.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship03.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship04.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship05.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship06.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship07.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship08.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship09.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship10.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship11.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship12.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship13.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship14.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship15.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship16.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship17.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship18.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship19.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship20.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship21.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship22.rgba create mode 100644 sprite-demos/invaders/img-src/bitmaps/ship23.rgba create mode 100644 sprite-demos/invaders/img-src/gal-explode/Galaxian52.png create mode 100644 sprite-demos/invaders/img-src/gal-explode/Galaxian53.png create mode 100644 sprite-demos/invaders/img-src/gal-explode/Galaxian54.png create mode 100644 sprite-demos/invaders/img-src/gal-explode/Galaxian55.png create mode 100644 sprite-demos/invaders/img-src/gal-explode/gal-explode00.rgba create mode 100644 sprite-demos/invaders/img-src/gal-explode/gal-explode01.rgba create mode 100644 sprite-demos/invaders/img-src/gal-explode/gal-explode02.rgba create mode 100644 sprite-demos/invaders/img-src/gal-explode/gal-explode03.rgba create mode 100644 sprite-demos/invaders/img-src/gal-red0.rgba create mode 100644 sprite-demos/invaders/img-src/gal-red1.rgba create mode 100644 sprite-demos/invaders/img-src/gal-red2.rgba create mode 100644 sprite-demos/invaders/img-src/gal-red3.rgba create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian37.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian38.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian39.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian40.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian41.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian42.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian43.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian44.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian45.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian46.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian47.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian48.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian49.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian50.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian51.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian52.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian53.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian54.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian55.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian56.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian57.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian58.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian59.png create mode 100644 sprite-demos/invaders/img-src/ship/Galaxian60.png create mode 100644 sprite-demos/invaders/img-src/ship/ship00.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship01.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship02.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship03.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship04.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship05.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship06.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship07.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship08.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship09.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship10.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship11.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship12.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship13.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship14.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship15.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship16.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship17.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship18.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship19.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship20.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship21.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship22.rgba create mode 100644 sprite-demos/invaders/img-src/ship/ship23.rgba create mode 100644 sprite-demos/invaders/makefile create mode 100644 sprite-demos/invaders/src/Alien.cpp create mode 100644 sprite-demos/invaders/src/Alien.hpp create mode 100644 sprite-demos/invaders/src/Bomb.cpp create mode 100644 sprite-demos/invaders/src/Bomb.hpp create mode 100644 sprite-demos/invaders/src/Bullet.cpp create mode 100644 sprite-demos/invaders/src/Bullet.hpp create mode 100644 sprite-demos/invaders/src/Ship.cpp create mode 100644 sprite-demos/invaders/src/Ship.hpp create mode 100644 sprite-demos/invaders/src/Sprite/RotSprite.cpp create mode 100644 sprite-demos/invaders/src/Sprite/Sprite.cpp create mode 100644 sprite-demos/invaders/src/Sprite/SpriteArray.cpp create mode 100644 sprite-demos/invaders/src/Sprite/SpriteGroup.cpp create mode 100644 sprite-demos/invaders/src/Sprite/SpriteList.cpp create mode 100644 sprite-demos/invaders/src/Sprite/Tile.cpp create mode 100644 sprite-demos/invaders/src/barrier.cpp create mode 100644 sprite-demos/invaders/src/barrier.hpp create mode 100644 sprite-demos/invaders/src/config.hpp create mode 100644 sprite-demos/invaders/src/main.cpp 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 0000000000000000000000000000000000000000..cee2eb76661e1298050185c8955a162140f5b79e GIT binary patch literal 1024 zcmeHDK@Pwm2;-l7`ELBgt&Ey##Owi*kV0wEV0L140XJ*liKutssi%fLapu_*q5GTk zR2X|a_a#=^&R=)4%r7K_J>(2di#-8PGvcjdtfVw!eSM*>?qa>Sisq_<(8q9Z*{sI9^Dniyb5tn|=^9|OXVl|4)qB{E6#b}rL3V@mlV%3Q6)?9GV+OKX tWH!uhWSZEpz-A6%z0~kOsu|>j9W33z{6N^<*i=B=0W%9iV^cS9VgMldjrRZm literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship01.rgba b/sprite-demos/invaders/bitmaps/ship01.rgba new file mode 100644 index 0000000000000000000000000000000000000000..d7498fa97afb76c5252202d88bca3b25bd1d99c5 GIT binary patch literal 1024 zcmd6lQ4WA03`2J^FYhV%<0hD9X{Zx3=Z`KSz}V{=!0hkQh8ai2E15QWH_<>o3unRU z$S6Hm4(ok`hx^caR%s4=rU6bF_9gp-U-gbUtXa?3yQ}v#lfx$xy|qYD62~?lk6%FZ literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship03.rgba b/sprite-demos/invaders/bitmaps/ship03.rgba new file mode 100644 index 0000000000000000000000000000000000000000..06b57c201819073ba787ea0190e974449b13b227 GIT binary patch literal 1024 zcmds#Q3}8y3`2XeU4EzV&zo!uB_x6h%Jws%7;E#aXvBX;t#Ro#<nS065N~$#do`?E}R^3RoewL2t=98Z=Y`b R-}dxif{~3c7+DW%`U?;TnTh}a literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship05.rgba b/sprite-demos/invaders/bitmaps/ship05.rgba new file mode 100644 index 0000000000000000000000000000000000000000..c3d62c0e0357ecd8010c9ef6617058e5bd2f4331 GIT binary patch literal 1024 zcmdUsOA5ds3`BFXUcRSr=S?gj3^OW9z%E)r@-c4`)$E(AR%<7dy}?tXq-P;xM&J32 zMrqD~gC8+8b~@yhRewE4=xgnL#VnfJ@ml9Tc(=aeKXH%ociA8HYWwQd8!)ddd-p1H ML>^~(7R0~o1NkqQ!2kdN literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship06.rgba b/sprite-demos/invaders/bitmaps/ship06.rgba new file mode 100644 index 0000000000000000000000000000000000000000..3f589f81ded07d8587c8622ca7239ad3b181c9e1 GIT binary patch literal 1024 zcmdsy(FwpX2t=K%%XfTtK{L3uFb#>n>@Pfco!k+lks-ke2cwm)kAK*Rt1 GFS`Lg-i`MF literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship07.rgba b/sprite-demos/invaders/bitmaps/ship07.rgba new file mode 100644 index 0000000000000000000000000000000000000000..a77f3d3b367deefb93cfd294b277b617d8257a45 GIT binary patch literal 1024 zcmd6iOAf#w2t++uFW*zR^CoSOyuetK{x-T9KpqUGtp8do#~+v9_}X_G`<^#8`0(zv z$j1n-_MLgRd*FZM$d!Z7iZ2M&E5C1kKQo-4-4Wi5fkWX<=N@z>GqMJ&y?TRZnX@>0 O?pb=3qxzhOSXoa7d6x44 literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship08.rgba b/sprite-demos/invaders/bitmaps/ship08.rgba new file mode 100644 index 0000000000000000000000000000000000000000..c20b42f0a51c6479805d103fcf9bc20f266639c5 GIT binary patch literal 1024 zcmdUrQ4WA03`2J^FYhV%<0k5CnpJcP;Y$_1MCF5~jaBtT59<8$0mC^iNKPEcEMO{YdWOsO;p&ry{ abl)@TUr*wVuJzvCx9@z?44Y4#J=p;VMw&?g literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship09.rgba b/sprite-demos/invaders/bitmaps/ship09.rgba new file mode 100644 index 0000000000000000000000000000000000000000..db0d0aaaf9e8cb93cbe9511fe6bd4bc05951f1c0 GIT binary patch literal 1024 zcmds#Q3`-C3`2V|FYhV*+fCFGLW;)e{1GgSc57eTz#{%;%NpShbhZ|I{>s2*O+BoB z!;+zAud~nDusWMDbI_)ni{?rD*BCo!j$`wU3_W)k;T=25XOCl_C;FW(&A!*~c>O7# M?Z4t*^=rP#Zh*$0Z2$lO literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship10.rgba b/sprite-demos/invaders/bitmaps/ship10.rgba new file mode 100644 index 0000000000000000000000000000000000000000..6d30ed3875f1344daf0e098d56261f568227916c GIT binary patch literal 1024 zcmd6kK@Pwm2n2muKi^mM=1*)0nQTH4O;4H_VBJA#TRU|< zqUOaz#1m`u81L(Qzp>FbtKlt@%d0u1DT9GyX1||zl|N={J`#DI_3{6j`zv*K_Pht* MT)$h*=BFp9FRuQXiU0rr literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship11.rgba b/sprite-demos/invaders/bitmaps/ship11.rgba new file mode 100644 index 0000000000000000000000000000000000000000..3efc1d865330fd045a827b9fdeeb0f9692e69503 GIT binary patch literal 1024 zcmZQz7>wZNe+C8^CdGX)JvaY9c));U21uNE0Md&M6Kld@J52qg=tb8L(~ImTm>4<@ y(u<6d^?=yu>XG^6>LbPsQsWaj3`o@ra}Uh#5dAPwVrfKLB3(aBFR^wFoH_taq?o|~ literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship12.rgba b/sprite-demos/invaders/bitmaps/ship12.rgba new file mode 100644 index 0000000000000000000000000000000000000000..472ae16cfa69b8b0a6dcd6a803c519038d78f2be GIT binary patch literal 1024 zcmZQz7;NC?e+CA0Ou8E%JYe__!U(fSGvlxwL_axZfb=5kC&dixdWmy8OfNDG3kP%> qmx(aF$m(&a#U+m23|O4v(uFDxG6UuYa^jGDy)bto)2MD6PCNi0MUD3W literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship13.rgba b/sprite-demos/invaders/bitmaps/ship13.rgba new file mode 100644 index 0000000000000000000000000000000000000000..682b71139535b2d0e83a962f8d8642d09e2f4eb6 GIT binary patch literal 1024 zcmd6lK?(pN2t_?vm!DI#>n05%kNJxrb2bTLNdG^j%x;W6%{>1E9@KNMF>HEPW_em@ zKYeZ=*OBnE9_W;fM|OMlsQ93V8?y&})mzO~;i`{vf}i~Z-0Sl0^pvnWqw#uoycV98 A^8f$< literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship14.rgba b/sprite-demos/invaders/bitmaps/ship14.rgba new file mode 100644 index 0000000000000000000000000000000000000000..a1344f75ff750e35026992d380f60ceb33c0be90 GIT binary patch literal 1024 zcmd6k(G9>L2t=8z%XbR@+{A{^R}$1p+K<+RoZ#IdD)Q%5nux}mg~xNBTIIY)-ecdS zX{eUS%z`dz{SNnUvDU9=pf_IDo4$EHbAvdH(S6~A@MBKhQ9a7_-tZOSP$TcrJnXOH OzGu%XKF^%<{mB6{B$`P8 literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship15.rgba b/sprite-demos/invaders/bitmaps/ship15.rgba new file mode 100644 index 0000000000000000000000000000000000000000..934b37310e85ccc8c9f9a30068ccab5ef2cd2e3d GIT binary patch literal 1024 zcmZQz7z*I#e+C8+rUX!C#)Ah8P&W{E$6-5$|Hv4m7lw)P2TU(a4>C=xevlrJImmiJ zY*O@NGXuANM7W^a39%OzcL;Sb5eN;5A6$A-%|O+O;9)ldCQphP5Pw3l)ci(Jgt?|W~NiTRqxPnDNn_brm)dkv@>hYZ8}w0*y_4@RrE8a*@H SyGHC|c6)dJ&BIRhto{ItA(@H* literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship17.rgba b/sprite-demos/invaders/bitmaps/ship17.rgba new file mode 100644 index 0000000000000000000000000000000000000000..11cd35347ea59c7154b1e54de0429fbbbcf31c14 GIT binary patch literal 1024 zcmdszT?&9O41;$vFYhV#wwoxSl&1CvhCVr%)GS}38{@z0JjNCOZYElEf#q$EiuXFR zIrX067?Oat0r8?xvT1j+rnP^6=h0?;!=AiiIeA9*`J3Ov z#d_!SJE=a$@JuvSv!vzA9G&sl9K2VaAGx{%`sU~}tn}c62aJgK*`KH!;2cB89a*ntaYynqu3QBx JJ(W85IUnpBnTh}a literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/bitmaps/ship23.rgba b/sprite-demos/invaders/bitmaps/ship23.rgba new file mode 100644 index 0000000000000000000000000000000000000000..4c79b15f0d578181115142dcec7630f6513dad4e GIT binary patch literal 1024 zcmZQz7z*I#e+C8+CI!Isz-UtRg4Evp|KI@w7?Y|K;#P$I!*&cLxE6q#uTf zbqlh7Qp~`o51&7f^}*bTEJh9Y!^|Z_BioD2CZrEl9+qw(@d%4k%F-dK4TFIP05lz# A!2kdN literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian.png b/sprite-demos/invaders/img-src/Galaxian.png new file mode 100644 index 0000000000000000000000000000000000000000..10b8d3cd3702e335fa3bf8a276fcab6bcff2c934 GIT binary patch literal 7299 zcmeI1cQBma+y7TdmIOhR)uIzglvUO$(R&L^qW4}_h%Q><(V73b|yR-!8>Qe0Ln!PPIH#fJP|5N_sf&WV$*hpINxZMx2n~LGBC2Re= z;%&-Rwcj>^JQWQ*bzj?g`dGfP1-Mx{x_a`t+Iq4G^MUz9Y?KXdqYQMUsvxW9Yqn#I z^k-;@^TK8Q;@bFqA^kf?I%LTKo2n-PKiKI*5R&1M+e1HW7y6wYUi@4gAHchD{aI@E z=%HmAqOfy3OXE@jU$B*O6oO{6>bZTL*Q~@VV4vY~*QC;rnfAG~q$1i7234(;VA=^3 zj`-w;ri$qW=XDCH8MBO43FUozMQ7Ih(VH>XI*&Tf?Nc zOJ&v5ybitV+-uImViRr=zNuy9#1Kmi4RnnU8@iA;*Faw8>sHI?C-+_@4UT!{PT8y8Ka97lx zp2Bu2G1m4mW1=80MV75;+2!Jaq%60ezmP6xw{sRHGvXxAsj&f91eC`5;A z$32^NqkxOBhY-jP5Pq8Sw_8N^{~>g$kjBC5tR)S`BgzhE+{7; z=fw@KBgGPCOEtW>x&LYR1)S(BZ6#rYPY^w6%V(nW`J|*MhtYYS)p&XqC|{^wdUPf5 z8Jh-TKd7McKD_8(MSj_@(?j1;#B8mSb-kqt#YA0QRV4)wegJgO*LDD-#>LlkNFQc5XN3L34KoLj&eTJJ2hq$zA=D zaDG8QI7p-_UCq&HlE};WklSMCoKuKcL^z6v7h_@4Wlk;^9ZF0s7hCLdgBmHH-x;8F zdPj{Pgo$!PT#_&DkZ%SEvdIMUmmut_uOd5jZBDO_*7N%=H4WndPV>;q%o2pUbm@=eUu^08i`A!34HY3Pp~-SYknL!tb;$*J{B= zxTzyWY+4Z~%Uw17a7BL5s_J+|dcEhiRqTsiMI(bCi?z0>?W+)S@lXa4^6 z`a^l-SkVNU_nSzfo$cp{tEoZ}O0=d!Cz6q$=Xf&vqZ>UPwt%O)(Ez2!5Z`700W#ws zKyff?5QA)s6NeQVobje+jfgHQxmIkJ{$*7Qc~HNvfodGh#;nmn)|c< zQM`^>{<4L{(KWRLCv(UZvyJvW6`#AKd(n;B>RFl8a>>T9bC9M*1}t*sG>k z1GkU>lz}n4C#O%lF=CK{JS1sj=WGmvD&torRirdgO%$kvrEz{>xj5Pqy+pkX_ncra zE|KIuV+m?JXh?f~PaY#`63$iFi(OwHH{uN)jD<#e-`uYlHkY1b!_&KAQH!ZF%u9cP zIG5dGu#b2md+>q5GsH`gaVz2?`|ebNx^~L<;E+MR5oyNN3;4$@(Fc&N2eyAob2QmJEKwrpOxf?o~fV2qOkk zQRE-7jL8sJW%^alt0apX;l!QvDDP~_6R5QJ8GdkZbQ4>IWHz}2-O29eIIKk8ujmq@ zD+tl9Z&05FgvN}qy2omhMFs%3eIssHK4M~-@Bsuy9oZA7g$ThV_@YohUU!o-Uu&pE z%kqF3c2UR?_kEvi)|b*AJGUcxsBa{ej=323mD+c7>&O(Le%r@HgaIVi<&fIGh7k;M z8n3QeQDDj1?ML$u`i{~sxTWJe*@pc9cLz2vXFaY7#u4}s-Z=!xbOOJDTHG|QN zEX2o2XxuvmZR7HYO7<=gL8$`s;=#=nV`&z~)M^i&2K=EFW1YgIXB1Ha29QAD*FoLG z{-L%S>A#FJu zqWIT{?l0IZ$|`I4UDGr=6ILy==d2w277bWCIHl~ zu)KQ)d!J8YRQPw1DAJyYF9)wiZ!gxsN-qr;Ab1O5oP{yY>}PowaJ5chnoOcYSJ$a@ zaNurKa&iz0q`Em3hP@FOV`sIiW2b9NMH^VUhj%Wda|URq{)bk;rSi z5nk%;*1}EFZh3}y&2Ku4`~wU)mp!{bZIm;m099S7c+$OK&~m}oTGjy^OWc^=O3#Bs z3f8N%T<{ijZmA3ut7vNJki<~{A```hRD*vSTzYOwpRiEJb4ku7sD5pzgwD%emuoSg zTG-dwkr!T#3jRN6qrbM}4CEg3bNQgF@YRf+?ZZeAP#NYFz1X2MtZx4VcK8K#oS+U1l#k4jsbX5)p2m8b^C5TSweLXTa`jloF+~R z@B_p=!&p}^~FrW-_qwpplxe^8W;iGj-ZsDkr4?wy->7hQIMX_M_ z|DspCx3T&SHFTic>T?tm=vX{dC{Dchgaz*ZbzgXaAN|E1#{M9hnQ!*Jn!3rY1Q}~b z_pfou*0mkm7cF6U=Sxd5)n0E3#oNbDKQcYi@qZL`c<{r`{=Bhmv_8F2VsTtUNCR=E4fY2l5uQer%q9;IO7 zG5{k(@DuA#WO0mU>s{v9Bh8QQf|jK?G09)!B^5Ls-Tt5Vvc~L zk0?rt?7M$>z#wFxAO|COycyBj$kdP`Z&ELDqgr) zx0&AYS#EfSU>tOmix@rladnn;%)fn27nM_!eJANMtLQ1BA4e~VPHS*`vP7NjnAJa# zv3RazW~G!3~XN`DiPRtem#BlmN5jcqOa|0t4qGU z$MGT%^|ichZ)yRF*BShWcctQ4B3Q>T#*(Dy`9~T$iUz}{ppBe5eUiHt2H*#BlNlxq zUsIlxG^NfbsqEMnguz`lD&3esbUCj#v-PJ4*Ql-$qrRuLVozlWrmz;B-AfFKGQ1rn zXi7J$?Z7N?z8!F!+5k|pj29or!mPxR@vKij6(MNUNAt{X_bqQ7Yc&X)AVcGS;^W)e zyp{g~{M@}|4EsTFaA%I{VV7#zN=r={S*rU4BpvS94UHBbX*ilUQy$(G{RQU^30mKt z+{k|Y>>&wOV7j9=S|_&bM~u>xU8>k|Kzu!8ZY^tKMkXE&(o!A#L^=b~SUEPZ?ycWJ zI3O@;h*pUGoM;C2#~q4)g(PY7F4GD$dogP&T~O7$7&*Sk|J}b&$0C~EwSq!}Xk&jj zq-R`5vkqufhkBkvXYh39mQvtlNOR}g183fP3Ef}2NHj!~Z{xsuH$jWJN0wpBKFfjK z#bU=R7$J5O{7l0Bx&oL0ZD2CPY`Qm~?#NEWwb)Z0kfun=^^kZ&BmJPq3qX#&T( zuy0mk>IlZczI|@ZsS^#ayp@n|@0*ywa5RGsSkQ*&vO;ePgk}Iz9m9i{wTve8uomKv zdM9R;JPz*WP+uz>j8cy#mH#w8?anoHL2+Ydy}Sqixa)9M?Jar3bNC{}f73{46dU3i zf305fTbJajXdH4m>@t{MT-GfRF`lCp6N{KDqaF6@G z$dMLj0E=h}%(AkAMtNoXq)v7S#^LVP@O}X)qgRDY9Cd$q)|U|OSKX@dPO5NZVtA|P=o9&!7+rxV!L{GRolJ+=*$7?#&6P2T*@i{EV5-Vs zXeNw1Htb2DAd|-3I1t-MsknbbB8Tq245=Q#A4(d;GbH?+=?qzZsw9IH1=(>tT!w=7 zwpu1Im%ryC+f}}Ni?rVlSZiZ$ex55GJQNt+5uA9_gd8?xv(B%+MWOXpoL7*|wdR$; z*mLI!5J`Kb)uZtLRtaIyf0;piR?5Qd47&a?h4}KrpYe3fw`zjH*%uYCGPim?<@Uy~kw`5jFIL(@Fz* z80|-1!g-004fBOA)5jWH}$lur#QAzWb-QYji`~Z+!6_cObtUum1f#2j}Dtr;^m$cE1@8RtPX=M3Cb{) zqWA(eUupQ4tKJMeNI}>zNw-^g65j*d8?}2nmC!p$kF9@SKbx0*oehVgi=_DAD=B1l zPpzXc&x(1xI-$j5+~XZKO9<9miKR1i^+NK=)J-G=n8MOXikwvgoo($W8XMZXInnTr zSi9InE#}AuOEI4%I3_vd`yMQ`sVXB4)6NL)-$=Lm!0GX74a3x+)LuHaa%J-+TwOzMpWp&4?yQt#OqtA1K!6zhLE#K$K4NxR@$lm+~jtZb*T)NLTx ziru;5i<d%>M_jgt|q1{lWJ z^i0^HWnPbvZ4UN1&ig_D1QtObtl$XKtMpOa`=Z0&X9{3v`@@t-P``RcPvVX0 z@~*>H-GZm3jO({!Dua*sv9{$H^$czccWzt|P-T9yiCTrPl<7wO+@k6p%-!m#@Dqx| zq3P*t!3XbdzGeb0V8g>-ng9wUAxFSz$Buu$WO&P@nV6_S37_*h z#)#*B4bAgXsI1yNs~4RI5|PVe`zW-|PjXVJxS4feZuUz`wbS>SP0DYOhYt27igE*8 zi}#)bKKCy#puev;v@02>+xmK2=1tqlxovz!q$m3kC34QAkXd(Doy}hH`f1&|r8|Z> zE00^v^LFL8weG-OToymuVC?8NPYS=ZI-!5j7Ngat!STkC!iDOnwVzY{mAKTTetldt zZyR~8d~C8G{n=z89=we|@B3oFpT3VXXQhwX%u)J{Uq`lVe?-)PVaBFKGiMu2Lgh~g zPiR6Q~K;fFRa3ZmZK^DuE~u6E}1I~LA#z-&-gIO#Q}4RYj7 zWskB(+QXjy>DSi%(+X)keUvv)WA;2_%h{^#;fkAI0&j(w`M^Qb`$V-9O5LZ{g0pFR z&ucE9z4SK)^}cE0JCx4IT1kKvEDiOTQbcvuIS#DO&RZV9%sVsc**2Z>3ypd?4d#}h zzEwR0Z5kKufeSfVSFQK!odh>z{>U>J0-??P-(ajsw8^1~0nWyjaGOI#ZjCP)9J1^& z6W-x$i?qzz2MCymTj|bp@|yLW`y1CbVyVD$Y2oxBHF;Vok-z^0sVZtIl*?I!{uhC# BXtn?V literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian1.png b/sprite-demos/invaders/img-src/Galaxian1.png new file mode 100644 index 0000000000000000000000000000000000000000..591f909186edda7b4bf8a90ce771d551b22da3a3 GIT binary patch literal 1171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u`BYlflGZ?JJHwjovJP2;gWZR`H@$Nu@W*h^S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ubP0 Hl+XkKvP3)r literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian12.png b/sprite-demos/invaders/img-src/Galaxian12.png new file mode 100644 index 0000000000000000000000000000000000000000..acf0c0a27d86bfcd8384a90e6d452ebb08a46980 GIT binary patch literal 1176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uxC%O7lUWdkJ-Pgg&ebxsLQ E0N8jq;s5{u literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian13.png b/sprite-demos/invaders/img-src/Galaxian13.png new file mode 100644 index 0000000000000000000000000000000000000000..2f9f5b6769d54b2a65fbde0662251e50c61c074b GIT binary patch literal 1171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u3Qm)#Np}c=d#Wzp$Pzn C6FIH` literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian15.png b/sprite-demos/invaders/img-src/Galaxian15.png new file mode 100644 index 0000000000000000000000000000000000000000..90f1e8747b2ecf3303ff451f3050a857d6ab7042 GIT binary patch literal 1173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ubQBS%=CFnhAdFKJ=aV_IgpfQKRA38Vfpt~g-%!oc9^>gTe~DWM4f DZE`vZ literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian16.png b/sprite-demos/invaders/img-src/Galaxian16.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e4b600a5653b269512b8d1093ee58ba708b96c GIT binary patch literal 1175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uHjhK7tk9fS_DYbG{yH)QfjGy@Bsg))r#4)!Jipw!{%>gTe~DWM4f D(aAYO literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian17.png b/sprite-demos/invaders/img-src/Galaxian17.png new file mode 100644 index 0000000000000000000000000000000000000000..d0a62e84320fd29595e59e53a028e8a92cd27b46 GIT binary patch literal 1176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ut<8 literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian18.png b/sprite-demos/invaders/img-src/Galaxian18.png new file mode 100644 index 0000000000000000000000000000000000000000..94392d86acc383aeead4aaa04c48e8881ec5ce1a GIT binary patch literal 1179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@um(=4j$|iVEp8$b;EMP*@q2GBF-}|=%zb~9~4M9AfO<`z_2xjQGf9%rDvcN;_2$= Jvd$@?2>_lrKtccj literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian19.png b/sprite-demos/invaders/img-src/Galaxian19.png new file mode 100644 index 0000000000000000000000000000000000000000..f737d87818fc1ed33728eb16802a2300d72b538e GIT binary patch literal 1181 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u4wREp;Ts2{OA`}0`e^*i%&Q4&A?(S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u>qlygN{!8OOjdy^K-+|4LbP0l+XkK D)oMGN literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian23.png b/sprite-demos/invaders/img-src/Galaxian23.png new file mode 100644 index 0000000000000000000000000000000000000000..9c91eed5be42da00335b3103072bf309e4bb5f59 GIT binary patch literal 1178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uO5w;p5B)S~C_fIWRnF)|errHbIEZLO#u?>_7(_n+F4fXfxyNO+n@XKtmWjUHx3v IIVCg!0L3dj2mk;8 literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian24.png b/sprite-demos/invaders/img-src/Galaxian24.png new file mode 100644 index 0000000000000000000000000000000000000000..6cf5d15c2131bfc31a7f133ac580de07f14424eb GIT binary patch literal 1176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uKr+p literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian26.png b/sprite-demos/invaders/img-src/Galaxian26.png new file mode 100644 index 0000000000000000000000000000000000000000..8697f3e435fabc8ad2f49158aa60d9b18e561526 GIT binary patch literal 1174 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ua64^mV2EKj zlFIHRCNZCLT@$Ak1B-)QN0VkElV)PW=Z9ezf#pv82ZqJ>UUlk#5{IX&pUXO@geCxx Ce>(^O literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian27.png b/sprite-demos/invaders/img-src/Galaxian27.png new file mode 100644 index 0000000000000000000000000000000000000000..46ce89c87001e6547ab261dfde914c77deab71de GIT binary patch literal 1173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ubQBS%=CFnhAdFKJ=aV_FuufQLcn0K@w2i#7tw6$S=RS3j3^P6S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uC zC{w1u(ru`4WWpB%Lqo=&4nhanH4_`U8#2Wtnt=sR)DMRBUoI4aiXaA0S3j3^P6S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u) literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian3.png b/sprite-demos/invaders/img-src/Galaxian3.png new file mode 100644 index 0000000000000000000000000000000000000000..61ad351d830b72d4b717df239b5e119d7306af7f GIT binary patch literal 1173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uqg{+vx$vNBF-}|=%zb~9~4M9AfO<`z>xBTVfECz3co-p#M9N! JWt~$(69BNWK?VQ- literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian31.png b/sprite-demos/invaders/img-src/Galaxian31.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1cde593f7d145a1b1e3f3a5a88980a028ea8a5 GIT binary patch literal 1180 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@umdK II;Vst03`@Jr~m)} literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian33.png b/sprite-demos/invaders/img-src/Galaxian33.png new file mode 100644 index 0000000000000000000000000000000000000000..17f0126acfb711b90035c6b990aa6de89aef50e3 GIT binary patch literal 1179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uFVdQ I&MBb@0KGCh_5c6? literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian34.png b/sprite-demos/invaders/img-src/Galaxian34.png new file mode 100644 index 0000000000000000000000000000000000000000..f22bc2e451c1a0b3625378f6474e4d49e6b724ab GIT binary patch literal 1174 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ugTe~DWM4f D>peUR literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian35.png b/sprite-demos/invaders/img-src/Galaxian35.png new file mode 100644 index 0000000000000000000000000000000000000000..eb2e3341706164cef83b9706b9b345089e1fa8d8 GIT binary patch literal 1202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uWSvVG7T{d&!{N3-%o{3+X!g)n5?D@(|J4zVtH1IL3KF%)DEf>kx d*w1WlEytYAEbvt2?>tbV@pScbS?83{1ORfvN*n+H literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian37.png b/sprite-demos/invaders/img-src/Galaxian37.png new file mode 100644 index 0000000000000000000000000000000000000000..873596439c79caa8fb4b42412541da56e256393f GIT binary patch literal 1192 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u_{pA literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian38.png b/sprite-demos/invaders/img-src/Galaxian38.png new file mode 100644 index 0000000000000000000000000000000000000000..1aab58c70b83926378ed0f6b647a9472fa1c38f1 GIT binary patch literal 1190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uvqFxokqjbeMkMC{GGQss&;<(183&@IgHz@ S%Dt9>l8UFRpUXO@geCwhl14iK literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian4.png b/sprite-demos/invaders/img-src/Galaxian4.png new file mode 100644 index 0000000000000000000000000000000000000000..99f573e932efee572b811a60b886e41bcd220b09 GIT binary patch literal 1175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uC zD5Iyq(ru`4WWpB%V`Ju@4nhanH4_`U8#2oznt=t+jHisMZ|bvEK&ivi)z4*}Q$iB} D*;6{v literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian40.png b/sprite-demos/invaders/img-src/Galaxian40.png new file mode 100644 index 0000000000000000000000000000000000000000..f4b9cde350eb26770daaaf7353107541aaf8fa2a GIT binary patch literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uUdlsDVte>&h$eCeZ=A#vQbM)qDEwSj*R6JYjzwS!T!SwYfnO>PHN2&k- literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian41.png b/sprite-demos/invaders/img-src/Galaxian41.png new file mode 100644 index 0000000000000000000000000000000000000000..cd7ac61f5795773d202316900e2e943f92d964bf GIT binary patch literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uSV1_{rlF6O(aj z=Z+f}e#GSDoN$U+p%kDe-NdbCuyw)5KwY+7-QApr*RuR!V`jKz!?;&KjfDl2L_A&n KT-G@yGywoEm_Zu= literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian43.png b/sprite-demos/invaders/img-src/Galaxian43.png new file mode 100644 index 0000000000000000000000000000000000000000..b4ec53095ff858a595ea42e3f6875eb83bf4d0d7 GIT binary patch literal 1171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@umdKI;Vst0CnU& AdH?_b literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian49.png b/sprite-demos/invaders/img-src/Galaxian49.png new file mode 100644 index 0000000000000000000000000000000000000000..790365d7c5bf526b5548a71cb19e7b226321529f GIT binary patch literal 1200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@udQRUD8<4Ylx#d*{an^LB{Ts5?VU=J literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian5.png b/sprite-demos/invaders/img-src/Galaxian5.png new file mode 100644 index 0000000000000000000000000000000000000000..1810b5d962ee4beb143e7e523e45fab6e3f80759 GIT binary patch literal 1176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u^gtJE#Bv literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian50.png b/sprite-demos/invaders/img-src/Galaxian50.png new file mode 100644 index 0000000000000000000000000000000000000000..704494c5727f8b5b88bf771d6d1009ab7c483bfd GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uElvF%j{an^LB{Ts5^Pogp literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian6.png b/sprite-demos/invaders/img-src/Galaxian6.png new file mode 100644 index 0000000000000000000000000000000000000000..b438b48382ef569db227b050eaca7e7b7624e519 GIT binary patch literal 1179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uE?o(-OlXHcFO5HL!JqEYP76X3*Nd(?ct-W1zJy1XB=?eVs9#WP=V1i>*vYipfuv? L>gTe~DWM4fWZgs9 literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian8.png b/sprite-demos/invaders/img-src/Galaxian8.png new file mode 100644 index 0000000000000000000000000000000000000000..741f8587ebf730d5f0e00df8ef3667c706ce3f69 GIT binary patch literal 1180 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u__sK1~1s literal 0 HcmV?d00001 diff --git a/sprite-demos/invaders/img-src/Galaxian9.png b/sprite-demos/invaders/img-src/Galaxian9.png new file mode 100644 index 0000000000000000000000000000000000000000..767054f57eb1294ef40adab92d67e907e774baaf GIT binary patch literal 1179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uQQ=^KTHCA>$Du41_v5z?)AZNYAq%Nt#o7*>`snzMb*eg{e+p00i_ I>zopr08vywqyPW_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..cee2eb76661e1298050185c8955a162140f5b79e GIT binary patch literal 1024 zcmeHDK@Pwm2;-l7`ELBgt&Ey##Owi*kV0wEV0L140XJ*liKutssi%fLapu_*q5GTk zR2X|a_a#=^&R=)4%r7K_J>(2di#-8PGvcjdtfVw!eSM*>?qa>Sisq_<(8q9Z*{sI9^Dniyb5tn|=^9|OXVl|4)qB{E6#b}rL3V@mlV%3Q6)?9GV+OKX tWH!uhWSZEpz-A6%z0~kOsu|>j9W33z{6N^<*i=B=0W%9iV^cS9VgMldjrRZm literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d7498fa97afb76c5252202d88bca3b25bd1d99c5 GIT binary patch literal 1024 zcmd6lQ4WA03`2J^FYhV%<0hD9X{Zx3=Z`KSz}V{=!0hkQh8ai2E15QWH_<>o3unRU z$S6Hm4(ok`hx^caR%s4=rU6bF_9gp-U-gbUtXa?3yQ}v#lfx$xy|qYD62~?lk6%FZ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..06b57c201819073ba787ea0190e974449b13b227 GIT binary patch literal 1024 zcmds#Q3}8y3`2XeU4EzV&zo!uB_x6h%Jws%7;E#aXvBX;t#Ro#<nS065N~$#do`?E}R^3RoewL2t=98Z=Y`b R-}dxif{~3c7+DW%`U?;TnTh}a literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c3d62c0e0357ecd8010c9ef6617058e5bd2f4331 GIT binary patch literal 1024 zcmdUsOA5ds3`BFXUcRSr=S?gj3^OW9z%E)r@-c4`)$E(AR%<7dy}?tXq-P;xM&J32 zMrqD~gC8+8b~@yhRewE4=xgnL#VnfJ@ml9Tc(=aeKXH%ociA8HYWwQd8!)ddd-p1H ML>^~(7R0~o1NkqQ!2kdN literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3f589f81ded07d8587c8622ca7239ad3b181c9e1 GIT binary patch literal 1024 zcmdsy(FwpX2t=K%%XfTtK{L3uFb#>n>@Pfco!k+lks-ke2cwm)kAK*Rt1 GFS`Lg-i`MF literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a77f3d3b367deefb93cfd294b277b617d8257a45 GIT binary patch literal 1024 zcmd6iOAf#w2t++uFW*zR^CoSOyuetK{x-T9KpqUGtp8do#~+v9_}X_G`<^#8`0(zv z$j1n-_MLgRd*FZM$d!Z7iZ2M&E5C1kKQo-4-4Wi5fkWX<=N@z>GqMJ&y?TRZnX@>0 O?pb=3qxzhOSXoa7d6x44 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c20b42f0a51c6479805d103fcf9bc20f266639c5 GIT binary patch literal 1024 zcmdUrQ4WA03`2J^FYhV%<0k5CnpJcP;Y$_1MCF5~jaBtT59<8$0mC^iNKPEcEMO{YdWOsO;p&ry{ abl)@TUr*wVuJzvCx9@z?44Y4#J=p;VMw&?g literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..db0d0aaaf9e8cb93cbe9511fe6bd4bc05951f1c0 GIT binary patch literal 1024 zcmds#Q3`-C3`2V|FYhV*+fCFGLW;)e{1GgSc57eTz#{%;%NpShbhZ|I{>s2*O+BoB z!;+zAud~nDusWMDbI_)ni{?rD*BCo!j$`wU3_W)k;T=25XOCl_C;FW(&A!*~c>O7# M?Z4t*^=rP#Zh*$0Z2$lO literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6d30ed3875f1344daf0e098d56261f568227916c GIT binary patch literal 1024 zcmd6kK@Pwm2n2muKi^mM=1*)0nQTH4O;4H_VBJA#TRU|< zqUOaz#1m`u81L(Qzp>FbtKlt@%d0u1DT9GyX1||zl|N={J`#DI_3{6j`zv*K_Pht* MT)$h*=BFp9FRuQXiU0rr literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3efc1d865330fd045a827b9fdeeb0f9692e69503 GIT binary patch literal 1024 zcmZQz7>wZNe+C8^CdGX)JvaY9c));U21uNE0Md&M6Kld@J52qg=tb8L(~ImTm>4<@ y(u<6d^?=yu>XG^6>LbPsQsWaj3`o@ra}Uh#5dAPwVrfKLB3(aBFR^wFoH_taq?o|~ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..472ae16cfa69b8b0a6dcd6a803c519038d78f2be GIT binary patch literal 1024 zcmZQz7;NC?e+CA0Ou8E%JYe__!U(fSGvlxwL_axZfb=5kC&dixdWmy8OfNDG3kP%> qmx(aF$m(&a#U+m23|O4v(uFDxG6UuYa^jGDy)bto)2MD6PCNi0MUD3W literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..682b71139535b2d0e83a962f8d8642d09e2f4eb6 GIT binary patch literal 1024 zcmd6lK?(pN2t_?vm!DI#>n05%kNJxrb2bTLNdG^j%x;W6%{>1E9@KNMF>HEPW_em@ zKYeZ=*OBnE9_W;fM|OMlsQ93V8?y&})mzO~;i`{vf}i~Z-0Sl0^pvnWqw#uoycV98 A^8f$< literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a1344f75ff750e35026992d380f60ceb33c0be90 GIT binary patch literal 1024 zcmd6k(G9>L2t=8z%XbR@+{A{^R}$1p+K<+RoZ#IdD)Q%5nux}mg~xNBTIIY)-ecdS zX{eUS%z`dz{SNnUvDU9=pf_IDo4$EHbAvdH(S6~A@MBKhQ9a7_-tZOSP$TcrJnXOH OzGu%XKF^%<{mB6{B$`P8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..934b37310e85ccc8c9f9a30068ccab5ef2cd2e3d GIT binary patch literal 1024 zcmZQz7z*I#e+C8+rUX!C#)Ah8P&W{E$6-5$|Hv4m7lw)P2TU(a4>C=xevlrJImmiJ zY*O@NGXuANM7W^a39%OzcL;Sb5eN;5A6$A-%|O+O;9)ldCQphP5Pw3l)ci(Jgt?|W~NiTRqxPnDNn_brm)dkv@>hYZ8}w0*y_4@RrE8a*@H SyGHC|c6)dJ&BIRhto{ItA(@H* literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..11cd35347ea59c7154b1e54de0429fbbbcf31c14 GIT binary patch literal 1024 zcmdszT?&9O41;$vFYhV#wwoxSl&1CvhCVr%)GS}38{@z0JjNCOZYElEf#q$EiuXFR zIrX067?Oat0r8?xvT1j+rnP^6=h0?;!=AiiIeA9*`J3Ov z#d_!SJE=a$@JuvSv!vzA9G&sl9K2VaAGx{%`sU~}tn}c62aJgK*`KH!;2cB89a*ntaYynqu3QBx JJ(W85IUnpBnTh}a literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4c79b15f0d578181115142dcec7630f6513dad4e GIT binary patch literal 1024 zcmZQz7z*I#e+C8+CI!Isz-UtRg4Evp|KI@w7?Y|K;#P$I!*&cLxE6q#uTf zbqlh7Qp~`o51&7f^}*bTEJh9Y!^|Z_BioD2CZrEl9+qw(@d%4k%F-dK4TFIP05lz# A!2kdN literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9d870e38f082d96ba9271787f652e86d4b9a5783 GIT binary patch literal 1196 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uh zYXO4-WzC0doC`A;RyzbS7%_Xc%x27Cn8YP8U-oQVi2DRKhP9U%!&RdB&x2Bkr>mdK II;Vst04+E@4FCWD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7609b6a9f3361905e061012d7919ac0c55969e3c GIT binary patch literal 1199 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uVDV~%JSD$+yt+?lX?wWhAd&6ecG0!SS jp8M(}l{`+df8f04{tX@hE5*lC9tY3&e4ic_N58AyUGDiV literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..70dd974fbb75d80c2ec9089b34a59f297926d773 GIT binary patch literal 1024 zcmeH@-3fp&41}|slXsD9qI}B1aiGLU!9bfP_mj}7Kl}%}YNuXnJF~E?)ql!uUV1f!ti;#A_mzIX#({6aF!7FU&LrF-AU-qnme*JotyOV4+B_6C8?osj?l literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fcb6cb49a80399028cc10ce8835a2b765998e94e GIT binary patch literal 1024 zcma)(Q4Yf}2t#wZo;;`6A2-?Z+PLz(L@QEcFgA3o_v77Wbj!to)!M1q_2H#KpHb5< zK5KZN;d{`!-t%GmiF&XrP1=W7PnzCd*KZ#v-Q8Qi$?br7K_J>(2di#-8PGvcjdtfVw!eSM*>?qa>Sisq_<(8q9Z*{sI9^Dniyb5tn|=^9|OXS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@umdKI;Vst0CnU& AdH?_b literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b7e2cac692cf15a164a6b3564085e0ac6ef0e54b GIT binary patch literal 1185 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@ul=3oPg; zQ0z8v6e(zoOkh-K=k0hP<-p`1Xu_yx7Q$#|mcpo}XEI&Ul3_WA90LREcgBkz4xRHs O3B}XZ&t;ucLK6V$Bs!D; literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7e0efb0410e280ae0cda801817fb889ea05eb286 GIT binary patch literal 1190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uM552cl*DdLHqET+iHx!{7Ib{z-DXiFKbP_K@^_zBFnxZ- VxVfi0b_*!6c)I$ztaD0e0sux4N#y_l literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9a775f3a8e72094f74194967a909a8bec979d086 GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u@%g0Gm;WMrY4Xle^1?Nk>(P7;C TbP0l+XkK^g>DF literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a9042d58724e1030d180bc7a9bfe303f950c8ea7 GIT binary patch literal 1186 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u17 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..817a5bec8b7be0e795eae0bd4cb6e3a404fe950a GIT binary patch literal 1188 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u_G04YKc^y3Kfj!?EhFjH~U$53;lG{5it>MTBwt TLb?0{prqpI>gTe~DWM4fS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u&SS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uNaAiT^LnV!G8y0?aWLxxUrokPr1NkQy82&F|+}l`tuN#y=JYD@< J);T3K0RRhZMUwyk literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4dc340d9c073fe87cac38ec11365462eb875b0a6 GIT binary patch literal 1171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uOqSkOrav yhDeq(?i16QxfNY5h9=Bv%;er>yS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uF_}jRqzUB>_8e<}R)fMFa5^gBXrjZV$ejVha}UxFFN^(65Gp;p!R2wH%ggR{#J2 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8b5901db9c3601ae94ae291b6364030c9cc58f60 GIT binary patch literal 1184 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uJ?1p-l~`-bU<-p+4FC%PZ_SyW85Baa)${h OnRvSTxvXS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uTs- literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fa28388d7b068f1f3e4d84df0a5cad677a846571 GIT binary patch literal 1189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uH91Xn>lNc0RI0EGEX11^vFfzQ|!niju S)ldYKRyS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@u_{pA literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1aab58c70b83926378ed0f6b647a9472fa1c38f1 GIT binary patch literal 1190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uvqFxokqjbeMkMC{GGQss&;<(183&@IgHz@ S%Dt9>l8UFRpUXO@geCwhl14iK literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f4b9cde350eb26770daaaf7353107541aaf8fa2a GIT binary patch literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uUdlsDVte>&h$eCeZ=A#vQbM)qDEwSj*R6JYjzwS!T!SwYfnO>PHN2&k- literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..cd7ac61f5795773d202316900e2e943f92d964bf GIT binary patch literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6zM9{GlNlJ883KGl zT!G>S1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uS1_lfaHyNUDGPF)%IDGT49m4|#hE|4~hZ$}@c))P@uSV1_{rlF6O(aj z=Z+f}e#GSDoN$U+p%kDe-NdbCuyw)5KwY+7-QApr*RuR!V`jKz!?;&KjfDl2L_A&n KT-G@yGywoEm_Zu= literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7a884d08ffd9a1184f1588d0f76dcefa6d1dc47f GIT binary patch literal 1024 zcmZQz7|!74e+CA0Ossz)`W`%B_z%Lw>Vl|4)qB{E6#b}rL3V@mlV%3Q6)?9GV+OKX tWH!uhWSZEpz-A6%z0~kOsu|>j9W33z{6N^<*i=B=0W%9iV^cS9VgMldjrRZm literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d7498fa97afb76c5252202d88bca3b25bd1d99c5 GIT binary patch literal 1024 zcmd6lQ4WA03`2J^FYhV%<0hD9X{Zx3=Z`KSz}V{=!0hkQh8ai2E15QWH_<>o3unRU z$S6Hm4(ok`hx^caR%s4=rU6bF_9gp-U-gbUtXa?3yQ}v#lfx$xy|qYD62~?lk6%FZ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..06b57c201819073ba787ea0190e974449b13b227 GIT binary patch literal 1024 zcmds#Q3}8y3`2XeU4EzV&zo!uB_x6h%Jws%7;E#aXvBX;t#Ro#<nS065N~$#do`?E}R^3RoewL2t=98Z=Y`b R-}dxif{~3c7+DW%`U?;TnTh}a literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c3d62c0e0357ecd8010c9ef6617058e5bd2f4331 GIT binary patch literal 1024 zcmdUsOA5ds3`BFXUcRSr=S?gj3^OW9z%E)r@-c4`)$E(AR%<7dy}?tXq-P;xM&J32 zMrqD~gC8+8b~@yhRewE4=xgnL#VnfJ@ml9Tc(=aeKXH%ociA8HYWwQd8!)ddd-p1H ML>^~(7R0~o1NkqQ!2kdN literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3f589f81ded07d8587c8622ca7239ad3b181c9e1 GIT binary patch literal 1024 zcmdsy(FwpX2t=K%%XfTtK{L3uFb#>n>@Pfco!k+lks-ke2cwm)kAK*Rt1 GFS`Lg-i`MF literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a77f3d3b367deefb93cfd294b277b617d8257a45 GIT binary patch literal 1024 zcmd6iOAf#w2t++uFW*zR^CoSOyuetK{x-T9KpqUGtp8do#~+v9_}X_G`<^#8`0(zv z$j1n-_MLgRd*FZM$d!Z7iZ2M&E5C1kKQo-4-4Wi5fkWX<=N@z>GqMJ&y?TRZnX@>0 O?pb=3qxzhOSXoa7d6x44 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..c20b42f0a51c6479805d103fcf9bc20f266639c5 GIT binary patch literal 1024 zcmdUrQ4WA03`2J^FYhV%<0k5CnpJcP;Y$_1MCF5~jaBtT59<8$0mC^iNKPEcEMO{YdWOsO;p&ry{ abl)@TUr*wVuJzvCx9@z?44Y4#J=p;VMw&?g literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..db0d0aaaf9e8cb93cbe9511fe6bd4bc05951f1c0 GIT binary patch literal 1024 zcmds#Q3`-C3`2V|FYhV*+fCFGLW;)e{1GgSc57eTz#{%;%NpShbhZ|I{>s2*O+BoB z!;+zAud~nDusWMDbI_)ni{?rD*BCo!j$`wU3_W)k;T=25XOCl_C;FW(&A!*~c>O7# M?Z4t*^=rP#Zh*$0Z2$lO literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6d30ed3875f1344daf0e098d56261f568227916c GIT binary patch literal 1024 zcmd6kK@Pwm2n2muKi^mM=1*)0nQTH4O;4H_VBJA#TRU|< zqUOaz#1m`u81L(Qzp>FbtKlt@%d0u1DT9GyX1||zl|N={J`#DI_3{6j`zv*K_Pht* MT)$h*=BFp9FRuQXiU0rr literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3efc1d865330fd045a827b9fdeeb0f9692e69503 GIT binary patch literal 1024 zcmZQz7>wZNe+C8^CdGX)JvaY9c));U21uNE0Md&M6Kld@J52qg=tb8L(~ImTm>4<@ y(u<6d^?=yu>XG^6>LbPsQsWaj3`o@ra}Uh#5dAPwVrfKLB3(aBFR^wFoH_taq?o|~ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..472ae16cfa69b8b0a6dcd6a803c519038d78f2be GIT binary patch literal 1024 zcmZQz7;NC?e+CA0Ou8E%JYe__!U(fSGvlxwL_axZfb=5kC&dixdWmy8OfNDG3kP%> qmx(aF$m(&a#U+m23|O4v(uFDxG6UuYa^jGDy)bto)2MD6PCNi0MUD3W literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..682b71139535b2d0e83a962f8d8642d09e2f4eb6 GIT binary patch literal 1024 zcmd6lK?(pN2t_?vm!DI#>n05%kNJxrb2bTLNdG^j%x;W6%{>1E9@KNMF>HEPW_em@ zKYeZ=*OBnE9_W;fM|OMlsQ93V8?y&})mzO~;i`{vf}i~Z-0Sl0^pvnWqw#uoycV98 A^8f$< literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a1344f75ff750e35026992d380f60ceb33c0be90 GIT binary patch literal 1024 zcmd6k(G9>L2t=8z%XbR@+{A{^R}$1p+K<+RoZ#IdD)Q%5nux}mg~xNBTIIY)-ecdS zX{eUS%z`dz{SNnUvDU9=pf_IDo4$EHbAvdH(S6~A@MBKhQ9a7_-tZOSP$TcrJnXOH OzGu%XKF^%<{mB6{B$`P8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..934b37310e85ccc8c9f9a30068ccab5ef2cd2e3d GIT binary patch literal 1024 zcmZQz7z*I#e+C8+rUX!C#)Ah8P&W{E$6-5$|Hv4m7lw)P2TU(a4>C=xevlrJImmiJ zY*O@NGXuANM7W^a39%OzcL;Sb5eN;5A6$A-%|O+O;9)ldCQphP5Pw3l)ci(Jgt?|W~NiTRqxPnDNn_brm)dkv@>hYZ8}w0*y_4@RrE8a*@H SyGHC|c6)dJ&BIRhto{ItA(@H* literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..11cd35347ea59c7154b1e54de0429fbbbcf31c14 GIT binary patch literal 1024 zcmdszT?&9O41;$vFYhV#wwoxSl&1CvhCVr%)GS}38{@z0JjNCOZYElEf#q$EiuXFR zIrX067?Oat0r8?xvT1j+rnP^6=h0?;!=AiiIeA9*`J3Ov z#d_!SJE=a$@JuvSv!vzA9G&sl9K2VaAGx{%`sU~}tn}c62aJgK*`KH!;2cB89a*ntaYynqu3QBx JJ(W85IUnpBnTh}a literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4c79b15f0d578181115142dcec7630f6513dad4e GIT binary patch literal 1024 zcmZQz7z*I#e+C8+CI!Isz-UtRg4Evp|KI@w7?Y|K;#P$I!*&cLxE6q#uTf zbqlh7Qp~`o51&7f^}*bTEJh9Y!^|Z_BioD2CZrEl9+qw(@d%4k%F-dK4TFIP05lz# A!2kdN literal 0 HcmV?d00001 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 ); +}