mirror of
https://github.com/cc65/cc65.git
synced 2025-08-09 13:25:06 +00:00
Add support for 4 quadrants
git-svn-id: svn://svn.cc65.org/cc65/trunk@5915 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -86,18 +86,9 @@ static enum Mode GetMode (const Collection* A)
|
||||
}
|
||||
|
||||
|
||||
|
||||
StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
|
||||
/* Generate binary output in Lynx sprite format for the bitmap B. The output
|
||||
* is stored in a string buffer (which is actually a dynamic char array) and
|
||||
* returned.
|
||||
*
|
||||
* The Lynx will draw 4 quadrants:
|
||||
* - Down right
|
||||
* - Up right
|
||||
* - Up left
|
||||
* - Down left
|
||||
*
|
||||
static void encodeSprite(StrBuf *D, enum Mode M, char ColorBits, char ColorMask, char LineBuffer[512],
|
||||
int i, int LastOpaquePixel) {
|
||||
/*
|
||||
* The data starts with a byte count. It tells the number of bytes on this
|
||||
* line + 1.
|
||||
* Special case is a count of 1. It will change to next quadrant.
|
||||
@@ -114,81 +105,18 @@ StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
|
||||
*
|
||||
* All data is high nybble first
|
||||
*/
|
||||
{
|
||||
enum Mode M;
|
||||
StrBuf* D;
|
||||
unsigned X, Y;
|
||||
unsigned OX, OY;
|
||||
char LineBuffer[512]; /* The maximum size is 508 pixels */
|
||||
char OutBuffer[512]; /* The maximum size is 508 pixels */
|
||||
char ColorBits;
|
||||
char ColorMask;
|
||||
|
||||
/* Anchor point of the sprite */
|
||||
OX = 0;
|
||||
OY = 0;
|
||||
|
||||
/* Output the image properties */
|
||||
Print (stdout, 1, "Image is %ux%u with %u colors%s\n",
|
||||
GetBitmapWidth (B), GetBitmapHeight (B), GetBitmapColors (B),
|
||||
BitmapIsIndexed (B)? " (indexed)" : "");
|
||||
|
||||
/* Get the sprite mode */
|
||||
M = GetMode (A);
|
||||
|
||||
/* If the mode wasn't given, fallback to packed */
|
||||
if (M == smAuto) {
|
||||
M = smLiteral;
|
||||
}
|
||||
|
||||
/* Now check if bitmap indexes are ok */
|
||||
if (GetBitmapColors (B) > 16) {
|
||||
Error ("Too many colors for a Lynx sprite");
|
||||
}
|
||||
ColorBits = 4;
|
||||
ColorMask = 0x0f;
|
||||
if (GetBitmapColors (B) < 9) {
|
||||
ColorBits = 3;
|
||||
ColorMask = 0x07;
|
||||
}
|
||||
if (GetBitmapColors (B) < 5) {
|
||||
ColorBits = 2;
|
||||
ColorMask = 0x03;
|
||||
}
|
||||
if (GetBitmapColors (B) < 3) {
|
||||
ColorBits = 1;
|
||||
ColorMask = 0x01;
|
||||
}
|
||||
|
||||
/* Create the output buffer and resize it to the required size. */
|
||||
D = NewStrBuf ();
|
||||
SB_Realloc (D, 63);
|
||||
|
||||
/* Convert the image for quadrant bottom right */
|
||||
for (Y = OY; Y < GetBitmapHeight (B); ++Y) {
|
||||
unsigned char OutIndex = 0;
|
||||
unsigned char V = 0;
|
||||
unsigned char OutIndex;
|
||||
unsigned W = 0;
|
||||
signed i = 0;
|
||||
signed j;
|
||||
signed k;
|
||||
signed LastOpaquePixel = -1;
|
||||
|
||||
/* Fill the LineBuffer for easier optimisation */
|
||||
for (X = OX; X < GetBitmapWidth (B); ++X) {
|
||||
|
||||
/* Fetch next bit into byte buffer */
|
||||
LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;
|
||||
|
||||
if (LineBuffer[i]) {
|
||||
LastOpaquePixel = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
switch (M) {
|
||||
case smAuto:
|
||||
case smLiteral:
|
||||
OutIndex = 0;
|
||||
k = 0;
|
||||
for (j = 0; j < i; j++) {
|
||||
/* Fetch next pixel index into pixel buffer */
|
||||
W = (W << ColorBits) | (LineBuffer[j] & ColorMask);
|
||||
@@ -253,6 +181,97 @@ StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
|
||||
case smPackedTransparent:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
|
||||
/* Generate binary output in Lynx sprite format for the bitmap B. The output
|
||||
* is stored in a string buffer (which is actually a dynamic char array) and
|
||||
* returned.
|
||||
*
|
||||
* The Lynx will draw 4 quadrants:
|
||||
* - Down right
|
||||
* - Up right
|
||||
* - Up left
|
||||
* - Down left
|
||||
*
|
||||
* The data starts with a byte count. It tells the number of bytes on this
|
||||
* line + 1.
|
||||
* Special case is a count of 1. It will change to next quadrant.
|
||||
* Other special case is 0. It will end the sprite.
|
||||
*
|
||||
* Ordinary data packet. These are bits in a stream.
|
||||
* 1=literal 0=packed
|
||||
* 4 bit count (+1)
|
||||
* for literal you put "count" values
|
||||
* for packed you repeat the value "count" times
|
||||
* Never use packed mode for one pixel
|
||||
* If the last bit on a line is 1 you need to add a byte of zeroes
|
||||
* A sequence 00000 ends a scan line
|
||||
*
|
||||
* All data is high nybble first
|
||||
*/
|
||||
{
|
||||
enum Mode M;
|
||||
StrBuf* D;
|
||||
signed X, Y;
|
||||
unsigned OX, OY;
|
||||
char ColorBits;
|
||||
char ColorMask;
|
||||
|
||||
/* Anchor point of the sprite */
|
||||
OX = 0;
|
||||
OY = 0;
|
||||
|
||||
/* Output the image properties */
|
||||
Print (stdout, 1, "Image is %ux%u with %u colors%s\n",
|
||||
GetBitmapWidth (B), GetBitmapHeight (B), GetBitmapColors (B),
|
||||
BitmapIsIndexed (B)? " (indexed)" : "");
|
||||
|
||||
/* Get the sprite mode */
|
||||
M = GetMode (A);
|
||||
|
||||
/* Now check if bitmap indexes are ok */
|
||||
if (GetBitmapColors (B) > 16) {
|
||||
Error ("Too many colors for a Lynx sprite");
|
||||
}
|
||||
ColorBits = 4;
|
||||
ColorMask = 0x0f;
|
||||
if (GetBitmapColors (B) < 9) {
|
||||
ColorBits = 3;
|
||||
ColorMask = 0x07;
|
||||
}
|
||||
if (GetBitmapColors (B) < 5) {
|
||||
ColorBits = 2;
|
||||
ColorMask = 0x03;
|
||||
}
|
||||
if (GetBitmapColors (B) < 3) {
|
||||
ColorBits = 1;
|
||||
ColorMask = 0x01;
|
||||
}
|
||||
|
||||
/* Create the output buffer and resize it to the required size. */
|
||||
D = NewStrBuf ();
|
||||
SB_Realloc (D, 63);
|
||||
|
||||
/* Convert the image for quadrant bottom right */
|
||||
for (Y = OY; Y < (signed)GetBitmapHeight (B); ++Y) {
|
||||
signed i = 0;
|
||||
signed LastOpaquePixel = -1;
|
||||
char LineBuffer[512]; /* The maximum size is 508 pixels */
|
||||
|
||||
/* Fill the LineBuffer for easier optimisation */
|
||||
for (X = OX; X < (signed)GetBitmapWidth (B); ++X) {
|
||||
|
||||
/* Fetch next bit into byte buffer */
|
||||
LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;
|
||||
|
||||
if (LineBuffer[i]) {
|
||||
LastOpaquePixel = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
|
||||
}
|
||||
|
||||
if ((OY == 0) && (OX == 0)) {
|
||||
@@ -270,20 +289,23 @@ StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
|
||||
|
||||
/* Convert the image for quadrant top right */
|
||||
for (Y = OY - 1; Y >= 0; --Y) {
|
||||
unsigned char V = 0;
|
||||
if (M == smLiteral) {
|
||||
for (X = OX; X < GetBitmapWidth (B); ++X) {
|
||||
signed i = 0;
|
||||
signed LastOpaquePixel = -1;
|
||||
char LineBuffer[512]; /* The maximum size is 508 pixels */
|
||||
|
||||
/* Fill the LineBuffer for easier optimisation */
|
||||
for (X = OX; X < (signed)GetBitmapWidth (B); ++X) {
|
||||
|
||||
/* Fetch next bit into byte buffer */
|
||||
V = (V << 4) | (GetPixel (B, X, Y).Index & 0x0f);
|
||||
LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;
|
||||
|
||||
/* Store full bytes into the output buffer */
|
||||
if ((X & 0x01) == 0x01) {
|
||||
SB_AppendChar (D, V);
|
||||
V = 0;
|
||||
}
|
||||
if (LineBuffer[i]) {
|
||||
LastOpaquePixel = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
|
||||
}
|
||||
|
||||
/* Next quadrant */
|
||||
@@ -291,41 +313,47 @@ StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
|
||||
|
||||
/* Convert the image for quadrant top left */
|
||||
for (Y = OY - 1; Y >= 0; --Y) {
|
||||
unsigned char V = 0;
|
||||
if (M == smLiteral) {
|
||||
signed i = 0;
|
||||
signed LastOpaquePixel = -1;
|
||||
char LineBuffer[512]; /* The maximum size is 508 pixels */
|
||||
|
||||
/* Fill the LineBuffer for easier optimisation */
|
||||
for (X = OX - 1; X >= 0; --X) {
|
||||
|
||||
/* Fetch next bit into byte buffer */
|
||||
V = (V << 4) | (GetPixel (B, X, Y).Index & 0x0f);
|
||||
LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;
|
||||
|
||||
/* Store full bytes into the output buffer */
|
||||
if ((X & 0x01) == 0x01) {
|
||||
SB_AppendChar (D, V);
|
||||
V = 0;
|
||||
}
|
||||
if (LineBuffer[i]) {
|
||||
LastOpaquePixel = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
|
||||
}
|
||||
|
||||
/* Next quadrant */
|
||||
SB_AppendChar (D, 1);
|
||||
|
||||
/* Convert the image for quadrant bottom left */
|
||||
for (Y = OY; Y < GetBitmapHeight (B); ++Y) {
|
||||
unsigned char V = 0;
|
||||
if (M == smLiteral) {
|
||||
for (Y = OY; Y < (signed)GetBitmapHeight (B); ++Y) {
|
||||
signed i = 0;
|
||||
signed LastOpaquePixel = -1;
|
||||
char LineBuffer[512]; /* The maximum size is 508 pixels */
|
||||
|
||||
/* Fill the LineBuffer for easier optimisation */
|
||||
for (X = OX - 1; X >= 0; --X) {
|
||||
|
||||
/* Fetch next bit into byte buffer */
|
||||
V = (V << 4) | (GetPixel (B, X, Y).Index & 0x0f);
|
||||
LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;
|
||||
|
||||
/* Store full bytes into the output buffer */
|
||||
if ((X & 0x01) == 0x01) {
|
||||
SB_AppendChar (D, V);
|
||||
V = 0;
|
||||
}
|
||||
if (LineBuffer[i]) {
|
||||
LastOpaquePixel = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
|
||||
}
|
||||
|
||||
/* End sprite */
|
||||
|
Reference in New Issue
Block a user