Shop OBEX P1 Docs P2 Docs Learn Events
Changing TV display colors — Parallax Forums

Changing TV display colors

EmptyBitEmptyBit Posts: 72
edited 2010-12-28 00:28 in Propeller 1
I am making great progress on my voicing counter display. This color thing is a real hangup. Although after it is operator selected, I'd hope to store the setting somehow to be retained on the next bootup. Any insight on that would be helpful as well.

I have yet to make much sense out of the colors for NTSC video. I have read many different threads, on and off these forums and still cannot get the concept for debugging this code. Some colors work as expected and some don't. The yellow or blue background does not get along. I get odd colors and gradients that seems to change luminance or some value in the color scheme.
What am I missing out on here?
How can this be resolved?
Is there a better method?

$0
''***************************************
''*  Voiced Counter & Display           *
''*                                     *
''*                                                 *
''*  Copyright (c) 12/23/2010           *               
''*  See end of file for terms of use.  *               
''***************************************


CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
  _stack = ($2800 + 100) >> 2   'accomodate display memory and stack

  x_tiles = 16
  y_tiles = 10

  paramcount = 14       
  bitmap_base = $5000
  display_base = $5000

  lines = 5
  thickness = 2
  bufferlen = 400


VAR

  long  mousex, mousey
 
  long  tv_status     '0/1/2 = off/visible/invisible           read-only
  long  tv_enable     '0/? = off/on                            write-only
  long  tv_pins       '%ppmmm = pins                           write-only
  long  tv_mode       '%ccinp = chroma,interlace,ntsc/pal,swap write-only
  long  tv_screen     'pointer to screen (words)               write-only
  long  tv_colors     'pointer to colors (longs)               write-only               
  long  tv_hc         'horizontal cells                        write-only
  long  tv_vc         'vertical cells                          write-only
  long  tv_hx         'horizontal cell expansion               write-only
  long  tv_vx         'vertical cell expansion                 write-only
  long  tv_ho         'horizontal offset                       write-only
  long  tv_vo         'vertical offset                         write-only
  long  tv_broadcast  'broadcast frequency (Hz)                write-only
  long  tv_auralcog   'aural fm cog                            write-only

  word  screen[x_tiles * y_tiles]
  long  colors[64]

  long  newcolor
  long  old1, old2, old3, old4
  long  D1, D2, D3, D4
  long  f_ext
  byte  f_name1
  byte  f_name2[2]
  byte  f_name_ext[6]
  byte buff[bufferlen]
OBJ
  'vp : "Conduit"  'Include this to set up ViewPort
 ' 
  tv    : "tv" 
  gr    : "graphics" 
  mouse : "mouse"
  
  

PUB start | i, dx, dy, numx



  longmove(@tv_status, @tvparams, paramcount)
  tv_screen := @screen
  tv_colors := @colors
  tv.start(@tv_status)
  

  'init colors
  numx := 1
  colorswap(NUMX)
  
  'repeat i from 0 to 63
    'colors[i] := $00001010 * (i+4) & $F + $2B020C07    '2B_Foreground_0C_Background color
                                                            '1C=Blue        07=White
                                                            '8E=Yellow      02=Black
                                                            '07=White       02=Black 
                                                            '02=Black       07=White

  'init tile screen                                         
  repeat dx from 0 to tv_hc - 1
    repeat dy from 0 to tv_vc - 1
      screen[dy * tv_hc + dx] := display_base >> 6 + dy + dx * tv_vc + ((dy & $3F) << 10)



  'start and setup graphics
  gr.start
  gr.setup(16, 10, 128, 72, bitmap_base)          '(x_tiles, y_tiles, x_origin, y_origin, base_ptr)

  'start mouse
  mouse.start(24, 25)

  D1 := D2 := D3 := D4 := "0"
  longmove(@old1, @D1, 4)


  'set font
  gr.textmode(10,16,6,5)      'textmode(x_scale, y_scale, spacing, justification)
                                 'my counter set at (10,16,6,5)

  'D1 := D2 := D3 :=D4 :="9"                               
  repeat
    'clear only changed area
    gr.colorwidth(0,8)    'text color and width  0,8
    dx := 70
    if old2<>D2
      dx += 65
    if old3<>D3
       dx += 65
    if old3<>D3
       dx += 65
    gr.box(135-dx,-72, dx, 142)

    'draw digits
    gr.colorwidth(2,8)    'text color and width  2, 8
    gr.text(-95,0,@D4)
    gr.text(-30,0,@D3)
    gr.text(35,0,@D2)
    gr.text(100,0,@D1)
   
    longmove(@old1, @D1, 4)   'copy new digits to old
    
   
    repeat until mouse.button(0)
      
      if mouse.button(1)
         repeat while mouse.button(1)
         numx := numx+1
         if numx > 7
            numx := 1 
         colorswap(numx) 
        

    repeat while mouse.button(0)
 

Pri colorswap(NUMX) | i                                                          
    
    case numx                                 '   Foreground     Background color
        $1 :                                        
           newcolor := $2B1B0C07                     '1B=Blue        07=White 
        $2 :                                        
           newcolor := $2B070C1B                     '07=White       1B=Blue  
        $3 :                                        
           newcolor := $2B8E0C1B                     '8E=Yellow      1B=Blue
        $4 :
           newcolor := $2B8E0C02                     '8E=Yellow      02=Black
        $5 :
           newcolor := $2B020C8E                     '02=Black       8E=Yellow           
        $6 :
           newcolor := $2B070C02                     '07=White       02=Black 
        $7 :
           newcolor := $2B020C07                     '02=Black       07=White


  repeat i from 0 to 63
     colors[i] := $00001010 * (i+4) & $F + newcolor        
     tv_colors := @colors  

return              
DAT

tvparams                long    0               'status
                        long    1               'enable
                        long    %001_0101       'pins
                        long    %0000           'mode
                        long    0               'screen
                        long    0               'colors
                        long    x_tiles         'hc
                        long    y_tiles         'vc
                        long    10              'hx
                        long    1               'vx
                        long    0               'ho
                        long    0               'vo
                        long    0               'broadcast
                        long    0               'auralcog

Comments

  • potatoheadpotatohead Posts: 10,261
    edited 2010-12-27 00:42
    http://forums.parallax.com/showthread.php?123709-Commented-Graphics_Demo.spin

    Take a good look through that commented version of graphics demo. The trouble you've got, is in the array that defines the colors. Try the methods in the commented program and you can trace through to see how the colors work easily. Each colors long specifies 4 colors, and those apply to all the tiles referencing that long in the colors array. You get sets of color, which you can assign to tiles. Once those are assigned, the color values 00, 01, 10, 11 then take on those colors within the tile.
  • EmptyBitEmptyBit Posts: 72
    edited 2010-12-27 18:36
    Thanks for the response potatohead. I have had that file now for 2 months and read the thread several times. I comprehend the principle in the documentation, but working the comparison to what I have modified, just did not work as expected. Possibly what threw me off was the bit manipulation in the following code.
      repeat i from 0 to 63
         colors[i] := $00001010 * (i+4) & $F + newcolor        
         tv_colors := @colors  
    

    The original uses hex instead of binary. The background color was being thrashed by the 10? The following code modification has it working bug free!
      repeat i from 0 to 63
         colors[i] := $00001000 * (i+4) & $F + newcolor        
         tv_colors := @colors  
    


    Now dare I ask, is there an explanation as to why the 10 was there in the first place? I don't see any obvious changes to the graphics demo version, although the array will reflect the change; the background color never changes in this particular demo.


    What is more important here is this lesson forced me to learn greater details on my own. I cannot say it is all perfectly clear, but this is resolved.

    Now on to storing the settings to the SD card or eeprom for booting it as set. Any pointers on this plan?

    $0
  • potatoheadpotatohead Posts: 10,261
    edited 2010-12-27 18:56
    The bitmask was simply to get a specific color set, based off the index values. All that really does is populate the 64 palette entries with some colors. You actually don't even need it.

    In the file I linked, I've got that array in the dat section. Just put the sets of colors you want, somewhere in the Propeller memory, then point the tiles to them, by changing the lower order bits in the screen array. The methods in that file show you how this is done.

    There is one array entry per tile. All the tiles can simply use one long for their color definition, if you want to do it that way. In that case, you would have a 4 color screen.

    If you need 8 colors, then you define two colors array elements, and put 4 colors in one, 4 in the other, then assign those to the tiles as needed.

    That concept can be expanded up to the 64 palettes possible, with the limitation of there being only 4 colors per tile.

    As for the storing to the EEPROM or SD card, that's easy. Just put all your stuff in a DAT, and write the program to the EEPROM. That's what DAT area storage is good for, again demonstrated in the file I linked you to.

    The math and loops in the original demo are fine for dynamically generating colors and such. Not necessary for most things.
  • EmptyBitEmptyBit Posts: 72
    edited 2010-12-27 20:15
    Ok, I'll try adapting the concepts you have there in my counter to set the colors. I really only need 2 color screens within options for my application to achieve high contrast.

    I tried setting the array populating section posted above to 4 instead of 63. The screen did not like that. Changing it to the following still works. Which follows your idea that the colors in a DAT section would work as well, although here it seems to need at least an array of 10 to complete the screen. This may be due to the method that applies the tile data.
      repeat i from 0 to 9
         colors[i] := newcolor        
         tv_colors := @colors 
    

    Maybe I was not clear on the SD/eeprom storage. My plan is for the program to retain the color setting. If the operator wants blue BG with yellow FG, I would rather they did not need to scroll back through each time it boots after a power down to reset their color preference again.

    I expect this would take writing the current numx for "newcolor" dat to the SD or prom. Unless you are talkng about self modifying code. I have no experience there yet.

    $0
  • potatoheadpotatohead Posts: 10,261
    edited 2010-12-27 20:36
    Each tile, which is represented by a word in the "screen" array gets assigned to one of the longs in the "colors" array. In the file I linked, all the tiles are pointed to the same color long.

    That's a 4 color display, where you can choose to just use two of them.

    If you incorporate this change:
    repeat dx from 0 to tv_hc - 1
        repeat dy from 0 to tv_vc - 1
          screen[dy * tv_hc + dx] := display_base >> 6 + dy + dx * tv_vc '+ ((dy & $3F) << 10)
    
      'I've commented out the original Parallax color scheme, which means all tiles are referencing
      'Color Palette entry 0
    
    To your program, all the screen tiles will be pointing to color array element 0.

    Then, just do colors[0] := your colors!

    There is no syntax highlighting, so remove this "+ ((dy & $3F) << 10)" from your program to change how it sets up the screen array, and the tile color palette indexes.
  • EmptyBitEmptyBit Posts: 72
    edited 2010-12-27 20:47
    That's funny....that is what I just changed as a first trial before putting in the dat area. :D

    That is what I meant by what was applying the tile data could be the problem....I guess that means some of this reading is sinking in.

    I am grateful to have your assistance.

    $0
  • potatoheadpotatohead Posts: 10,261
    edited 2010-12-27 20:51
    Yeah, so do that, then do this:

    DAT

    colors long $07050302 (all greys)

    long $07060504 (lighter greys)

    ... etc..

    And you are set! Get rid of the colors array in the VAR section, and just make as many DAT entries as you need. Those will go to the EEPROM. You can get rid of that colors loop too. It's not needed in your case.
  • EmptyBitEmptyBit Posts: 72
    edited 2010-12-27 21:45
    What a deal. I amaze me self that I even understand this programming sometimes!

    I can't help being satisfied with steps forward. Much appreciated Potatohead!


    ''***************************************
    ''*  Voiced Counter & Display           *
    ''*                                     *
    ''*   *
    ''*  Copyright (c) 12/23/2010           *               
    ''*  See end of file for terms of use.  *               
    ''***************************************
    
    
    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      _stack = ($2800 + 100) >> 2   'accomodate display memory and stack
    
      x_tiles = 16
      y_tiles = 10
    
      paramcount = 14       
      bitmap_base = $5000
      display_base = $5000
    
      lines = 5
      thickness = 2
      bufferlen = 400
    
    
    VAR
    
      long  mousex, mousey
     
      long  tv_status     '0/1/2 = off/visible/invisible           read-only
      long  tv_enable     '0/? = off/on                            write-only
      long  tv_pins       '%ppmmm = pins                           write-only
      long  tv_mode       '%ccinp = chroma,interlace,ntsc/pal,swap write-only
      long  tv_screen     'pointer to screen (words)               write-only
      long  tv_colors     'pointer to colors (longs)               write-only               
      long  tv_hc         'horizontal cells                        write-only
      long  tv_vc         'vertical cells                          write-only
      long  tv_hx         'horizontal cell expansion               write-only
      long  tv_vx         'vertical cell expansion                 write-only
      long  tv_ho         'horizontal offset                       write-only
      long  tv_vo         'vertical offset                         write-only
      long  tv_broadcast  'broadcast frequency (Hz)                write-only
      long  tv_auralcog   'aural fm cog                            write-only
    
      word  screen[x_tiles * y_tiles]
      long  old1, old2, old3, old4
      long  D1, D2, D3, D4
      long  f_ext
      byte  f_name1
      byte  f_name2[2]
      byte  f_name_ext[6]
      byte buff[bufferlen]
    OBJ
      'vp : "Conduit"  'Include this to set up ViewPort
     ' 
      tv    : "tv" 
      gr    : "graphics" 
      mouse : "mouse"
      
      
    
    PUB start | i, dx, dy, numx
    
    
      longmove(@tv_status, @tvparams, paramcount)
      tv_screen := @screen
      tv_colors := @colors
      tv.start(@tv_status)
      
    
      'init colors
      numx := 0
      colorswap(NUMX)
      
    
      'init tile screen                                         
      repeat dx from 0 to tv_hc - 1
        repeat dy from 0 to tv_vc - 1
          screen[dy * tv_hc + dx] := display_base >> 6 + dy + dx * tv_vc 
    
    
    
      'start and setup graphics
      gr.start
      gr.setup(16, 10, 128, 72, bitmap_base)          '(x_tiles, y_tiles, x_origin, y_origin, base_ptr)
    
      'start mouse
      mouse.start(24, 25)
    
      D1 := D2 := D3 := D4 := "0"
      longmove(@old1, @D1, 4)
    
    
      'set font
      gr.textmode(10,16,6,5)      'textmode(x_scale, y_scale, spacing, justification)
                                     'my counter set at (10,16,6,5)
    
      'D1 := D2 := D3 :=D4 :="9"                               
      repeat
        'clear only changed area
        gr.colorwidth(0,8)    'text color and width  0,8
        dx := 70
        if old2<>D2
          dx += 65
        if old3<>D3
           dx += 65
        if old3<>D3
           dx += 65
        gr.box(135-dx,-72, dx, 142)
    
        'draw digits
        gr.colorwidth(2,8)    'text color and width  2, 8
        gr.text(-95,0,@D4)
        gr.text(-30,0,@D3)
        gr.text(35,0,@D2)
        gr.text(100,0,@D1)
       
        longmove(@old1, @D1, 4)   'copy new digits to old
        
       
        repeat until mouse.button(0)
          
          if mouse.button(1)
             repeat while mouse.button(1)
             numx := numx+1
             if numx > 7
                numx := 0 
             colorswap(numx) 
            
    
        repeat while mouse.button(0)
     
    
    Pri colorswap(NUMX)                                                          
           
         tv_colors := @colors[numx]  
    
    return              
    DAT
    
    tvparams                long    0               'status
                            long    1               'enable
                            long    %001_0101       'pins
                            long    %0000           'mode
                            long    0               'screen
                            long    0               'colors
                            long    x_tiles         'hc
                            long    y_tiles         'vc
                            long    10              'hx
                            long    1               'vx
                            long    0               'ho
                            long    0               'vo
                            long    0               'broadcast
                            long    0               'auralcog
                          
                                                                '   Foreground     Background color 
    colors                  long    $00_1B_00_07                     '1B=Blue        07=White
                            long    $00_07_00_1B                     '07=White       1B=Blue
                            long    $00_8E_00_1B                     '8E=Yellow      1B=Blue
                            long    $00_1B_00_8E                     '8E=Blue        1B=Yellow 
                            long    $00_8E_00_02                     '8E=Yellow      02=Black
                            long    $00_02_00_8E                     '02=Black       8E=Yellow
                            long    $00_07_00_02                     '07=White       02=Black
                            long    $00_02_00_07                     '02=Black       07=White     
                            
                          
    


    The reason for having the pri colorswap was for saving the setting to retain it somehow to restore it on boot. I will also be restoring the display count anyways as well.

    $0
  • potatoheadpotatohead Posts: 10,261
    edited 2010-12-28 00:28
    Well cool. Glad you got it working.
Sign In or Register to comment.