diff --git a/assets/heart.si2 b/assets/heart.si2 new file mode 100644 index 0000000..b95a095 Binary files /dev/null and b/assets/heart.si2 differ diff --git a/assets/img2si.py b/assets/img2si.py new file mode 100644 index 0000000..b593695 --- /dev/null +++ b/assets/img2si.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +from array import array +from PIL import Image +import argparse +import io +import os + + +__author__ = "Kuruyia" +__version__ = "1.0.0" +__license__ = "MIT" + +# The "Simple Image for Space Invaders" (.si2) file format specifications +# Authors: Alexandre "Kuruyia" SOLLIER, Marc AMBAUD (2019 - 2020) +# +# | Address | Length | Description | +# |---------|--------|-------------------------------------| +# | 0x00 | 2 | Magic number ("SI") | +# | 0x02 | 4 | Header magic number ("HEAD") | +# | 0x06 | 2 | File version | +# | 0x08 | 4 | Pixel count | +# | 0x0C | 4 | Image width | +# | 0x10 | 4 | Data magic number ("DATA") | +# | 0x14 | ??? | Uncompressed image data as RGBA8888 | +# "File version", "Pixel count" and "Image width" entries are little-endian, unsigned numbers. + + +def is_file_si2(filePath): + # Check the magic number + with open(filePath, 'rb') as file: + return file.read(2) == b'SI' + + +def convert_from_si2(source, output): + # Print summary + print('Source image: .si2') + _, outExtension = os.path.splitext(output) + print('Output image: {}'.format(outExtension)) + + # Read si2 image data + with open(source, 'rb') as file: + file.seek(0x08) + pixelCount = int.from_bytes(file.read(4), byteorder='little', signed=False) + lineSize = int.from_bytes(file.read(4), byteorder='little', signed=False) + imageSize = (lineSize, int(pixelCount/lineSize)) + file.seek(0x14) + imageData = file.read() + + # Print summary 2: Electric Boogaloo + print('Image size is {}x{}'.format(imageSize[0], imageSize[1])) + print() + print('Starting conversion...') + + # Save the converted image + img = Image.frombytes('RGBA', imageSize, imageData) + img.save(output) + + +def convert_to_si2(source, output): + # Print summary + _, outExtension = os.path.splitext(source) + print('Source image: {}'.format(outExtension)) + print('Output image: .si2') + + # Read source image + with Image.open(source) as img: + imageSize = img.size + + if img.mode != 'RGBA': + # Convert image mode if unsupported + print('Source image mode "{}" is unsupported, attempting conversion...'.format(img.mode)) + + imgConvt = img.convert('RGBA') + imageData = imgConvt.load() + else: + imageData = img.load() + + # Print summary 2: Electric Boogaloo + print('Image size is {}x{}'.format(imageSize[0], imageSize[1])) + print() + print('Starting conversion...') + + # Convert the image + with open(output, 'wb') as file: + file.write(b'SIHEAD\01\00') + file.write((imageSize[0]*imageSize[1]).to_bytes(4, byteorder='little')) + file.write((imageSize[0]).to_bytes(4, byteorder='little')) + file.write(b'DATA') + + for y in range(0, imageSize[1]): + for x in range(0, imageSize[0]): + file.write(bytes(imageData[x, y])) + + +def main(): + # Setup argument parser + parser = argparse.ArgumentParser(description='This tool converts images compatible with PIL to the minGL 2 Simple Image format (.si2), and vice versa.') + parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0') + parser.add_argument('', help='The path to the image to convert. A .si2 will be converted to a .png file. Any other image type will be converted to a .si2 file.') + parser.add_argument('', help='The path to output the converted image to.') + + args = vars(parser.parse_args()) + source = args[''] + output = args[''] + + # Check that source file exists + if not os.path.isfile(source): + exit('"{}"\nThe specified path does not exist.'.format(source)) + + # Check if source file is in the .si2 format + isSourceSi2 = is_file_si2(source) + + if isSourceSi2: + convert_from_si2(source, output) + else: + convert_to_si2(source, output) + + print('Done!') + + # with Image.open(source) as img: + # for y in range(0, img.height): + # for x in range(0, img.width): + # print(img.getpixel((x, y))) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/assets/missile.si2 b/assets/missile.si2 new file mode 100644 index 0000000..7453eaf Binary files /dev/null and b/assets/missile.si2 differ diff --git a/assets/player.si2 b/assets/player.si2 index e5de91b..783906d 100644 Binary files a/assets/player.si2 and b/assets/player.si2 differ diff --git a/assets/player2.png b/assets/player2.png new file mode 100644 index 0000000..d1d1e8e Binary files /dev/null and b/assets/player2.png differ diff --git a/assets/player2.si2 b/assets/player2.si2 new file mode 100644 index 0000000..8614921 Binary files /dev/null and b/assets/player2.si2 differ diff --git a/config.yml b/config.yml index 7ea2523..45b9b24 100644 --- a/config.yml +++ b/config.yml @@ -14,7 +14,7 @@ # general: maxFPS: 30 - theme: + theme: good ############################# diff --git a/headers/pixelManager/goodPixelManager.h b/headers/pixelManager/goodPixelManager.h index 7223dc8..0a412fe 100644 --- a/headers/pixelManager/goodPixelManager.h +++ b/headers/pixelManager/goodPixelManager.h @@ -58,6 +58,19 @@ class GoodPixelManager : public PixelManager{ * @brief sprite of the torpedo */ MySprite torpedo; + + /*! + * @brief sprite of the heart + */ + MySprite heart; + + void drawInvaderA(const Position& baseVector, unsigned size, const RGBAcolor& color) const override; + void drawInvaderB(const Position& baseVector, unsigned size, const RGBAcolor& color) const override; + void drawInvaderC(const Position& baseVector, unsigned size, const RGBAcolor& color) const override; + void drawPlayer(unsigned x, unsigned width, const RGBAcolor& color) const override; + void drawMissile(const Position& baseVector, unsigned width, const RGBAcolor& color) const override; + void drawTorpedo(const Position& baseVector, unsigned width, const RGBAcolor& color) const override; + void drawHeart(const Position& baseVector) const override; public: /*! diff --git a/headers/pixelManager/pixelManager.h b/headers/pixelManager/pixelManager.h index d84ef80..3112225 100644 --- a/headers/pixelManager/pixelManager.h +++ b/headers/pixelManager/pixelManager.h @@ -98,7 +98,7 @@ public: * @param[in] color : color multiplicaror of the invader * @fn void drawInvaderA(const Position& baseVector, unsigned size, const RGBAcolor& color) const; */ - void drawInvaderA(const Position& baseVector, unsigned size, const RGBAcolor& color) const; + virtual void drawInvaderA(const Position& baseVector, unsigned size, const RGBAcolor& color) const; /*! * @brief display a type B invader on screen @@ -107,7 +107,7 @@ public: * @param[in] color : color multiplicaror of the invader * @fn void drawInvaderB(const Position& baseVector, unsigned size, const RGBAcolor& color) const; */ - void drawInvaderB(const Position& baseVector, unsigned size, const RGBAcolor& color) const; + virtual void drawInvaderB(const Position& baseVector, unsigned size, const RGBAcolor& color) const; /*! * @brief display a type C invader on screen @@ -116,7 +116,7 @@ public: * @param[in] color : color multiplicaror of the invader * @fn void drawInvaderC(const Position& baseVector, unsigned size, const RGBAcolor& color) const; */ - void drawInvaderC(const Position& baseVector, unsigned size, const RGBAcolor& color) const; + virtual void drawInvaderC(const Position& baseVector, unsigned size, const RGBAcolor& color) const; /*! * @brief display a player on screen @@ -125,7 +125,7 @@ public: * @param[in] color : color of the plater * @fn void drawPlayer(unsigned x, unsigned width, const nsGraphics::RGBAcolor& color) const; */ - void drawPlayer(unsigned x, unsigned width, const nsGraphics::RGBAcolor& color) const; + virtual void drawPlayer(unsigned x, unsigned width, const nsGraphics::RGBAcolor& color) const; /*! * @brief display a missile on screen @@ -134,7 +134,7 @@ public: * @param[in] color : color of the missile * @fn void drawMissile(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const; */ - void drawMissile(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const; + virtual void drawMissile(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const; /*! * @brief display a torpedo on screen @@ -143,7 +143,7 @@ public: * @param[in] color : color of the torpedo * @fn void drawTorpedo(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const; */ - void drawTorpedo(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const; + virtual void drawTorpedo(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const; #define HEART_LENGTH 40 @@ -152,7 +152,7 @@ public: * @param[in] baseVector : pixel coordinates of the heart * @fn void drawHeart(const Position& baseVector) const; */ - void drawHeart(const Position& baseVector) const; + virtual void drawHeart(const Position& baseVector) const; /*! * @brief display a sprite on screen diff --git a/src/pixelManager/goodPixelManager.cpp b/src/pixelManager/goodPixelManager.cpp index a891308..98a13b7 100644 --- a/src/pixelManager/goodPixelManager.cpp +++ b/src/pixelManager/goodPixelManager.cpp @@ -8,8 +8,37 @@ void GoodPixelManager::loadSprites(vector& tasks) { ADD_SPRITE_TASK(invaderC) ADD_SPRITE_TASK(missile) ADD_SPRITE_TASK(torpedo) + ADD_SPRITE_TASK(heart) } GoodPixelManager::GoodPixelManager(MinGL& win) : PixelManager(win) { } + +void GoodPixelManager::drawInvaderA(const Position& baseVector, unsigned size, const RGBAcolor &color) const { + drawSprite(invaderA, baseVector); +} + +void GoodPixelManager::drawInvaderB(const Position& baseVector, unsigned size, const RGBAcolor &color) const { + drawSprite(invaderB, baseVector); +} + +void GoodPixelManager::drawInvaderC(const Position& baseVector, unsigned size, const RGBAcolor &color) const { + drawSprite(invaderC, baseVector); +} + +void GoodPixelManager::drawPlayer(unsigned x, unsigned width, const RGBAcolor& color) const { + drawSprite(player, Position(x, getScreenHeight()-PLAYER_HEIGHT)); +} + +void GoodPixelManager::drawMissile(const Position& baseVector, unsigned width, const RGBAcolor& color) const { + drawSprite(missile, baseVector); +} + +void GoodPixelManager::drawTorpedo(const Position& baseVector, unsigned width, const RGBAcolor& color) const { + drawSprite(torpedo, baseVector); +} + +void GoodPixelManager::drawHeart(const Position& baseVector) const { + drawSprite(heart, baseVector); +} diff --git a/unconverted_assets/missile.png b/unconverted_assets/missile.png new file mode 100644 index 0000000..6f21c6f Binary files /dev/null and b/unconverted_assets/missile.png differ diff --git a/unconverted_assets/player.png b/unconverted_assets/player.png new file mode 100644 index 0000000..3c9f4fe Binary files /dev/null and b/unconverted_assets/player.png differ