#
# --------------------------------------------------------------------
# The CCF File Format
#
# The CCF File format begins with a CCF Header. The type of this header
# depends on the values of header->version1 and header->version2. You
# can read these values at fixed offsets to choose the correct format
# for decoding. Once the header is read, the rest of the objects can
# be found using absolute offset pointers. All formats are big endian.
# --------------------------------------------------------------------
#

#
# --------------------------------------------------------------------
# Object types
#
#  S* - 4 byte pointer to a length-string (1 byte len + string)
#  S# - where # is an int refers to inline string of specified length
#  N1 - 1 byte integer
#  N2 - 2 byte integer
#  N4 - 4 byte integer
#  Z* - 4 byte pointer to another object (see third column for type)
#  Z+ - array of objects starting at this offset in the object
#     - see third column for length of this array (object field)
#  B+ - inline array of bytes. length comes from another field.
#
# --------------------------------------------------------------------
# Colors
#
# There are two schemes for representing colors. In grayscale Prontos,
# the foreground and background colors are stored in a single byte. In
# color Prontos, the foreground is a single byte and the background is
# three repeat bytes. Notice that foreground and background are switched
# in color and grayscale representations.
#
# A grayscale 'color' byte looks like this: BG BG BG FG
# Where BG and FG are bit pairs that represent one of four levels:
#  00 = black
#  01 = dark gray
#  10 = light gray
#  11 = white
#
# A color integer (4 bytes) looks like this; FG BG BG BG
# where FG and BG are bytes which index into a 256-bit color table.
# --------------------------------------------------------------------
#

#
# --------------------------------------------------------------------
# CCF Object class : Header
#
# ident1 = fixed string "@\245Z@_CCF"
# ident2 = fixed string "CCF\000"
#
# capability = 32 bit field
#   bit 1 .... uses timers
#   bit 2 .... uses udb ir codes
#   bit 16 ... unknown - always set
#   bit 24 ... unknown - possible color flag
#   bit 25 ... unknown - always set on color and marantz x200 devices
#   bit 27 ... marantz x200 extended device keys
#
# attributes = 32 bit field
#   bit 1 .... config read only
#   bit 2 .... home read only
#
# attribPos = offset of attribute field. 60 or 64
# --------------------------------------------------------------------
#

#
# Greyscale Prontos: TSU1000, TSU2000, RU890, RU940, RC5000(i), RC5200
#
[CCFHeader:gray:notimers]

  S*  version
  N4  reserved1
  S8  ident1
  N4  crc1Pos
  N2  time_year
  N1  time_month
  N1  time_day
  N1  reserved2
  N1  time_hour
  N1  time_minute
  N1  time_seconds
  N4  reserved3
  S4  ident2
  N4  capability
  N4  crc2Pos
  N4  attribPos
  Z*  firstHome             CCFDevice:nocolor
  Z*  firstDevice           CCFDevice:nocolor
  Z*  firstMacro            CCFDevice:nocolor
  N4  attributes
  N4  reserved4
  Z*  macroPanel            CCFPanel:nocolor
                           
                           
#
# Greyscale Prontos: TSU2000, RU940, RC5000(i), RAV2000
#
[CCFHeader:gray:timers]         
                           
  S*  version
  N4  reserved1
  S8  ident1
  N4  crc1Pos
  N2  time_year
  N1  time_month
  N1  time_day
  N1  reserved2
  N1  time_hour
  N1  time_minute
  N1  time_seconds
  N4  reserved3
  S4  ident2
  N4  capability
  N4  crc2Pos
  N4  attribPos
  Z*  firstHome             CCFDevice:nocolor
  Z*  firstDevice           CCFDevice:nocolor
  Z*  firstMacro            CCFDevice:nocolor
  Z*  firstTimer            CCFTimer
  N4  attributes
  Z*  macroPanel            CCFPanel:nocolor
  N2  reserved4
                           
                           
#
# Color Prontos: TSU6000, RU970, RC9200
#
[CCFHeader:color:timers]
                           
  S*  version
  N4  reserved1
  S8  ident1
  N4  crc1Pos
  N2  time_year
  N1  time_month
  N1  time_day
  N1  reserved2
  N1  time_hour
  N1  time_minute
  N1  time_seconds
  N4  reserved3
  S4  ident2
  N4  capability
  N4  crc2Pos
  N4  attribPos
  Z*  firstHome             CCFDevice:color
  Z*  firstDevice           CCFDevice:color
  Z*  firstMacro            CCFDevice:color
  Z*  firstTimer            CCFTimer
  N4  attributes
  Z*  macroPanel            CCFPanel:color
  N4  reserved4
  N3  reserved5
  N1  channelID


#
# Color Prontos: TSU6000, RU970, RC9200
#
[CCFHeader:color:notimers]
                           
  S*  version
  N4  reserved1
  S8  ident1
  N4  crc1Pos
  N2  time_year
  N1  time_month
  N1  time_day
  N1  reserved2
  N1  time_hour
  N1  time_minute
  N1  time_seconds
  N4  reserved3
  S4  ident2
  N4  capability
  N4  crc2Pos
  N4  attribPos
  Z*  firstHome             CCFDevice:color
  Z*  firstDevice           CCFDevice:color
  Z*  firstMacro            CCFDevice:color
  N4  attributes
  Z*  macroPanel            CCFPanel:color
  N1  channelID


#
# --------------------------------------------------------------------
# CCF Object class : Device
#
# attributes = 32 bit field
#   bit 1 .... read only
#   bit 6 .... has separator
#   bit 7 .... is template
# --------------------------------------------------------------------
#

[CCFDevice:nocolor]

  Z*  nextDevice            CCFDevice:nocolor
  S*  name
  Z*  iconUnselected        CCFIcon
  Z*  iconSelected          CCFIcon
  Z*  action                CCFActionList
  Z*  keyLeft               CCFActionList
  Z*  keyRight              CCFActionList
  Z*  keyVolMinus           CCFActionList
  Z*  keyVolPlus            CCFActionList
  Z*  keyChanMinus          CCFActionList
  Z*  keyChanPlus           CCFActionList
  Z*  keyMute               CCFActionList
  N4  reserved1
  S*  nameKeyLeft
  S*  nameKeyRight
  Z*  firstPanel            CCFPanel:nocolor
  N1  attributes


[CCFDevice:color]

  Z*  nextDevice            CCFDevice:color
  S*  name
  Z*  iconUnselected        CCFIcon
  Z*  iconSelected          CCFIcon
  Z*  action                CCFActionList
  Z*  keyLeft               CCFActionList
  Z*  keyRight              CCFActionList
  Z*  keyVolMinus           CCFActionList
  Z*  keyVolPlus            CCFActionList
  Z*  keyChanMinus          CCFActionList
  Z*  keyChanPlus           CCFActionList
  Z*  keyMute               CCFActionList
  Z*  keyFarLeft            CCFActionList
  Z*  keyFarRight           CCFActionList
  N4  reserved1
  S*  nameKeyLeft
  S*  nameKeyRight
  S*  nameKeyFarLeft
  S*  nameKeyFarRight
  Z*  firstPanel            CCFPanel:color
  N1  attributes
  N1  rfExtender
  N4  reserved2


[CCFDevice:marantz]

  Z*  nextDevice            CCFDevice:marantz
  S*  name
  Z*  iconUnselected        CCFIcon
  Z*  iconSelected          CCFIcon
  Z*  action                CCFActionList
  Z*  keyLeft               CCFActionList
  Z*  keyRight              CCFActionList
  Z*  keyMute               CCFActionList
  Z*  keyChanMinus          CCFActionList
  Z*  keyChanPlus           CCFActionList
  Z*  keyVolMinus           CCFActionList
  Z*  keyVolPlus            CCFActionList
  Z*  keyM                  CCFActionList
  Z*  keyReturn             CCFActionList
  Z*  keyEx                 CCFActionList
  Z*  arrowUp               CCFActionList
  Z*  arrowLeft             CCFActionList
  Z*  arrowRight            CCFActionList
  Z*  arrowDown             CCFActionList
  N4  reserved1
  N1  attributes
  N1  rfExtender
  N2  reserved2
  S*  nameKeyLeft
  S*  nameKeyRight
  Z*  firstPanel            CCFPanel:color

 
#
# --------------------------------------------------------------------
# CCF Object class : Panel
#
# namePos = a 'S*' string pointer with the notable exception that if
#   the high bit is set, the panel is considered hidden. this makes it
#   somewhat difficult to use a normal 'S*' processing rule.
#
# count1 and count2 should be the same
# --------------------------------------------------------------------
#

[CCFPanel]

  Z*  nextPanel             CCFPanel
  N4  namePos
  N1  count1
  N1  count2
  Z+  child                 CCFChild             ${count1}


#
# --------------------------------------------------------------------
# CCF Object class : Frame
#
# count1 and count2 should be the same
# --------------------------------------------------------------------
#

[CCFFrame:nocolor]

  N2  width
  N2  height
  S*  name
  Z*  icon                  CCFIcon
  N4  reserved
  N1  fontSize
  N1  colors
  N1  count1
  N1  count2
  Z+  child                 ${count1}


[CCFFrame:color]

  N2  width
  N2  height
  S*  name
  Z*  icon                  CCFIcon
  N4  reserved
  N1  fontSize
  N4  colors
  N1  count1
  N1  count2
  Z+  child                 ${count1}


#
# --------------------------------------------------------------------
# CCF Object class : Child
#
# type = child class type where 0=frame and 1=panel
# --------------------------------------------------------------------
#

[CCFChild]

  N2  posX
  N2  posY
  Z*  child                 [CCFFrame,CCFPanel]  ${type}
  N1  type                  


#
# --------------------------------------------------------------------
# CCF Object class : Button
#
# type*Act*Sel where * = Y or N
# Act = active (has an associated action)
# Sel = selected (button pressed)
# --------------------------------------------------------------------
#

[CCFButton:nocolor]

  N2  width
  N2  height
  Z*  actionList            CCFActionList
  S*  name
  S*  idtag
  N1  fontSize
  N1  reserved1
  Z*  iconNActNSel          CCFIcon
  Z*  iconNActYSel          CCFIcon
  Z*  IconYActNSel          CCFIcon
  Z*  iconYActYSel          CCFIcon
  N1  colorNActNSel
  N1  colorNActYSel
  N1  colorYActNSel
  N1  colorYActYSel


[CCFButton:color]

  N2  width
  N2  height
  Z*  actionList            CCFActionList
  S*  name
  S*  idtag
  N1  fontSize
  N1  reserved1
  Z*  iconNActNSel          CCFIcon
  Z*  iconNActYSel          CCFIcon
  Z*  IconYActNSel          CCFIcon
  Z*  iconYActYSel          CCFIcon
  N4  colorNActNSel
  N4  colorNActYSel
  N4  colorYActNSel
  N4  colorYActYSel


#
# --------------------------------------------------------------------
# CCF Object class : Timer
#
# startDays = bit field (0=Mon ... 6=Sun, 7=Weekly)
# endDays = see startDays
# startTime = hour * 60 + min
# endTime = see startTime
# --------------------------------------------------------------------
#

[CCFTimer]

  Z*  nextTimer             CCFTimer
  N1  startDays
  N1  reserved1
  N2  startTime
  N1  endDays
  N1  reserved2
  N2  endTime
  Z1  startAction           CCFAction
  Z1  endAction             CCFAction


#
# --------------------------------------------------------------------
# CCF Object class : ActionList
#
# count1 and count2 should be the same
# --------------------------------------------------------------------
#

[CCFActionList]

  N1  count1
  N1  count2
  Z+  action                ${count1}


#
# --------------------------------------------------------------------
# CCF Object class : Action
#
# type = action type
# p1 = action specific
# p2 = action specific
#
# type           p1             p2                  description
# ----           ----           ----                ----
# 1              0              pointer to code     IR Code
# 2              (Z*) device    (Z*) button         Button Alias
# 3              (Z*) device    (Z*) panel          Jump to Panel
# 4              0              delay in millisecs  Delay
# 5              (Z*) device    key code            Hard Key Alias
# 6              (Z*) device    0                   Device Alias
# 7              0              (Z*) timer          Timer
# 8              0              beep code           Beep
# 9              (Z*) device    (Z*) panel          same as 3, Marantz x200
#
# Key Code       Pronto         ProntoPro           Marantz
# ---------      ------         ---------           -------
# 0              Left           Left                Left
# 1              Right          Right               Right
# 2              Vol-           Vol-                Mute
# 3              Vol+           Vol+                CH-
# 4              CH-            CH-                 CH+
# 5              CH+            CH+                 Vol-
# 6              Mute           Mute                Vol+
# 7                             Far Left            Menu
# 8                             Far Right           End
# 9                                                 Exit
# 10                                                Up Arrow
# 11                                                Left Arrow
# 12                                                Right Arrow
# 13                                                Down Arrow
# 14                                                Home
# 15                                                Light
# 16                                                Back
# 17                                                Ahead
#
# Panel Jump Exceptions (panel pointer is not a pointer)
# ------------------------------------------------------
# 0xbbbbbbbb = Jump Forward
# 0xcccccccc = Jump Back
# 0xdddddddd = Scroll Down
# 0xeeeeeeee = Scroll Up
# 0xffffffff = Mouse Mode
#
# Beep Encoding - four bytes (a b b c)
# -------------
# a = duration in milliseconds / 10 (0-255)
# b = frequency in Hz (0-65535)
# c = duty cycle (0-100)
# --------------------------------------------------------------------
#

[CCFAction]

  N1  type
  N4  p1
  N4  p2


#
# --------------------------------------------------------------------
# CCF Object class : IRCode
#
# 0x0000 = pulse width encoding
# 0x0100 = pulse position encoding
# 0x5000 = RC5 code
# 0x5001 = RC5x code
# 0x6000 = RC6 code
# 0x6001 = RC6x code
# 0x7000 = unknown
# 0x8000 = unknown
# 0x9000 = unknown
#
# 0x0000 Pulse Width Encoding
# ---------------------------
# 2 bytes - header (always 0x0000)
# 2 bytes - frequency base (4194304/freq == Hz)
# 2 bytes - # elements in base sequence (* 2 for # bytes)
# 2 bytes - # elements in repeat sequence (* 2 for # bytes)
# x byte pairs - where x is base sequence 
# x byte pairs - where x is repeat sequence
#
# each byte pair in the base and repeat sequence represents an 'off'
# time and an 'on' time. each time is represented in cycles of the
# frequency base (carrier wave frequency). most sequences consist of
# an optional preamble, a set of two repeating code pairs which can be
# interpreted as 0,1 bits for producing a numeric code and an optional
# suffix.
# --------------------------------------------------------------------
#

[CCFIRCode]

  N2  size
  S*  name
  B+  data                  ${size}-6


#
# --------------------------------------------------------------------
# CCF Object class : Icon
#
# type = 16 bit field
#   bit 0 .... 4 level gray if set, otherwise 2 levels
#   bit 2,3 .. gray foreground
#   bit 4,5 .. gray background
#   bit 7 .... compressed
#   bit 8 .... 256 level color if set
#
# there are four types of icons since color icons are not compressed:
#   Gray 2-color, Gray 4-color (normal and compressed) and 256-Color
#
# Encodings
# ---------
# Gray 2-color takes it's foreground/background from the type1 attr.
# Each bit represents 0=background, 1=foreground. Lines are padded to
# the byte boundary.
#
# Gray 4-color uncompressed is like the 2-color icon except that it
# uses two bits for each pixel. Each bit pair corresponds to the color
# take at the beginning of this document.
#
# Gray 4-color compressed uses two encoding modes. Read a byte. If the
# high bit is set, it's a repeating color. The color comes from bits
# 0 and 1. Bits 2-6 represent the number of pixels - 4. Otherwise, use
# bits 5,4 3,2 and 1,0 as the next three pixel colors.
#
# 256-color uncompressed. Each byte is a pixel. See 256 color index.
# --------------------------------------------------------------------
#

[CCFIcon]

  N2  size
  N2  width
  N2  height
  N2  type
  B+  data                  ${size}-8


