Full Color Tile Driver Thread
potatohead
Posts: 10,261
Here is the latest, stable, release: http://forums.parallax.com/attachment.php?attachmentid=76703&d=1293501693
Tiles are 4x8. I know that is a tiny tile, but the trade-off is very good screen positioning. Groups of tiles can be handled in SPIN.
Pulled bad code archives from thread.
Tiles are 4x8. I know that is a tiny tile, but the trade-off is very good screen positioning. Groups of tiles can be handled in SPIN.
Pulled bad code archives from thread.
Comments
Pictures showing what this is about are at the bottom of the page on this thread http://forums.parallax.com/showthread.php?t=126936&page=2
I've been thinking about ways of creating tiles from pictures. It is a number of steps using paint shop but not that hard. Resize to 64x64, (possibly round off corners) and decrease color depth to the custom propeller palatte. And I have code buried away somewhere that can take a bitmap and turn it into numbers. (I found some code http://www.rayslogic.com/propeller/programming/Programming.htm that can do a 'printscreen' from vga to a bitmap on an sd card, so it would be the reverse of that).
For an operating system, you could have a .bin file for the compiled binary, and a .ico file for the icon.
Meanwhile though, a demo that simply has numbers 0-63 to display all the colors would be fine. So a single 8x8 tile with numbers in it will suffice for testing. That could be a DAT or created with a few lines of spin.
Big question - do you think this can be done on VGA as well?
Lots of stuff can drive the TV COG, which currently just renders from a scan line buffer. To see this in action, just don't start the graphics COG.
In the "start" Cog, just comment out this line to see the color bars.
TX.start(@tx_cog_init) 'Launch the text cog
With out the render COG, the TV cog will just draw what's in the buffer over and over. Others can do their own graphics COG.
I did this to illustrate the merits of developing very robust TV and or VGA cogs, as the prototype time was very short. Basically, I did not have to worry about the signal AT ALL, just the graphics logic, counters and such.
Time to build the (*^*&%* TV COG was LONG. Time to build a new graphics COG = very short!
Anyway, have a play with this bit. It's enough, and we can talk about where it goes.
We can also clean this up, and test the whole, load a COG from the SD card bit, to change modes and such... Like going from the menu to a text display, just by killing off a graphics COG, then firing off another one!
IMHO, the best way to build this stuff up, is to just make a bitmap, that's X tiles by Y tiles in size. 256 x 32 bitmap, for example, could hold all the tiles. The graphics cog can be tinkered with to use the image data directly. I've not yet done that.
Right now, the tile addressing is linear, meaning you should break the image up into strips, 4 pixels wide, encode your tile data, numbering the tiles sequentially from the top. Pack each strip in to a file, one after the other, and replace the tile pointer I've included, with the address of the top of the file.
Then put the tile numbers on the screen where you want the strips to appear.
That can all be adjusted, if this makes sense to do. IMHO, simple SPIN programs could also be written to just slice and dice a image it finds on SD card as well.
You could save code space in loading the parameters but of course this will not speed things up.
Whereabouts do you need the code sped up?
This is a first pass, prototype to see whether or not it's worth it... And, of course I don't have VGA, so I'm a TV kind of guy, but I'll argue we could do S-video, and be looking very sweet. EDIT: I do have VGA now, just haven't for a long time.
Anyway, the graphics COG needs out of order instructions, like Potatotext did. I'm not doing it yet, because there needs to be cleanup, and some capabilities added, and the stripping out of some potatotext guts still in there. Just wanted to post something these guys could tinker with, sooner rather than later.
And I really wanted to give the, "just write a graphics cog" approach a try, with the work done to create the Potatotext TV COG. It just didn't take that long to get to this stage. Few hours, which given how long it normally takes me when futzing with the signal, is just excellent!!
Probably hold off for a moment or two, until the graphics cog intent is sorted out. Some thought needs to happen on tiles, and optimal code. Some tile sizes work out to simple bit masks and adds, others don't, and where that's true, the loop slows down a lot.
Oh, I just saw what you were referring to. Ignore colors. It's not used at all, and is one of the things to clean up. It's a left over.
Re vga vs TV - I don't have TV and you don't have vga. Do you have a vga monitor - I could send you a dracblade board if you do.
I've a VGA, but until recently, I've almost never been where I can code against it. Got a little workspace now! (kid left house, whee!!) So that, and the scope are usable now, with far less hassle. For the last few years, I've literally just packed the Prop around, with a video capture, for lack of any other place to do it.
Then there is learning the VGA... Should do it, maybe start with Kye's excellent work. I don't know all the timing details. Big task there is to build / convert something that does the right signal into a scan-line cog like this one, so that graphics cogs can connect. That might be a while... Who else knows VGA, and can we share tips?? Maybe it's easier than dealing with PAL is.
Re: Sizes. Yep, I was thinking that too, but this method only allows for 8K of tile data. It's less than optimal. Need words for the tile number. It's just wasteful, that's all. We are already wasting a few bits just doing a byte / pixel. Word addressing would waste a bunch more. That's why Chip packed so much into his TV COG, so that colors could be mixed with addresses...
Need to think on this, all comments welcome.
Kye's bitmap driver looks pretty sweet. I'm going to fire it up and tinker some. IMHO, it's a candidate for doing this stuff. Clean. Just don't know about speed in full-color mode. He's using full waitvid frames. That's 16 or 32 pixels. Full color requires 4 pixel frames, which will add complexity...
Edit: I've got his driver up. I'll do some speed tests to see what can happen, once I get it converted to full color.
Anyway, the dracblade can be configured for TV or VGA. I'll send you a freebie board which you can keep - call it a 'hardware for software' swap?! Can you PM me your postal address?
I don't think memory will be an issue with an sd card and the ability to pre-load cogs and then to reload with the main program, as catalina does.
If you can get a tile with all the colors I think many of the other problems can be/have already been solved.
If speed is a problem, can you go multi-cog? 3 might be the max given other essential things but there are combos eg mouse/keyboard in one cog that can save cogs. So anything up to and including 3 cogs would be ok.
I've attached one that has a simple set tile method, and that does 320 pixels at 80Mhz.
And a couple of really boring screenies.
...more when I get back from my "honey do" list. I'll PM the address in a bit. I really gotta get some good tile data. I'm willing to try the VGA. The two screenies are 320 pixels and 80 pixels, just to show the tile nature, and give some idea of screen density possible.
After struggling with HWpins for my platform ... again, I have a display on my dinky DVD TV LCD.
The screen is a thatch pattern and a small 2 tile yellow overlay rectangle. The driver is small Thanks for posting pics with the new .zip - I'll try that soon.
Just interested...
potatohead: Yes, I will just wait till your ready.
jazzed: No rest for the wicked! This forum keeps taking my design time!
Basically, a waitvid has pixels and colors. 4 Colors are possible, and can be distributed among the pixels. The frame size is basically what you want, up to the limits of 16 and 32 pixels, depending on 2 or 4 color. This you know, and it's in the documentation.
It's common to run smaller than optimal frame sizes to make the video loops operate efficiently. A great example is the 8x8 text drivers. Those run 2 or 4 color, with just 8 pixels in the frame, which eliminates some shuffling around of bits in the COG at video signal draw time. That's costly --very costly. A big part of making Propeller video work is finding those things that a COG can just index with a simple add, or shift. Anything else, and combinations of those must either be pre-computed, or the video loop slows down, and that cuts resolution.
What I did, and have done in the past, is run the waitvid backwards. The frame is always just 4 pixels, never more, never less. The pixel data is fixed too. It's either #%%3210, or #%%0123, depending on the order of pixel output desired. In this configuration, a waitvid can reverse the data as part of the normal processing --a nice bonus in return for the small frame size.
Once you've fixed the pixel data, the colors data then simply becomes pixels!! There still is a 4 color limit, but since the frame is 4 pixels, there is basically no limit at all, making it possible to just assign any pixel to any color.
Clearly, this impacts two things: One is the video loop just got a lot shorter, meaning it's gotta run very lean, or bad things happen, like inability to feed the waitvid fast enough, and two, the amount of data that has to move goes up a lot, because we are talking whole bytes now, not just bits. On the other hand, dealing with bytes in a COG is a whole lot more efficient than bits are, so that's a net gain, combined with the "auto reverse" on the pixels, makes full color possible, although at a generally lower resolution than is possible otherwise.
TV is most favorable to this technique because of it's slower horizontal sweep frequency. I've not really got to run the VGA stuff to see what may be possible, but I do know it's got a faster sweep. That probably means in-line, unrolled video loops. No big deal on those. I think Linus did it for his demo, because I captured a post he had here with exactly that kind of thing going on. (that post is gone now, and I never did know why)
Because this really constrains the video loop, it's highly likely multi-cog will be needed. That means a scan line buffer, and the TV COG + Graphics COG approach I ended up using. The sprite drivers do this kind of thing, meaning there is code out there to learn from, which is what I've done, mostly because I kind of like this stuff.
Your driver is really clean Kye! I'm thinking it probably can be made to fetch from a scan line buffer pretty easy, and from there, add the signals to talk to a graphics COG. We shall see! It's always good to have a clean driver to learn from. Personally, I found the Parallax ones difficult because they do a lot! I started with a simple TV driver, written by CardboardGuru, and later on, used the Templates Eric did.
IMHO, your VGA bitmap is nice to build and learn off of. Thanks for writing it
Re: 400+ colors.
That's a NTSC trick. Basically, if you operate at a resolution of 160 pixels (2560 PLLA), and run the waitvid at 320 pixels, everything mixes together. I put a screen capture in the wiki, showing the mixing. There are a lot more colors possible. 1 or 2K is the max I think is doable. Needs to be NTSC and needs to be 160 pixels, period though. Thought it would be great for games. And a scan-line buffer driver conversion is needed to really exploit that. Hasn't been done.
This TV COG outputs a nice signal, sharp, and full interlaced, so the colors will show up very well on most TV's, making 320 pixels reasonable. One of these days, I need to build the S-video port, and run it that way. Bet that 512 - 640 looks pretty great.
It function on my little LCD TV but have some horizontal line problems in periods of 2-3 second that are some 0.5 seconds long
@Sapieha: What clock? What pixel rate? Which data? Which signal settings?
Mine displays steady for long periods of time. I've run it on 80Mhz Demoboard, and 96Mhz HYBRID. In fact, it's been running @ 320 pixels on the Demoboard, since the post above.
I did all my calculations for VGA mode but TV will be different. The bitmap will come out of paint shop pro having been decreased to 64 colors, then increased again when saved as a bitmap. So each pixel will be three bytes, and the bytes will have one of four values, 0, 85, 170 and 255.
Translating that to single byte values for vga will be easy.
But for TV, I see a table in the code that has 6 intensities and 16 hues.
So that is a palatte of 96 colors. Indeed, decreasing to 64 colors like for vga and then increasing to the best match of 96 is going to lose color information.
Better to start with the original bitmap data of 3 bytes per pixel and translate that to 96 colors in code rather than processing it through paint shop.
I'm greatly encouraged by the comments that vga will be possible. But for the moment with TV, what we probably need is a little bit of code that translates bitmaps into the nearest color in this table?
So, for VGA... I would say you'll probably need a 100Mhz propeller to pull this off.
... But if you unrolled the loop and used a counter module to provide indexing for the video memory then something may be possible. Getting the counter to count up at the same speed though will be tricky.
The problem is that:
These 3 lines must be run per waitvid. So, I think you can do an 8 pixel waitvid without problems... but a four pixel one will require an unrolled loop or a faster processor. If we could remove the "add buffer, #4" line with a counter module then it may be possible.
...
One more thing, since the prop has very little memory the resolution will be so low with this system that it will not be useable. So, what's the point?
And can't the pixels be stretched to fit? That's something I've not had a chance to learn yet. On a TV, one just makes a longer pixel, and have it be a factor of the optimal number of pixels.
Can't that happen on VGA? So then, maybe it's good for 300 pixels, or so, right?
As for usability, that's a matter of what one wants the display for. Sprites are usable in low RAM situations. Tiles are too, which is how the nice text displays are done.
The idea being explored here is to present a graphical set of choices. Since the prop has software video, one can simply load what it takes to make that happen, stop it, then load something else from storage. That changes the usability game considerably, which is why I bothered with the tile display in the first place.
Baggers has a full on Raycaster running on the thing. A few tiles isn't out of the realm of what can be done. Besides, it's fun!
Had to make a run to Cleveland today and missed this thread..
Will definitely be playing catch-up!
OBC
Sounds like we do TV first?
Re the use, well, lots of uses. I'm thinking a black screen with six hi-color 64x64 buttons (approx ipad size), and each of those brings up menus of other buttons, or runs binary programs. But you can do other things too - eg have primitive tiles for things like the corners of buttons, and the lines on the side and top, and the fill. Tiles for a check box that is checked, and one that is unchecked.
Sure, you are not going to fill a screen with these due to hub ram limitations, but if you have a gray screen with a couple of check boxes and a button, and then you refresh off the sd card with brand new tiles and redraw another screen, it would have an 'eye candy' appeal that text based operating systems will never have.
Of course, it still might be something like Kyedos behind the scenes. Or Catalina (which gives you about 30k of hub ram to play with).
I can picture all kinds of interesting uses for something like this..
OBC
External ram may be useful though as it could be faster to load tiles from sram than from an sd card. For flexibility, one would probably have the option to load tiles from either source.
I'm not sure it would be possible to load external ram on the fly for each frame. Possibly with cluso's ram but the aim would be to design screens that don't require this. Lots of simple screens that you click through rather than putting everything on one screen.
OBC: From here, the paths to more colors involve new video circuits, as in what Coley and Baggers did, or multi-cog tricks, and in all cases, the HUB RAM gets consumed. Using all the Prop colors has always been possible. What changes the game is being able to run programs from external RAM, and SD card, followed by the idea of BLOB style drivers. Kye-DOS means being able to make a fairly large program, fetching things, doing something, then fetching something else. It's like early computers now!
So, some driver work now makes sense. Before, it was a curio, like for the wiki display, and the fractals, where only a tiny program is needed, or possible.
Looking at the palatte for TV, it seems different to the vga palatte I calculated - eg there seem to be a lot less red and yellows. Is there a mathematical formula to convert RGB values to the single byte hex code you use?
VGA uses RGB values directly. So it's just levels of red, blue, green.
TV uses a phase angle for the HUES, and there are 16 of those. Google the color wheel, and dividing the wheel into 16 slices gets you the kind of formula you need to work out the hues. Edit: And how the signals add together limit things some. Just for extra fun, we can shift these some in the TV cog, by altering the reference signal, improving reds and yellows, at the expense of greens and probably blues... TV's are messy.
Intensities range from 02 to 07, and are just added to a hue. If you broke the RGB down to HSV, those values would map over more easily.
Lower order bits are intensity, higher order bits are hue, some unused with TV.
Color = hue(0-17) + intensity(2-7) is the space I use, with the CLUT table you found.
Another oddity is any hue + intensity 7, is outta spec, and shows up as a higher saturation color. That's the top row in graphics_palette.spin
If you look at the wiki page I did, ALL the propeller colors are in that table on the page, and there are two high-saturation color sets, and they are hue shifted from the ordinary colors. Look at the strip along the bottom, and up the right hand side. Those are all "pure" Propeller TV colors. About 96 of those will display well on all devices. Some devices reject the low intensity colors, and some reject the brightest, out of spec colors too.
where "pixels" = %%00112233, for the same 320 pixel resolution found on TV. That's the thing to try on my next session.
So, scratch the 4 pixel frame, never more, never less. It can vary. It might have to on the higher sweep rates.
Ok, the color wheel http://en.wikipedia.org/wiki/Color_wheel is great for colors but it doesn't show shades of gray, nor shades of gray with slight color added (gray with a tinge of blue). I think you need three axes to describe all the colors? (hue/saturation/lightness or red/green/blue).
So "Lower order bits are intensity, higher order bits are hue" - what does lightness? http://en.wikipedia.org/wiki/HSL_and_HSV
So say we take the first two lines of the data
byte byte $02, $03, $04, $05, $06, $07, $07, $07 'Six intensities
byte byte $09, $0a, $0b, $0c, $0d, $0e, $88, $9f
Is the first line the shades of gray?
And is the second line a combination of intensity and color, or do you pass these as two separate bytes?
I'm just thinking if we are going to preprocess a bitmap, may as well process it so the cog does the absolute minimum. Eg if it is easier to pass a long to a value rather than a byte, then pre combine pixels into a long.
By strenching the pixels across the screen by setting the vscl register you will have plenty of time to get the next four pixels.
So, I think 160x120 at 1 byte per pixel will be very much doable. The only problem I see is that you won't be able to double buffer...
So, now the real question is: Would this driver be usable if you can't do that. 160x120 = 19200 pixels... That's alot of elements to clear and change at 60 FPS. Changing them any slower will result in screen crawl.
... So, unless the resolution gets even smaller the screen will never be able to be updated nicely.