Shop OBEX P1 Docs P2 Docs Learn Events
VGA long color modification — Parallax Forums

VGA long color modification

T ChapT Chap Posts: 4,223
edited 2012-08-25 13:08 in Propeller 1
Is there a way in spin to modify the 2 colors in the longs for a 1 bit vga color? I would like to be able to change the colors of each ff and bg in spin on the fly versus having to change the longs or have a long list to choose from.


'ff bg ff bg ff = graphic, bg = background
'ff ff bg bg
DAT

vgacolors    
                        long    $FC00FC00       'white graphics  blk bg
                        long    $FCFC0000

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-08-24 19:29
    Yes, it's definitely possible and quite easy to pull off. Just haave the video driver read the colors from the hub during the vertical sync interval.

    -Phil
  • T ChapT Chap Posts: 4,223
    edited 2012-08-24 21:24
    Thanks Phil. Here is how I did it:
      long vga[6]
      byte white, green, black, red
    
    pub Main|i,j
    '$FC00FC00
    '$FCFC0000
    '$c000c000
    '$c0c00000
    '$30003000
    '$30300000
    
      white := $FC
      red := $C0
      green := $30
      black := $00
    
      bb := black
      ff:= white
      vga.byte[0] := bb
      vga.byte[1] := ff
      vga.byte[2] := bb
      vga.byte[3] := ff
      vga.byte[4] := bb
      vga.byte[5] := bb
      vga.byte[6] := ff
      vga.byte[7] := ff
      ff := red
      vga.byte[8] := bb         'c000c000
      vga.byte[9] := ff
      vga.byte[10] := bb
      vga.byte[11] := ff
      vga.byte[12] := bb
      vga.byte[13] := bb
      vga.byte[14] := ff
      vga.byte[15] := ff
      ff := green
      vga.byte[16] := bb         'c000c000
      vga.byte[17] := ff
      vga.byte[18] := bb
      vga.byte[19] := ff
      vga.byte[20] := bb
      vga.byte[21] := bb
      vga.byte[22] := ff
      vga.byte[23] := ff
    

    This makes it much easier to assign colors for use later.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-08-25 01:28
    I'm not sure if this is close to what you're after or not.

    I use this method to change VGA colors in one of my touchscreen programs.
    PUB SetColor(text, background)
    ''  result used as a local variable
      
      if colorIndex > 0
        if text == oldColorText[colorIndex - 1] and background == oldColorBackground[colorIndex - 1]
          print($110 + colorIndex - 1)                        ' use last color
          return
        else  
          repeat result from 0 to colorIndex - 2            ' We already know it's not colorIndex - 1
            if text == oldColorText[result] and background == oldColorBackground[result]
              print($110 + result)                          ' use earler color
              return
      ' new color to generate
      gobalColor :=  byte[@colorPalete + text]
      gobalColor <<=  8
      gobalColor +=  byte[@colorPalete + background]
      gobalColor <<=  8
      gobalColor +=  byte[@colorPalete + text]
      gobalColor <<=  8
      gobalColor +=  byte[@colorPalete + background]
     
      longmove(@vgacolors + (colorIndex * 8), @gobalColor, 1)
         
      gobalColor :=  byte[@colorPalete + text]
      gobalColor <<=  8
      gobalColor +=  byte[@colorPalete + text]
      gobalColor <<=  8
      gobalColor +=  byte[@colorPalete + background]
      gobalColor <<=  8
      gobalColor +=  byte[@colorPalete + background]
         
      longmove(@vgacolors + (colorIndex * 8) + 4, @gobalColor, 1)
        
        
      oldColorText[colorIndex]  := text
      oldColorBackground[colorIndex] := background
        
      print($110 + colorIndex++)
      colorIndex <#= $0F
      
    
    Here are some of the global variables used in the above object.

    CON      
      _MaxColors = 16
    
    VAR
      long globalIndex, gobalColor    
      
      byte oldColorText[_MaxColors], oldColorBackground[_MaxColors], colorIndex
     
    


    This still requires a list of colors to choose from. I have the list in a "DAT" section.
    DAT
    vgacolors               long 0[32]                  'reserved for colors
    
    DAT
    
      
    colorPalete   byte $00, $01, $04, $08, $0C, $10, 14, $18, $1C, {
                     } $20, $24, $28, $2C, $30, $34, $38, {
                 $3C,} $FC, $C0, {$20,} $F0, $CC, $28, $40, $20, $E0, $D0, {
                     }    $00[16]
                                                            {$00[16] is memory reserved for temp colors}
      ' The color easterEgg (which is $01 black) is a flag for PrintButton method not to print anything to the screen
      ' but to keep an area of the screen as an invisible button.
      
    CON    '' Color enumeration  
      #0, _Black, _EasterEgg, _Blue1, _Blue2, _Blue, _Green1, _BlueGreen1, _Greenish1Blue2, _Greenish1Blue, { 0-8
        } _Green2, _Blueish1Green2, _Greenish2Blue2, _Greenish2Blue, _Green, _Blueish1Green, _Blueish2Green, { 9-15
        }_White, _Red, _Yellow{, _Green}, _Purple, _Cyan, _FRed, _FGreen, _YellowOrange, _Orange, { 16-24
      '  } _FirstTempColor
      
    
    

    The list of names under "Color enumeration" corresponds with the byte sized color codes in "colorPalete". For example, element #3 of "colorPallete" is "$08". "_Blue2" is the constant name associated with this color since the value of "_Blue2" is 3.

    Instead of having to remember to use "$08" whenever the second alternative blue color is to be used, I can use "colorPalete[_Blue2]". The first method I listed takes the byte color codes for the text and the background color and fills these values into the long "gobalColor".

    The first portion of the method "SetColor" allows me to keep track of which color combinations are being used in the current menu. You probably don't need this book keeping code yourself.
  • potatoheadpotatohead Posts: 10,261
    edited 2012-08-25 12:13
    Edit: Never mind. I see your post above. Whoops! Oh well, I'll leave this here for others.

    What do you mean, "on the fly?"

    When using the color palette method to assign colors, there are two layers to it. One is the tile to palette assignment. The other is the palette entry to color value assignment.

    If you assign all your tiles to one palette, you've got a 4 color screen at that point. Only one palette entry is then required, no list. This simplifies the colors down to just the palette entry values.

    From there, if you want to change a color mid-screen, you could wait for the VBLANK, then change it sometime afterword basically using one palette entry for two color values. Of course, if you do that, you also need to put it back during VBLANK so that the original value, not the secondary one is present for the drawing of the upper part of the screen.

    That's complicated though, requires timing and complexity.

    You might mean, just being able to change the color anytime when you say, "on the fly". In that case, just change the palette entry directly anytime you want! Again, if you've set all your tiles to the same palette, you have a 4 color screen. Changing the palette entry would just change one of those four colors.

    That's the minimum for filling the screen with pixels in color.

    If you want to then have more than 4 colors on the screen, simply add another palette entry, and assign tiles to that palette. Say that's 4 colors for the top half, and four colors for the bottom. Assign the top half to palette 0, bottom to palette 1.

    Then change the entries as you need. The more colors you require, and the more screen regions you find necessary, the more palettes you define. The "Parallax Colors Simplified" in my signature highlights doing this. It's for graphics_demo.spin, but the general technique is applicable for any Parallax style tile drivers. That's VGA.spin and TV.spin for sure. I am pretty sure it's the HEL driver found on the HYDRA CD as well, and there are probably others.

    IMHO, this color flexibility is actually very useful. Most drivers out there don't include the color redirection capability, either being limited in colors on screen, or requiring absolute colors, which don't allow for image changes without also redrawing all the pixels.
  • RaymanRayman Posts: 14,826
    edited 2012-08-25 12:36
    The VGA_Text_Demo shows one way to do this...

    Here's the code that sets the colors:
    PUB setcolors(colorptr) | i, fore, back
    '' Override default color palette
    '' colorptr must point to a list of up to 8 colors
    '' arranged as follows (where r, g, b are 0..3):
    ''
    ''               fore   back
    ''               ------------
    '' palette  byte %%rgb, %%rgb     'color 0
    ''          byte %%rgb, %%rgb     'color 1
    ''          byte %%rgb, %%rgb     'color 2
    ''          ...
      repeat i from 0 to 7
        fore := byte[colorptr][i << 1] << 2
        back := byte[colorptr][i << 1 + 1] << 2
        colors[i << 1]     := fore << 24 + back << 16 + fore << 8 + back
        colors[i << 1 + 1] := fore << 24 + fore << 16 + back << 8 + back
    
    

    And here are the default color definitions:
                           '        fore   back
                            '         RGB    RGB
    palette                 byte    %%333, %%001    '0    white / dark blue
                            byte    %%330, %%110    '1   yellow / brown
                            byte    %%202, %%000    '2  magenta / black
                            byte    %%111, %%333    '3     grey / white
                            byte    %%033, %%011    '4     cyan / dark cyan
                            byte    %%020, %%232    '5    green / gray-green
                            byte    %%100, %%311    '6      red / pink
                            byte    %%033, %%003    '7     cyan / blue
    

    You can just make your own "palette" definitions, say "palette2" and then call SetColors(palette2)
  • T ChapT Chap Posts: 4,223
    edited 2012-08-25 12:59
    What I mean by on the fly is, to be able to change any color as needed anytime. The method I posted is basically the same as the original, except I moved the longs with the color values to the VAR section and allowed each of the two colors of the 1bit bitmap dat files to be changed more easily than having to edit the longs in the DAT section. I will look at the other examples you guys posted too.
  • potatoheadpotatohead Posts: 10,261
    edited 2012-08-25 13:08
    That's easy. You just need to decide how best to edit the color values in the palette entry. Lots of choices on that.

    Sometimes "on the fly" can get complicated, because it can mean, "while the image is being drawn." In any case, the palettes are not static. The moment you change them, the on screen color will change on the very next tile that references that palette.
Sign In or Register to comment.