Jump to content
IGNORED

Can we have monochromatic sprites with 1 bit per pixel?


Recommended Posts

Hi everyone,

I am struggling with what I thought was a rather simple problem.
I need to display something as simple as an 8 pixel wide, 6 pixel high rectangles with just 1 color to chose for the foreground and 1 common background color.
Due to a bug in Suzy chip if I do this I lose the 8th pixel on each line.

If I add an extra dummy byte just to display the missing pixel, I end up deleting 8 (or 7) pixels on the right of my sprite.

I am using something like this, which gives me a solid background with a missing last pixel and I don't know how to force Suzy to display the missing pixel without deleting 8 pixels to the right of the sprite.

        _tgi_tile[i].sprctl0 = (unsigned char) (BPP_1 | TYPE_NORMAL);
        _tgi_tile[i].sprctl1 = (unsigned char) (LITERAL | REHV);
        _tgi_tile[i].sprcoll = (unsigned char) NO_COLLIDE;

 

Link to comment
Share on other sites

Thanks @42bs, so BPP_1 has no transparent color... and with BPP1 I cannot display 8 pixels. I can do only 7 pixels or 15 pixels...
In reality I don't need transparency. I would just be happy with 8 solid pixels with foreground and background color.
I thought of transparency as a way to work around the hardware bug of the Suzy chip.

So I have to use BPP_2, then how do I set a color to be transparent?
Sorry if I ask basic questions... I have read some doc and I have not understood it.

What is then penpal[0] in BPP_2 ?
penpal[0] -> 00
penpal[1] -> 01
penpal[2] -> 10
penpal[3] -> 11
?
What do you mean by "don't care" ? you mean transparent ?

 

Edited by Fabrizio Caruso
Link to comment
Share on other sites

33 minutes ago, Fabrizio Caruso said:

Thanks @42bs, so BPP_1 has no transparent color... and with BPP1 I cannot display 8 pixels. I can do only 7 pixels or 15 pixels...
In reality I don't need transparency. I would just be happy with 8 solid pixels with foreground and background color.
I thought of transparency as a way to work around the hardware bug of the Suzy chip.

So I have to use BPP_2, then how do I set a color to be transparent?
Sorry if I ask basic questions... I have read some doc and I have not understood it.

What is then penpal[0] in BPP_2 ?
penpal[0] -> 00
penpal[1] -> 01
penpal[2] -> 10
penpal[3] -> 11
?
What do you mean by "don't care" ? you mean transparent ?

 

Right. 0 is transparent. Or if you go for 1BPP you can - as  @LordKraken wrote - also 0 as transparent. But then you need to clear the area before drawing.

Link to comment
Share on other sites

@42bs, so I am confused. I am using 1BPP and 0 is not transparent. It is solid. If it can be made transparent, I would like to know how.

What I need to do is display an 8 pixel wide 6 pixel solid high rectangle with just 1 foreground color (that may change on each 8x6 block) and a common background color.

Probably irrelevant here: All such rectangles are aligned on 8 pixel wide 6 pixel. So they are sort of like "tiles".

If I could display transparent + 1 color sprites in 1BPP, I could clear the area first and then display what I want so that the end result looks like an 8x6 tile. I need to display all pixels and avoid the hardware bug.

Do you mean I can do it in 1BPP? Could you please tell me how?

Link to comment
Share on other sites

@LordKraken I don't understand how to have a transparent color in BPP1. You seem to say it is possible.
What do you mean by "first color" ?
You mean the color mapped to the "0" bits or the color 0 in the palette?

If I do something like:

        _tgi_tile[i].sprctl0 = (unsigned char) (BPP_1 | TYPE_NORMAL | 0x07);
		...
        _tgi_tile[i].penpal[0] = (unsigned char) 0x14;

 

then the color mapped to 0 bit, is still not transparent.

Link to comment
Share on other sites

Sprite TYPE_NORMAL should have a transparent pen 0. Make sure you use that pen for drawing. I am not sure how it all works for BPP lower than 4, as the documentation states that the pens E and F are special, 1-D are fairly normal. In BPP_1 through BPP_3 those pens are not available, how would you do a shadow or boundary pen? 

 

Link to comment
Share on other sites

This should be what you need

 

#include <6502.h>
#include <conio.h>
#include <tgi.h>
#include <stdlib.h>
#include <joystick.h>
#include <conio.h>

unsigned char rect[19] = {  3, 0xff, 0,
							3, 0x81, 0,
							3, 0x81, 0,
							3, 0x81, 0,
							3, 0x81, 0,
							3, 0xff, 0,0
						};

SCB_REHV_PAL sp_sprite = 
{
    BPP_1 | TYPE_NORMAL,
    REHV|LITERAL,
    NO_COLLIDE,
    0,
    rect,
    0, 0,
    0x100,0x100,
    {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}
};

void main(void) 
{
	tgi_install(&tgi_static_stddrv);
	tgi_setframerate(60);
	tgi_init();
	CLI();

	while (1) 
	{
		tgi_clear();
		sp_sprite.hpos=78;
		sp_sprite.vpos=50;
		sp_sprite.penpal[0]=0x01;
		tgi_sprite(&sp_sprite);
		sp_sprite.hpos=82;
		sp_sprite.vpos=52;
		sp_sprite.penpal[0]=0x02;
		tgi_sprite(&sp_sprite);
		tgi_updatedisplay();
		while(tgi_busy());
	}
}

 

image.png.e27adc499d3894ba4eef467d19bac671.png

bpp1.lnx

  • Like 1
Link to comment
Share on other sites

8 hours ago, Fabrizio Caruso said:

@LordKraken I don't understand how to have a transparent color in BPP1. You seem to say it is possible.
What do you mean by "first color" ?
You mean the color mapped to the "0" bits or the color 0 in the palette?

If I do something like:

        _tgi_tile[i].sprctl0 = (unsigned char) (BPP_1 | TYPE_NORMAL | 0x07);
		...
        _tgi_tile[i].penpal[0] = (unsigned char) 0x14;

 

then the color mapped to 0 bit, is still not transparent.

The color you choose must be 0, not the index. But Nop90 gave you a great example to play with.

Link to comment
Share on other sites

Let's see if I understand it better now.

The global palette for the colors defines the colors per pen 0 through F. In your SCB penpal you pick a color from that palette, taking into account that 0, E and F might be special depending on your sprite type. 

So, it is not the index of the penpal that is determining what is special, but what color index from the palette you choose.

Correct?

 

And for additional educational purposes: @Nop90: should your example define just one byte in the penpal, instead of 8? 

I thought that was the case, because BPP_1 only loads a single byte for two colors. 

Link to comment
Share on other sites

The data in the sprites tell what pen to use for every pixel, a BPP4 image can use all the 16  pens, a BPP2 only the first four, a BPP1 only the first two.

 

Some pens has special behaviour (e.g. Pen 0 can be transparent if using TYPE_NORMAL, pens E and F can have special caracteristics with the collision handling, etc).

 

The palette is composed of 16 RGB (12bpp) colors and is global for the whole screen (but can be changed on the fly row by row knowing how to do 😉), every sprite can map every pen to one of the 16 colors using the penpal array. Several pens can map on the same color if needed.

 

The Penpal array has a fixed size (8 bytes, i.e 16 nibbles, one per pen), it's a field of the SCB structure. If a SCB doesn't need to change the pens mapping can avoid to have the penpal field an have the REUSEPAL flag set, it will use the same mapping of the previous sprite handled by Suzy.

 

I think thats all. 

Edited by Nop90
  • Like 1
Link to comment
Share on other sites

@Nop90Thanks a lot!
I was setting penpal[0] with wrong values that made the sprite solid and so I was getting the Suzy bug (no final pixel).
@Nop90 I can use your example to get my code to display transparent sprites!

Now my goal is to get a total result that looks like a solid sprite without the Suzy bug. I need to clear the 8x6 "tile". How can I do it?
My background color is black.
I thought I could use tgi_bar (no idea what it does behind internally) but it does not produce the desired effect.
Then I could just use a transparent black block with no transparent pixels but I don't know how to do it.

Link to comment
Share on other sites

I got it to work by trial and error without fully understanding what I am doing...
I delete the tile area by using black as foreground and it works:
 

void _tgi_gfx_delete(uint8_t x, uint8_t y)
{
    empty_spr->hpos = (x)*8;
    empty_spr->vpos = (y)*6;
    empty_spr->penpal[0] = 1;
    tgi_sprite(empty_spr);
}


void _tgi_gfx_draw(uint8_t x, uint8_t y, uint8_t tile, uint8_t color)
{
    _tgi_gfx_delete(x, y);
    _tgi_tile[tile].hpos = (x)*8;
    _tgi_tile[tile].vpos = (y)*6;
    _tgi_tile[tile].penpal[0]=color;
    tgi_sprite(&(_tgi_tile[tile]));
}

 

Edited by Fabrizio Caruso
Link to comment
Share on other sites

5 hours ago, Fabrizio Caruso said:

I got it to work by trial and error without fully understanding what I am doing...
I delete the tile area by using black as foreground and it works:
 

void _tgi_gfx_delete(uint8_t x, uint8_t y)
{
    empty_spr->hpos = (x)*8;
    empty_spr->vpos = (y)*6;
    empty_spr->penpal[0] = 1;
    tgi_sprite(empty_spr);
}


void _tgi_gfx_draw(uint8_t x, uint8_t y, uint8_t tile, uint8_t color)
{
    _tgi_gfx_delete(x, y);
    _tgi_tile[tile].hpos = (x)*8;
    _tgi_tile[tile].vpos = (y)*6;
    _tgi_tile[tile].penpal[0]=color;
    tgi_sprite(&(_tgi_tile[tile]));
}

 

Beware that the penpal array is composed of 16 nibbles, so setting penpal[0] you are defining the mapping of two pens, pen0 and pen1. Pen0 is set by the High nibble, pen1 by the Low nibble. The same for the other valued of the penpal array.

 

This means that if you set penpal[0]=1 you are mapping pen0 to color 0 and pen1 to color 1. That's why it is a common practice to us hex values setting the pens (i.e. penpal[0]=0x01) so the assignment of the two pens is evident.

 

BTW great job with you cross-lib framework. Un saluto, Gisberto

 

 

Link to comment
Share on other sites

Thanks/Grazie @Nop90!

The penpal array was indeed confusing for me as well as Handy 0.95 which hides the Suzy bug.
I am happy I got the Atari Lynx glitch sorted thanks to you.
Next Atari target I need to improve is the Atari 7800, which is currently lacking real graphics in Cross-Lib.

I would like to show make my games playable on the browser through a Javascript emulator as I do for some of my targets (VIC20, C64, Laser500, Laser 200, etc.). Any suggestion?
 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...