Shop OBEX P1 Docs P2 Docs Learn Events
2-bit gui — Parallax Forums

2-bit gui

RaymanRayman Posts: 14,642
edited 2017-02-13 01:13 in Propeller 2
So, the 4-bit gui seems workable. But, I wanted to try a 2-bit gui before going all in.

2-bits lets us use P1 ROM font and allows higher resolutions.
The font also looks smoother than with the 4bpp mode because the characters are 16x32 instead of 8x16.

This is just a test at VGA and XGA resolution (tested on P2V13, but think will work on P2V15 too):
1632 x 1224 - 808K
«1

Comments

  • RaymanRayman Posts: 14,642
    Next challenge is to figure out how to draw a cursor on top...

    With P1, I did a block cursor, the size of a character, where I basically just inverted and jumbled the colors so you can see where it is.

    Would really like to do an arrow, but not sure if it's possible...
  • kwinnkwinn Posts: 8,697
    Rayman wrote: »
    Next challenge is to figure out how to draw a cursor on top...

    With P1, I did a block cursor, the size of a character, where I basically just inverted and jumbled the colors so you can see where it is.

    Would really like to do an arrow, but not sure if it's possible...

    Nothing wrong with a block cursor. Very easy to see, particularly if you toggle between inverted/non inverted colors when it is over a character.
  • jmgjmg Posts: 15,173
    kwinn wrote: »
    Rayman wrote: »
    Would really like to do an arrow, but not sure if it's possible...

    Nothing wrong with a block cursor. Very easy to see, particularly if you toggle between inverted/non inverted colors when it is over a character.

    I'd agree, text editors use vertical strip or underscore or block cursors, all are ok for char-based cursors.

    A problem with an arrow cursor, is users will expect single-pixel resolution - unless that is what you intended to try ?
  • RaymanRayman Posts: 14,642
    Block cursor is easy, I think.
    But, since the screen is buffered, I could make things like a drawing/Paint app with 4 colors...
    Also, could identify the pixel clicked on in an image.

    But, I guess I should think about these adverse affects of arrow and see if that would cause more pain than it helps...
  • potatoheadpotatohead Posts: 10,261
    edited 2017-02-13 21:33
    Two ways to do an arrow for character displays:

    One way is to add it in as the pixels are put on the scanline. You do the computation during blank, set counters and pointer to mouse pixel data.

    On count condition being met, two character pixel data gets fetched, then the mouse data gets added.

    Another way is to buffer 4 characters. This little buffer is for the mouse and whatever text is under it.

    On each blank, grab the 4 under the mouse, combine them with the mouse and substitute them into the bit stream when it's time.

    For bitmap, it's just counters. Buffer one line always. On blank, and on count, write the arrow into the buffer before it gets streamed.

    That's a two byte read, mask in arrow, write back out. An xor arrow can work nice, as can one that actually picks one single pixel above the tip of the pointer graphic. Most people will get used to this.


  • RaymanRayman Posts: 14,642
    edited 2017-02-14 23:25
    For the 4-character buffer, that could work, but I'd have to reserve 2 of 4 colors in each of the 16 colorsets for the mouse color, or it'd change color as it moved across tiles with different colorsets.

    Was just playing with introducing immediate xcont commands into the scanline.
    Looks like the buffering will let me do two single pixel xconts.
    So, appears a single color cursor might work.
    Think it's because XGA pixel clock is faster than 40 MIPS.
    At 80 MIPS, might be able to do arbitrary colored cursor, for xga anyway.
  • potatoheadpotatohead Posts: 10,261
    edited 2017-02-15 05:44
    The character and line buffering works at any bit depth. It's all about whether the pointer needs it's own color.

    Edit, I didn't see tiles. Yup. Somehow I was thinking 2bpp whole screen.

    The xcont is interesting! Novel thinking there. :D



  • An example of monochrome pointer. Just for grins.

  • RaymanRayman Posts: 14,642
    Problem is the tip of the pointer...
    First line is one pixel of white, that's OK.
    Second line is the problem. One white, one black and then one white again...
  • RaymanRayman Posts: 14,642
    Might be able to do a 2-tone cursor like this:
  • potatoheadpotatohead Posts: 10,261
    edited 2017-02-15 18:17
    Could work.

    Was thinking about colors. Truth is, let the pointer change.

    A single pointer color can work when it's different from the others.

    From there, let the people decide. They get three per tile. Or pointer changes. Planning for that isn't tough to do.

    SGI had a bright red pointer. Worked well almost all the time.
  • potatoheadpotatohead Posts: 10,261
    edited 2017-02-15 18:16
    And if %11 is that color, OR into line buffer is cake.

    And don't the Parallax fonts use %00, 10, 01?
  • Other options:

    Small 4x4 pixel block. A corner is the tip. Same size cross hair. Those are very unobtrusive. Should work with the two pixel limit.

    Can you show me a code snippet of doing the xcont?

  • RaymanRayman Posts: 14,642
    Uh oh, just found at least one flaw with that xcont idea...
    Problem is that even if I tell it to do less that 16 pixels, the pixels always come from end of the long and I need to shift them...

    For this to have any chance, I'd need to change from xcont RFLONG LUT mode to separate RFLONG and xcont Immediate commands, with some shifts in between...

    Maybe that doesn't work, have to see...
    getnib  cnib,c,#3               'nib#3
                    setnib  m_rf2,cnib,#4
                    xcont   m_rf2,#0
    
                    'test cursor idea
                    getnib  cnib,c,#4               'nib#4
                    'setnib  m_rf2,cnib,#4                
                    'xcont   m_rf2,#0
    
                    setnib  m_rf2b,cnib,#4
                    'setnib  m_rf2a,cnib,#4
                    xcont   m_rf2b,#0
                    xcont   m_rf2c,##$FFFF0000
                    'xcont   m_rf2d,##$FF000000
                    'xcont   m_rf2d,##$00000000  
                    'xcont   m_rf2b,#0
    
    m_rf2b           long    $5F000000+12 'one 16pixel tile wide@2bpp=1long             '2bit RFLONG LUT '4bit RFLONG LUT $7F000000+640           'visible rlong 8bpp lut
    m_rf2c           long    $CF000000+4 'immediiate one 16pixel tile wide@2bpp=1long             '2bit RFLONG LUT '4bit RFLONG LUT $7F000000+640           'visible rlong 8bpp lut
    m_rf2d           long    $CF000000+3 'immediiate one 16pixel tile wide@2bpp=1long             '2bit RFLONG LUT '4bit RFLONG LUT $7F000000+640           'visible rlong 8bpp lut
    
  • potatoheadpotatohead Posts: 10,261
    edited 2017-02-16 00:00
    You could convert the tile lines, associated with the pointer, to a higher color mode during blank, then add in the pointer, so it's all ready to go.

    When you get to a pointer line, use a different draw loop, and in it, change depths for part of that line, or maybe the whole line, and only need a small buffer and would have a lot of time to do it.

    That way, you have the extra colors needed. If you used 4bpp, it would all work out and you could do a nice pointer, outline and all, if you want.



  • RaymanRayman Posts: 14,642
    That sounds like a good idea...
  • RaymanRayman Posts: 14,642
    If we had 160 MHz clock, then could do single pixel xconts at XGA resolution.
    This is puzzle with 80 Mhz clock though.

    Think I'll see if I can rotate pixels where I need to during vertical refresh...
  • RaymanRayman Posts: 14,642
    Hmm... Another problem is that if I make the width of the cursor 16 pixels, then there could be a case where I'd need xcont with 0 pixels. Not sure that would work...

    My two-tone cursor was only 13 pixels at widest point though.

    With that each xcont from buffer would always take at least one pixel, I think.
    A block around a two color cursor spanning at most 6 tiles would need at most 26 colors.
    Could use the currently free values in first 256 longs of LUT to hold these colors.
    Then, create this say 13x20 pixel block of 8-bpp LUT in cog RAM.
    Use the xcont LUT 8bpp immediate mode to

  • RaymanRayman Posts: 14,642
    edited 2017-02-16 01:14
    actually, the tile colors are already in LUT and the cursor colors could be too...
    The cursor pixels in 13x20 block would be static, only need to change the background pixels to match the screen...

    Actually, 12x20 would be more convenient as it's three longs wide...
  • potatoheadpotatohead Posts: 10,261
    edited 2017-02-16 03:25
    Seems like a plan.

    Also seems to me, one could set this all up on a nice, even tile boundary by just shifting the pointer too, should timing get funky. This does mean buffering the pointer somewhere, but it also might break down per tile nicely too. You never have a quick change, relative to the instruction speed.

    Four draw loops, potentially.

    One normal one, non pointer lines. (2222222222222222222222)

    One two segment, higher bpp, then 2bpp. (hhh22222222222222222)

    One other two segment, 2bpp, then higher bpp. (22222222222222222222hhh)

    One three segment, 2bpp, higher bpp, 2bpp. (2222222hhh222222222222)

    And maybe it's just two: Normal, and segmented. Seems like there is time to make that conditional, but this is worst case.

    I did test changing streamer color depth mid scan line some time back. It worked, but a bit of scanline time could get lost, depending on when the streamer ended and the next instruction to fire it off again happened.

    Sent that one to Chip, and the answer was a double command buffer to insure streams happened back to back.
  • RaymanRayman Posts: 14,642
    edited 2017-02-19 22:20
    It's been a huge puzzle to figure out how to put a cursor on top of 2bpp tiles,
    But I think I have it...

    You can see in the image a 2x2 tiles area that is replaced by 4bpp data (the red, yellow, white, blue bars near the bird's head).

    Tried really hard to make 8bpp cursor work, but just not enough clocks...

    4bpp may work out really well anyway as the colors are divided into 16 sets of 32 colors.
    The first four colors in each set are used for displaying the 2bpp tiles. That leaves 28 colors that can be used for the cursor. I'm planning on just copying those 28colors to all 16 sets.
    Then, I can use the same set that the tile would have used for 2bpp buffer with the 4bpp cursor on top of buffer data.

    Next question is if there is enough time during vertical refresh to construct the 4bpp cursor area... If not, I'll have to bring in another cog to do it...
  • That's great work!
  • RaymanRayman Posts: 14,642
    It's actually 16 sets of 32 colors, so 28 colors for cursor... I've updated the above...

    Really need to turn 2bpp P1 interleaved font into 1bpp non-interleaved font.
    With only 16 sets of colors, don't want to use 2 sets for each fore/back color combo.
    With 1bpp font, can have many more color combo options...
  • jmgjmg Posts: 15,173
    Rayman wrote: »
    You can see in the image a 2x2 tiles area that is replaced by 4bpp data (the red, yellow, white, blue bars near the bird's head).

    Looks nifty.
    Rayman wrote: »
    Next question is if there is enough time during vertical refresh to construct the 4bpp cursor area... If not, I'll have to bring in another cog to do it...

    I would think there is, plus real cursors only move sporadically, so have a number of options..
    * You could spread the render over more than one frame, with priority given to the cursor element
    eg Google earth renders in more than one pass.
    * You could use interrupts, so the scan stuff gets priority and the cursor background render is done using lower priority sysclks, when available.
    * A quick check for 'no movement or changes' would skip the render update. Mostly, this path is taken.


  • RaymanRayman Posts: 14,642
    This has been some difficult and complex coding, but I now think this cursor idea is going to work. The attached code shows 32 pixels wide by cursor height 4bpp data in the area where the cursor is. I still need to shift the cursor within these 32 pixels to the proper location, but this shows that the concept works.

    Right now, it shows a red cursor that jumps around on the screen.

    This method gives 28 available colors for the cursor. What's even better is that I can use 4 of those colors to create a darkened version of all the 2bpp colors. This allows for a cursor that casts a shadow, just like newer versions of PC OS do.

    Anyway, this is about a million times more complex than a block cursor, but I think it's worth it...
    1632 x 1224 - 683K
  • jmgjmg Posts: 15,173
    Rayman wrote: »
    ....
    Anyway, this is about a million times more complex than a block cursor, but I think it's worth it...

    What is the code size and cycles overhead for running this advanced cursor ?
  • RaymanRayman Posts: 14,642
    edited 2017-02-25 12:48
    Needs a cog and code to run it, not much more...

    BTW: The other nice thing about doing the cursor this way is that I'm not messing with the underlying 2bpp screen buffer. That is nice because I don't have to suspend the cursor when drawing on the screen, like have to with my 4bpp driver.

    Also, might be able to bring in Chip's P1 graphics code...
  • RaymanRayman Posts: 14,642
    Ok, I think I've proven to myself that this can work.
    Can do windows and buttons with P1 rom font.
    Can also make shadows.
    Cursor can work.
    Now, have to think about 2bpp gui versus 4bpp gui...

    1632 x 1224 - 548K
  • cgraceycgracey Posts: 14,152
    Rayman wrote: »
    Ok, I think I've proven to myself that this can work.
    Can do windows and buttons with P1 rom font.
    Can also make shadows.
    Cursor can work.
    Now, have to think about 2bpp gui versus 4bpp gui...

    That screen image is looking really good.
Sign In or Register to comment.