diff --git a/src/sp65/bitmap.c b/src/sp65/bitmap.c index b9862c879..c8c908833 100644 --- a/src/sp65/bitmap.c +++ b/src/sp65/bitmap.c @@ -79,9 +79,12 @@ Bitmap* NewBitmap (unsigned Width, unsigned Height) void FreeBitmap (Bitmap* B) /* Free a dynamically allocated bitmap */ { - /* Free the palette and then the bitmap */ - xfree (B->Pal); - xfree(B); + /* Alloc NULL pointers */ + if (B != 0) { + /* Free the palette and then the bitmap */ + xfree (B->Pal); + xfree(B); + } } @@ -110,9 +113,7 @@ Bitmap* SliceBitmap (const Bitmap* O, unsigned OrigX, unsigned OrigY, /* Check the coordinates and size */ - PRECONDITION (OrigX != 0 && OrigY != 0 && - OrigX + Width <= O->Width && - OrigY + Height <= O->Height); + PRECONDITION (OrigX + Width <= O->Width && OrigY + Height <= O->Height); /* Create a new bitmap with the given size */ B = NewBitmap (Width, Height); @@ -181,8 +182,8 @@ Pixel GetPixel (const Bitmap* B, unsigned X, unsigned Y) unsigned GetBitmapColors (const Bitmap* B) /* Get the number of colors in an image. The function will return the number * of palette entries for indexed bitmaps and 2^24 for non indexed bitmaps. - */ -{ + */ +{ switch (B->Type) { case bmMonochrome: return 2; case bmIndexed: return B->Pal->Count; diff --git a/src/sp65/bitmap.h b/src/sp65/bitmap.h index 4fe56f752..5c111a27b 100644 --- a/src/sp65/bitmap.h +++ b/src/sp65/bitmap.h @@ -53,6 +53,10 @@ +/* Safety limit for the bitmap sizes */ +#define BM_MAX_WIDTH 4096U +#define BM_MAX_HEIGHT 4096U + /* Safety limit for the size of the bitmap in pixels */ #define BM_MAX_SIZE 4194304UL diff --git a/src/sp65/koala.c b/src/sp65/koala.c index 317ddbf32..723cd0f5f 100644 --- a/src/sp65/koala.c +++ b/src/sp65/koala.c @@ -33,38 +33,70 @@ +/* common */ +#include "attrib.h" + /* sp65 */ +#include "error.h" #include "koala.h" +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Screen size of a koala picture */ +#define WIDTH 160U +#define HEIGHT 200U + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ -StrBuf* GenKoala (const Bitmap* B, const Collection* A) +StrBuf* GenKoala (const Bitmap* B, const Collection* A attribute ((unused))) /* Generate binary output in koala format for the bitmap B. The output is * stored in a string buffer (which is actually a dynamic char array) and * returned. */ { - /* Koala pictures are always 160x200 in size with 16 colors */ - if (GetBitmapType (B) != bmIndexed || - GetBitmapColors (B) > 16 || - GetBitmapHeight (B) != 200 || - GetBitmapWidth (B) != 160) { + StrBuf* D; + unsigned char Screen[160][200]; + unsigned char X, Y; + + /* Koala pictures are always 160x200 in size with 16 colors */ + if (GetBitmapType (B) != bmIndexed || + GetBitmapColors (B) > 16 || + GetBitmapHeight (B) != HEIGHT || + GetBitmapWidth (B) != WIDTH) { Error ("Bitmaps converted to koala format must be in indexed mode " - "with 16 colors max and a size of 160x200"); - } - - + "with 16 colors max and a size of %ux%u", WIDTH, HEIGHT); + } + /* Read the image into Screen */ + for (Y = 0; Y < HEIGHT; ++Y) { + for (X = 0; X < WIDTH; ++X) { + Screen[X][Y] = (unsigned char) GetPixel (B, X, Y).Index; + } + } + /* Create the output buffer and resize it to the required size. */ + D = NewStrBuf (); + SB_Realloc (D, 10003); + /* Add $4400 as load address */ + SB_AppendChar (D, 0x00); + SB_AppendChar (D, 0x44); + /* Return the converted bitmap */ + return D; } diff --git a/src/sp65/main.c b/src/sp65/main.c index a49b69fbe..7a72f5a5e 100644 --- a/src/sp65/main.c +++ b/src/sp65/main.c @@ -39,6 +39,7 @@ #include /* common */ +#include "abend.h" #include "cmdline.h" #include "print.h" #include "version.h" @@ -82,6 +83,8 @@ static void Usage (void) "\n" "Long options:\n" " --help\t\tHelp (this text)\n" + " --pop\t\t\tRestore the original loaded image\n" + " --slice x,y,w,h\tGenerate a slice from the loaded bitmap\n" " --verbose\t\tIncrease verbosity\n" " --version\t\tPrint the version number and exit\n", ProgName); @@ -89,6 +92,22 @@ static void Usage (void) +static void SetWorkBitmap (Bitmap* N) +/* Delete an old working bitmap and set a new one. The new one may be NULL + * to clear it. + */ +{ + /* If we have a distinct work bitmap, delete it */ + if (C != 0 && C != B) { + FreeBitmap (C); + } + + /* Set the new one */ + C = N; +} + + + static void OptHelp (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print usage information and exit */ @@ -99,6 +118,21 @@ static void OptHelp (const char* Opt attribute ((unused)), +static void OptPop (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Restore the original image */ +{ + /* C and B must differ and we must have an original */ + if (B == 0 || C == 0 || C == B) { + Error ("Nothing to pop"); + } + + /* Delete the changed image and restore the original one */ + SetWorkBitmap (B); +} + + + static void OptRead (const char* Opt, const char* Arg) /* Read an input file */ { @@ -108,14 +142,14 @@ static void OptRead (const char* Opt, const char* Arg) /* Parse the argument */ - Collection* C = ParseAttrList (Arg, NameList, 2); + Collection* A = ParseAttrList (Arg, NameList, 2); /* Must have a file name given */ - const char* FileName = NeedAttrVal (C, "name", Opt); + const char* FileName = NeedAttrVal (A, "name", Opt); /* Determine the format of the input file */ int IF = ifAuto; - const char* Format = GetAttrVal (C, "format"); + const char* Format = GetAttrVal (A, "format"); if (Format != 0) { IF = FindInputFormat (Format); if (IF < 0) { @@ -123,8 +157,46 @@ static void OptRead (const char* Opt, const char* Arg) } } - /* Read the file */ - B = ReadInputFile (FileName, IF); + /* Clear the working copy */ + SetWorkBitmap (0); + + /* Delete the original */ + FreeBitmap (B); + + /* Read the file and use it as original and as working copy */ + B = C = ReadInputFile (FileName, IF); + + /* Delete the attribute list */ + FreeCollection (A); +} + + + +static void OptSlice (const char* Opt attribute ((unused)), const char* Arg) +/* Generate a slice of a bitmap */ +{ + unsigned X, Y, W, H; + unsigned char T; + + /* We must have a bitmap otherwise we cannot slice */ + if (C == 0) { + Error ("Nothing to slice"); + } + + /* The argument is X,Y,W,H */ + if (sscanf (Arg, "%u,%u,%u,%u,%c", &X, &Y, &W, &H, &T) != 4) { + Error ("Invalid argument. Slice must be given as X,Y,W,H"); + } + + /* Check the coordinates to be within the original bitmap */ + if (W > BM_MAX_WIDTH || H > BM_MAX_HEIGHT || + X + W > GetBitmapWidth (C) || + Y + H > GetBitmapHeight (C)) { + Error ("Invalid slice coordinates and/or size"); + } + + /* Create the slice */ + SetWorkBitmap (SliceBitmap (C, X, Y, W, H)); } @@ -139,7 +211,7 @@ static void OptVerbose (const char* Opt attribute ((unused)), static void OptVersion (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Print the assembler version */ { fprintf (stderr, @@ -155,7 +227,9 @@ int main (int argc, char* argv []) /* Program long options */ static const LongOpt OptTab[] = { { "--help", 0, OptHelp }, + { "--pop", 0, OptPop }, { "--read", 1, OptRead }, + { "--slice", 1, OptSlice }, { "--verbose", 0, OptVerbose }, { "--version", 0, OptVersion }, }; @@ -202,8 +276,8 @@ int main (int argc, char* argv []) } } else { - /* #### Testing */ - ReadInputFile (Arg, ifAuto); + /* We don't accept anything else */ + AbEnd ("Don't know what to do with `%s'", Arg); } /* Next argument */ diff --git a/src/sp65/make/gcc.mak b/src/sp65/make/gcc.mak index 96607004f..fc54bcc28 100644 --- a/src/sp65/make/gcc.mak +++ b/src/sp65/make/gcc.mak @@ -34,7 +34,8 @@ OBJS = asm.o \ main.o \ output.o \ palette.o \ - pcx.o + pcx.o \ + vic2sprite.o LIBS = $(COMMON)/common.a diff --git a/src/sp65/make/watcom.mak b/src/sp65/make/watcom.mak index 3b1307a84..f3c68d190 100644 --- a/src/sp65/make/watcom.mak +++ b/src/sp65/make/watcom.mak @@ -72,7 +72,8 @@ OBJS = asm.obj \ main.obj \ output.obj \ palette.obj \ - pcx.obj + pcx.obj \ + vic2sprite.obj LIBS = ../common/common.lib diff --git a/src/sp65/vic2sprite.c b/src/sp65/vic2sprite.c new file mode 100644 index 000000000..9c4c36864 --- /dev/null +++ b/src/sp65/vic2sprite.c @@ -0,0 +1,107 @@ +/*****************************************************************************/ +/* */ +/* vic2sprite.c */ +/* */ +/* VICII sprite format backend for the sp65 sprite and bitmap utility */ +/* */ +/* */ +/* */ +/* (C) 2012, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +/* common */ +#include "attrib.h" + +/* sp65 */ +#include "error.h" +#include "vic2sprite.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Screen size of a koala picture */ +#define WIDTH 24U +#define HEIGHT 21U + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +StrBuf* GenVic2Sprite (const Bitmap* B, const Collection* A attribute ((unused))) +/* 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. + */ +{ + StrBuf* D; + unsigned X, Y; + + /* Sprites pictures are always 24x21 in size with 2 colors */ + if (GetBitmapType (B) != bmIndexed || + GetBitmapColors (B) != 2 || + GetBitmapHeight (B) != HEIGHT || + GetBitmapWidth (B) != WIDTH) { + + Error ("Bitmaps converted to vic2 sprite format must be in indexed " + "mode with 2 colors max and a size of %ux%u", WIDTH, HEIGHT); + } + + /* Create the output buffer and resize it to the required size. */ + D = NewStrBuf (); + SB_Realloc (D, 63); + + /* Convert the image */ + for (Y = 0; Y < HEIGHT; ++Y) { + unsigned char V = 0; + for (X = 0; X < WIDTH; ++X) { + + /* Fetch next bit into byte buffer */ + V = (V << 1) | (GetPixel (B, X, Y).Index != 0); + + /* Store full bytes into the output buffer */ + if ((X & 0x07) == 0x07) { + SB_AppendChar (D, V); + V = 0; + } + } + } + + /* Return the converted bitmap */ + return D; +} + + + diff --git a/src/sp65/vic2sprite.h b/src/sp65/vic2sprite.h new file mode 100644 index 000000000..8b1407e64 --- /dev/null +++ b/src/sp65/vic2sprite.h @@ -0,0 +1,69 @@ +/*****************************************************************************/ +/* */ +/* vic2sprite.h */ +/* */ +/* VICII sprite format backend for the sp65 sprite and bitmap utility */ +/* */ +/* */ +/* */ +/* (C) 2012, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ +/* */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#ifndef VIC2SPRITE_H +#define VIC2SPRITE_H + + + +/* common */ +#include "coll.h" +#include "strbuf.h" + +/* sp65 */ +#include "bitmap.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +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. + */ + + + +/* End of vic2sprite.h */ + +#endif + + +