Fabrizio Caruso Posted February 24 Share Posted February 24 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; Quote Link to comment Share on other sites More sharing options...
42bs Posted February 24 Share Posted February 24 you cannot. You need to go for BPP_2 and use e.g. 1 and 2 for background/foreground and 0 for "don't care". Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 24 Author Share Posted February 24 (edited) 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 February 24 by Fabrizio Caruso Quote Link to comment Share on other sites More sharing options...
LordKraken Posted February 24 Share Posted February 24 (edited) The first color in your palette is the transparent one, if you define in your SCB the flag 0x07 in CTL0 (so for 2 bpp, that would be 0x47) Edited February 24 by LordKraken Quote Link to comment Share on other sites More sharing options...
42bs Posted February 24 Share Posted February 24 1 minute ago, LordKraken said: The first color in your palette is the transparent one, if you define the flag 0x07 in CTL0 Right, but then you must clear the background before drawing. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 24 Share Posted February 24 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. Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 24 Author Share Posted February 24 @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? Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 24 Author Share Posted February 24 @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. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted February 25 Share Posted February 25 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? Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 25 Share Posted February 25 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()); } } bpp1.lnx 1 Quote Link to comment Share on other sites More sharing options...
42bs Posted February 25 Share Posted February 25 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. Quote Link to comment Share on other sites More sharing options...
LX.NET Posted February 25 Share Posted February 25 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. Quote Link to comment Share on other sites More sharing options...
42bs Posted February 25 Share Posted February 25 Right, one byte for penpal will be enough. And yes, the color in penpal is important, not the index in the sprite data. The latter would be bad idea, if you think about it. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 25 Share Posted February 25 (edited) 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 February 25 by Nop90 1 Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 25 Author Share Posted February 25 @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. Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 25 Author Share Posted February 25 (edited) 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 February 25 by Fabrizio Caruso Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 26 Author Share Posted February 26 Thanks everyone here! Without you I was lost. I have managed to build fixed versions of all my 8 home-brews that I have written with my Cross-Lib framework: https://github.com/Fabrizio-Caruso/CROSS-LIB/releases/tag/atari_lynx Quote Link to comment Share on other sites More sharing options...
Nop90 Posted February 26 Share Posted February 26 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 Quote Link to comment Share on other sites More sharing options...
Fabrizio Caruso Posted February 26 Author Share Posted February 26 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? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.