TV_Text.Spin - User Defined Characters
hippy
Posts: 1,981
I'm trying to modify TV_Text.spin to display a user defined character but having little joy. The original character displaying' code is -
Am I right, that to convert the character "X" to my single user defined character I need to use -
Also, how do I ensure that the tile definition I want to use is appropriately aligned in the DAT section ?
PRI print(c) screen[noparse][[/noparse]row * cols + col] := (color << 1 + c & 1) << 10 + $200 + c & $FE
Am I right, that to convert the character "X" to my single user defined character I need to use -
PRI print(c) if c == "X" screen[noparse][[/noparse]row * cols + col] := (color << 1 ) << 10 + ( @MyTileAddress >> 6 ) else screen[noparse][[/noparse]row * cols + col] := (color << 1 + c & 1) << 10 + $200 + c & $FE
Also, how do I ensure that the tile definition I want to use is appropriately aligned in the DAT section ?
Comments
If you are using the standard TV driver, you are probably aware of the need to align the data on a 16-long boundary. You can do the alignment at run time. One way to do this is to add a pad of 15 longs previous to your definition, create a pointer to your data and round it off (ptr & $FFC0), then move the data from the original location to the rounded location. Your copy will overlap the original, so make sure you copy starting at the lower address. You can also check to see if the rounded address == the original address to avoid copying unnecessarily if it's already aligned.
BTW: Are you using 4-color mode?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
Post Edited (Ken Peterson) : 9/26/2007 4:15:47 PM GMT
As to 4 colour mode; I'm using as it comes, which allows a palette of 8 entries. In my own app I've modified it for 16 entries which seems to be working okay. I'm guessing there's some caveat I'm not aware of for four colour mode ?
Also, I noticed that you are leaving out the color calculations in your example. Since character definitions are "interlaced" in the ROM, the color palette determines which character of the pair is displayed. This is why the character is rounded off and the LSB of the character determines which color is used.
Then again, if you are designing your own characters you probably wouldn't make them interlaced (interleaved?) like the ROM definitions. Then you can use all four colors per character using your code example (I think).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
Post Edited (Ken Peterson) : 9/26/2007 4:32:15 PM GMT
'64 byte align the user characters
user_charbase := @uchar & $FFC0 'destination
longmove(user_charbase,@uchar,16*nuchars)· 'nuchars=# of new characters
padding LONG 7[noparse][[/noparse]16] 'alignment padding for the following user defined characters
uchar
LONG %%1100_1100_1100_1111 'new character 0
LONG %%1100_1100_1100_1111
LONG %%0011_0011_0011_0011
LONG %%0011_0011_0011_0011
LONG %%1100_1100_1100_1111
LONG %%1100_1100_1100_1111
LONG %%0011_0011_0011_0011
LONG %%0011_0011_0011_0011
LONG %%1100_1100_1100_1111
LONG %%1100_1100_1100_1111
LONG %%0011_0011_0011_0011
LONG %%0011_0011_0011_0011
LONG %%1100_1100_1100_1111
LONG %%1100_1100_1100_1111
LONG %%0011_0011_0011_0011
LONG %%0011_0011_0011_0011
I guess I wasn't sure whether LONGMOVE starts at the low end or high end. Sometimes code is better optimized by counting down. If it doesn't start at the low end, you'll have a problem.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
After this kind of dicussion has occurred three or four times now I changed it some weeks ago to allow LONG addressing, which leaves 2 bits for other purposes.. One is used to indicate the interleave variant, the other to allow non-interleaved bitpatterns (which is more comfortable).
It still needs documentation ... the worst thing is, this SILVA_TV is not compatible to the standard TV.. So.it needs SILVA_TEXT ...
And it is monochrome of course
Adding (256!!) colours is straightforward using a second BYTE vector corresponding to the LONGs, but not yet done
As far as adding colors, it would also be possible to bank in different color vectors, as the color number is just an index. Each row of tiles could theoretically use a different color vector. I wouldn't be surprised if something like this has already been done.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
I do the longmove of 16 longs ( just the once ) and what I'm seeing is two square boxes stacked vertically, similar to an "8". What I was hoping to see was one box sitting just above the ground. I guess this is due to the interleaving, or I've misunderstood the pixel mapping ?
The manual says "Each character definition is 16 pixels wide by 32 pixels tall", yet TV.spin says, "pixelgroups are <tileheight> longs which define (left-to-right, top-to-bottom) the 2-bit (four color) pixels that make up a 16x16 or a 32x32 pixel tile". For the life of me I cannot correlate those two statements together, nor understand what the manual means when it talks of merging and 'odd-even' pairs.
More intriguing though; if I make the padding array longer, for example 64 longs, extra pixels are turned on beneath the two boxes. Even if I change the padding value from 7 to zero. That doesn't make sense to me. It's still moving 16 longs from '@uchar' to '@uchar & $FFC0', and the pointer put into the 'screen' array is '@uchar & $FFC0' in both cases. The addresses are further down memory, but still aligned on a 64 byte / 16 long boundary.
Any ideas or pointers to clearer, more explanatory, information ?
Just this: The Video Logic always outputs 16 2-bitPAIRS. You have to decide by the choice of an appropriate colour combination which bit of the pair is to be output... This is why TV_TEXT can only allow two colours (fg and bg ) per tile.
No, you HAVE not - you CAN. Thats all the reason behind it!
There are many possibilities...
The color number is not "just an index", but "just a number". I should prefer it to be a "color value" in SILVA_TV rather than an index as with TV. But I have not yet implemented anything...
Post Edited (deSilva) : 9/27/2007 2:19:42 AM GMT
The characters in the ROM are interleaved in that each "character" in ROM is actually two characters. There is a pair of bits for each pixel, which represents one of four colors in your palette. If you choose 00, you get background. If you choose 01, you get one character. If you choose 10, you get the other character, and if you choose 11 (not usually used for text, only for box borders) you get BOTH characters.
Look closely at how the TV_Text.spin calculates the value for the screen tile. It multiplies your color number by two and adds one if your character is ODD. This has the effect of choosing a color palette that will display the proper character in the interleave. Also notice that the offset in the Character ROM is rounded to the nearest even address (c & $FE). This is because there are TWO characters at each address, and the color palette, as mentioned above, makes the final determination as to which character you see.
Also look closely at how the color palettes are defined in the TV_Text object. They work together in pairs - you have eight pairs of colors to work with for displaying text, and which one of the pair is chosen depends on whether you are displaying an even or odd character. For one character, values for 01 and 11 would be foreground, while 00 and 10 would be background. For the other character, values 10 and 11 would be foreground and 00 and 01 would be background.
Hope this clears things up for you a little.
Ken
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The more I know, the more I know I don't know.· Is this what they call Wisdom?
I hate to disagree, but I'm not finding it at all simple.
Outside of TV_Spin_Demo, in my own application, I applied the same changes and I see one box at the top half of the character and garbage pixels below. There's obviously something missing which I haven't understood. It has all the hallmarks of the bottom half of the character being a (half?-) tile taken from some address I am not putting pixel data into, which indicates to me the tile definition I'm using is incomplete.
I look forward to its arrival. It's got to be better than banging my head on my TV
I'll try 32 longs later as it's definitely time for bed in my part of the world (5am).
Taking TV_Text_Demo.spin as delivered and modifying TV_Text.Spin as follows -
Optionally, modify TV_Text_Demo.spin as follows -
The only unexpected thing is that the pixel maps are right to left, not left to right as TV.spin describes them.
Post Edited (hippy) : 9/28/2007 1:35:33 AM GMT
I have an applet here for generating characters:
http://www.rayslogic.com/propeller/Programming/Characters.htm
Note that it is for 16x16, 4-color characters right now.
I think I'll only use 16x16 character mode so that I can draw buttons and borders using the built-in font.