X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fsp65%2Fvic2sprite.c;h=9fbe06f119a408b1c18da9d2c78aaf61a4400218;hb=35e1184901ca38bdb2e56d154ed3b71f6096eacc;hp=371b9616bdeaffdbb6f06294fc3a05a706939921;hpb=c140a15dac72a1b33893c65a06efaedf29784412;p=cc65 diff --git a/src/sp65/vic2sprite.c b/src/sp65/vic2sprite.c index 371b9616b..9fbe06f11 100644 --- a/src/sp65/vic2sprite.c +++ b/src/sp65/vic2sprite.c @@ -38,6 +38,7 @@ #include "print.h" /* sp65 */ +#include "attr.h" #include "error.h" #include "vic2sprite.h" @@ -49,9 +50,17 @@ -/* Screen size of a koala picture */ -#define WIDTH 24U -#define HEIGHT 21U +/* Sprite mode */ +enum Mode { + smAuto, + smHighRes, + smMultiColor +}; + +/* Size of a sprite */ +#define WIDTH_HR 24U +#define WIDTH_MC 12U +#define HEIGHT 21U @@ -61,12 +70,33 @@ -StrBuf* GenVic2Sprite (const Bitmap* B, const Collection* A attribute ((unused))) +static enum Mode GetMode (const Collection* A) +/* Return the sprite mode from the attribute collection A */ +{ + /* Check for a mode attribute */ + const char* Mode = GetAttrVal (A, "mode"); + if (Mode) { + if (strcmp (Mode, "highres") == 0) { + return smHighRes; + } else if (strcmp (Mode, "multicolor") == 0) { + return smMultiColor; + } else { + Error ("Invalid value for attribute `mode'"); + } + } else { + return smAuto; + } +} + + + +StrBuf* GenVic2Sprite (const Bitmap* B, const Collection* A) /* Generate binary output in VICII sprite format for the bitmap B. The output * is stored in a string buffer (which is actually a dynamic char array) and * returned. */ { + enum Mode M; StrBuf* D; unsigned X, Y; @@ -74,16 +104,40 @@ StrBuf* GenVic2Sprite (const Bitmap* B, const Collection* A attribute ((unused)) /* Output the image properties */ Print (stdout, 1, "Image is %ux%u with %u colors%s\n", GetBitmapWidth (B), GetBitmapHeight (B), GetBitmapColors (B), - (GetBitmapType (B) == bmIndexed)? " (indexed)" : ""); + BitmapIsIndexed (B)? " (indexed)" : ""); + + /* Get the sprite mode */ + M = GetMode (A); - /* Sprites pictures are always 24x21 in size with 2 colors */ - if (GetBitmapType (B) != bmIndexed || - GetBitmapColors (B) != 2 || - GetBitmapHeight (B) != HEIGHT || - GetBitmapWidth (B) != WIDTH) { + /* Check the height of the bitmap */ + if (GetBitmapHeight (B) != HEIGHT) { + Error ("Invalid bitmap height (%u) for conversion to vic2 sprite", + GetBitmapHeight (B)); + } - Error ("Bitmaps converted to vic2 sprite format must be in indexed " - "mode with a size of %ux%u and two colors", WIDTH, HEIGHT); + /* If the mode wasn't given, determine it from the image properties */ + if (M == smAuto) { + switch (GetBitmapWidth (B)) { + case WIDTH_HR: + M = smHighRes; + break; + case WIDTH_MC: + M = smMultiColor; + break; + default: + Error ("Cannot determine mode from image properties"); + } + } + + /* Now check if mode and the image properties match */ + if (M == smMultiColor) { + if (GetBitmapWidth (B) != WIDTH_MC || GetBitmapColors (B) > 4) { + Error ("Invalid image properties for multicolor sprite"); + } + } else { + if (GetBitmapWidth (B) != WIDTH_HR || GetBitmapColors (B) > 2) { + Error ("Invalid image properties for highres sprite"); + } } /* Create the output buffer and resize it to the required size. */ @@ -93,15 +147,29 @@ StrBuf* GenVic2Sprite (const Bitmap* B, const Collection* A attribute ((unused)) /* Convert the image */ for (Y = 0; Y < HEIGHT; ++Y) { unsigned char V = 0; - for (X = 0; X < WIDTH; ++X) { + if (M == smHighRes) { + for (X = 0; X < WIDTH_HR; ++X) { + + /* Fetch next bit into byte buffer */ + V = (V << 1) | (GetPixel (B, X, Y).Index & 0x01); + + /* Store full bytes into the output buffer */ + if ((X & 0x07) == 0x07) { + SB_AppendChar (D, V); + V = 0; + } + } + } else { + for (X = 0; X < WIDTH_MC; ++X) { - /* Fetch next bit into byte buffer */ - V = (V << 1) | (GetPixel (B, X, Y).Index != 0); + /* Fetch next bit into byte buffer */ + V = (V << 2) | (GetPixel (B, X, Y).Index & 0x03); - /* Store full bytes into the output buffer */ - if ((X & 0x07) == 0x07) { - SB_AppendChar (D, V); - V = 0; + /* Store full bytes into the output buffer */ + if ((X & 0x03) == 0x03) { + SB_AppendChar (D, V); + V = 0; + } } } }