Advertisement
SReject

fancyencode.mrc

Sep 16th, 2017
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
mIRC 26.52 KB | None | 0 0
  1. ;**********************************;
  2. ;    CHALLENGE-SPECIFIC ALAISES    ;
  3. ;**********************************;
  4. alias FancyEncodeExample {
  5.   FancyEncode Sed posuere condimentum turpis, vel cursus felis ultricies sit amet. Proin auctor massa nec neque hendrerit eleifend. Pellentesque ullamcorper tellus sit amet sagittis aliquet. Integer auctor egestas turpis, quis sollicitudin erat rutrum sit amet. Aliquam suscipit, dolor ac porttitor convallis, lorem turpis pulvinar massa, quis pharetra lorem lorem varius erat. Donec lacus mi, porttitor a tortor et, congue gravida purus. Duis sed sem lorem. Cras sollicitudin leo eu lectus commodo, aliquam accumsan libero mollis. Aliquam imperdiet vulputate eros tempus mollis. Cras vel tincidunt sapien. Aliquam sit amet dictum enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque et diam et magna fermentum suscipit. Vestibulum et dolor nec risus laoreet volutpat. Nulla vitae mauris non turpis aliquet lobortis. Sed efficitur euismod dolor, sed rhoncus sapien scelerisque ut. Proin posuere, metus et dignissim interdum, orci dui suscipit turpis, ve nullam.
  6. }
  7.  
  8. alias FancyEncode {
  9.   if ($0) {
  10.     bset -tc &FancyEncodeInput 1 $1-
  11.   }
  12.   FancyEncoder &FancyEncodeInput
  13. }
  14.  
  15. alias FancyDecode {
  16.   return $bvar($FancyDecoder, 1-).text
  17. }
  18.  
  19.  
  20.  
  21. ;***********************;
  22. ;    UTILITY ALIASES    ;
  23. ;***********************;
  24. ; Aliases used by this script that are not script-specific
  25.  
  26. ; /badd -tac &bvar values...
  27. ;   Appends the values to the bvar
  28. ;   Switches are the same as /bset
  29. alias -l badd {
  30.   if ($isid) {
  31.     return
  32.   }
  33.   elseif (-* iswm $1) {
  34.     bset $1-2 $calc($bvar($2,0) +1) $3-
  35.   }
  36.   else {
  37.     bset $1 $calc($bvar($1,0) +1) $2-
  38.   }
  39. }
  40.  
  41.  
  42. ; $ModifyColor(RGBValue, Modifier)[.add]
  43. ; $ModifyColor(RedValue, GreenValue, BlueValue, Modifier)[.add]
  44. ;
  45. ; Modifies the input color by multiplying the colors R,G,B values by the modifier
  46. ; If the .ad prop is specified, the modifier is added instead
  47. ;
  48. ; Returns the color as an integer
  49. alias -l ModifyColor {
  50.  
  51.   ; If there's only two inputs the first is an RGBValue the second is the modifider
  52.   ;   1. convert the color from $1 to R,G,B and store each value
  53.   ;   2. set the modifier to $2
  54.   ; Otherwise
  55.   ;   1. Store the R($1), G($2), B($3) values
  56.   ;   2. set the modifier to $4
  57.   if ($0 == 2) {
  58.     var %Color = $rgb($1), %Red = $gettok(%Color, 1, 44), %Green = $gettok(%Color, 2, 44), %Blue = $gettok(%Color, 3, 44), %Mod = $2
  59.   }
  60.   else {
  61.     var %Red = $1, %Green = $2, %Blue = $3, %Mod = $4
  62.   }
  63.  
  64.   ; If the prop is 'add' add the midifier to the R,G,B values and roudn to the closest whole number
  65.   if ($prop == add) {
  66.     var %Red = $round($calc(%Mod + %Red), 0), %Green = $round($calc(%Mod + %Green), 0), %Blue = $round($calc(%Mod + %Blue), 0)
  67.   }
  68.  
  69.   ; otherwise multuple the R, G, B values by the modifier, ane round to the closest whole number
  70.   else {
  71.     var %Red = $round($calc(%Mod * %Red), 0), %Green = $round($calc(%Mod * %Green), 0), %Blue = $round($calc(%Mod * %Blue), 0)
  72.   }
  73.  
  74.   ; Cap the R, G, B values at 255
  75.   if (%Red > 255) {
  76.     %Red = 255
  77.   }
  78.   if (%Green > 255) {
  79.     %Green = 255
  80.   }
  81.   if (%Blue > 255) {
  82.     %Blue = 255
  83.   }
  84.  
  85.   ;; Conver the R, G, B values to a color and return the result
  86.   return $rgb(%Red, %Green, %Blue)
  87. }
  88.  
  89.  
  90. ; $BlendColors(RGBValueA, RGBValueB, Percentage)[.rgb]
  91. ; $BlendColors(RedA, GreenA, BlueA, RedB, GreenB, BlueB, Percentage)[.rgb]
  92. ;
  93. ; Mixes the input colors where the specified percentage is the amount of the first color to use
  94. ;   Percentage = 1.0 = All of first color, none of the second
  95. ;   Percentage = 0.5 = Equal parts first and second color
  96. ;   Percentage = 0.0 = None of first color, All of second color
  97. ;
  98. ; If .rgb is specified the color is returned in R,G,B format
  99. ; Otherwise the color is returned as an integer
  100.  
  101. alias -l BlendColors {
  102.  
  103.   ; Default mixing percentage
  104.   var %Percentage = .5, %Red, %Green, %Blue
  105.  
  106.   ; If 2-3 inputs were given
  107.   ;   Assume the input colors are integer values
  108.   if ($0 isnum 2-3) {
  109.  
  110.     ; If the first input contains a comma(,):
  111.     ;   assume the input is formatted as <R,G,B>
  112.     ;
  113.     ; Otherwise
  114.     ;   Assume its an integer color value and convert to R,B,G format
  115.     if ($chr(44) isin $1) {
  116.       %ColorA = $1
  117.     }
  118.     else {
  119.       %ColorA = $rgb($1)
  120.     }
  121.  
  122.     ; If the second input contains a comma(,):
  123.     ;   assume the input is formatted as <R,G,B>
  124.     ;
  125.     ; Otherwise
  126.     ;   Assume its an integer color value and convert to R,B,G format
  127.     if ($chr(44) isin $2) {
  128.       %ColorB = $2
  129.     }
  130.     else {
  131.       %ColorB = $rgb($2)
  132.     }
  133.  
  134.     ; Extract the Red, Green and blue values from the two colors
  135.     var %RedA = $gettok(%ColorA, 1, 44), %GreenA = $gettok(%ColorA, 2, 44), %BlueA = $gettok(%ColorA, 3, 44)
  136.     var %RedB = $gettok(%ColorB, 1, 44), %GreenB = $gettok(%ColorB, 2, 44), %BlueB = $gettok(%ColorB, 3, 44)
  137.  
  138.     ; If a 3rd input is specified, use it for the percentage    
  139.     if ($0 == 3) {
  140.       %Percentage = $3
  141.     }
  142.   }
  143.  
  144.   ; Otherwise assume the RGB values are given for each color
  145.   else {
  146.     var %RedA = $1, %GreenA = $2, %BlueA = $3
  147.     var %RedB = $4, %GreenB = $5, %BlueB = $6
  148.  
  149.     ; if a 7th input is given, assume its the mix percentage
  150.     if ($0 == 7) {
  151.       %Percentage = $7
  152.     }
  153.   }
  154.  
  155.   ; Mix colors
  156.   var %Red   = $round($calc((%RedA   * %Percentage) + (%RedB   * (1 - %Percentage))), 0)
  157.   var %Green = $round($calc((%GreenA * %Percentage) + (%GreenB * (1 - %Percentage))), 0)
  158.   var %Blue  = $round($calc((%BlueA  * %Percentage) + (%BlueB  * (1 - %Percentage))), 0)
  159.  
  160.   ; Cap each color value at 255
  161.   if (%Red > 255) {
  162.     %Red = 255
  163.   }
  164.   if (%Green > 255) {
  165.     %Green = 255
  166.   }
  167.   if (%Blue > 255) {
  168.     %Blue = 255
  169.   }
  170.  
  171.   ; Return as R,G,B format
  172.   if ($prop == rgb) {
  173.     return $+(%Red, $chr(44), %Green, $chr(44), %Blue)
  174.   }
  175.  
  176.   ; Return as integer
  177.   return $rgb(%Red, %Green, %Blue)
  178. }
  179.  
  180.  
  181.  
  182. ;**********************;
  183. ;    EVENT HANDLING    ;
  184. ;**********************;
  185.  
  186. ; When text is entered into the Main window's editbox
  187. ;     if ctrlenter was pressed or the lead character is not the command character
  188. ;     encode the input text
  189. on *:INPUT:@FancyEncode:{
  190.   if ($ctrlenter) || ($left($1,1) !==  / && $left($1,1) !== $comchar) {
  191.     FancyEncode $1-
  192.     halt
  193.   }
  194. }
  195.  
  196. ; Cleanup on load, start, when either window closes, mirc exits or the script is unloaded
  197. on *:LOAD:{
  198.   cleanup
  199.  
  200.   echo -s * Optimal Input
  201.   echo -s *   50 to 1000 input characters, the more the merrier
  202.   echo -s *   More diverse inputs are recommended
  203.   echo -s *
  204.   echo -s * If you have a MIDI-capable device you can play the sound
  205.   echo -s *   file of the encode via right clicking the @FancyEncode
  206.   echo -s *   window
  207. }
  208. on *:START:cleanup
  209. on *:CLOSE:@FancyEncode:cleanup
  210. on *:CLOSE:@FancyEncodeBuffer:cleanup
  211. on *:EXIT:cleanup
  212. on *:UNLOAD:cleanup
  213.  
  214. alias -l cleanup {
  215.   if ($timer(FancyEncodeEBSelect)) {
  216.     .timerFancyEncodeEBSelect off
  217.   }
  218.   if ($window(@FancyEncodeBuffer)) {
  219.     close -@ @FancyEncodeBuffer
  220.   }
  221.   if ($window(@FancyEncode)) {
  222.     close -@ @FancyEncode
  223.   }
  224.   if ($inmidi.fname === $scriptdirFancyEncode.mid) {
  225.     splay stop
  226.   }
  227.   if ($isfile($scriptdirFancyEncode.mid)) {
  228.     .remove $qt($scriptdirFancyEncode.mid)
  229.   }
  230. }
  231.  
  232.  
  233.  
  234. ;************************;
  235. ;    MAIN WINDOW MENU    ;
  236. ;************************;
  237. menu @FancyEncode {
  238.   $submenu($FancyEncodeMenu($1))
  239. }
  240.  
  241. ; Generates the Main window menu based on current state
  242. alias -l FancyEncodeMenu {
  243.  
  244.   ; First menu item
  245.   ;   If
  246.   ;     There's no data encoded(determined by checking if the first pixel of the center line)
  247.   ;     OR a sound being played that isn't a MIDI
  248.   ;     OR a MIDI is being played that isn't FancyEncode.mid
  249.   ;     OR the FancyEncode.mid file doesn't exist
  250.   ;       return a disabled 'Play' menu item
  251.   ;
  252.   ;   elseif
  253.   ;     the MIDI being played is the FancyEncode.mid
  254.   ;       return a 'Stop' menu item
  255.   ;
  256.   ;   else
  257.   ;     return a 'Play' menu item
  258.   if ($1 == 1) {
  259.     if ($getdot(@FancyEncode, 10, 264) == 0) {
  260.       return $style(2) Play:FancyEncodeToggleSound
  261.     }
  262.     elseif ($insong || $inwave) {
  263.       return $style(2) Play:FancyEncodeToggleSound
  264.     }
  265.     elseif ($inmidi && $inmidi.fname !== $scriptdirFancyEncode.mid) {
  266.       return $style(2) Play:FancyEncodeToggleSound
  267.     }
  268.     elseif (!$isfile($scriptdirFancyEncode.mid)) {
  269.       return $style(2) Play:FancyEncodeToggleSound
  270.     }
  271.     elseif ($inmidi) {
  272.       return Stop: FancyEncodeToggleSound
  273.     }
  274.     return Play: FancyEncodeToggleSound
  275.   }
  276.  
  277.   ; Second Menu Item - Menu Item Seperator
  278.   elseif ($1 == 2) {
  279.     return -
  280.   }
  281.  
  282.   ; Third Menu Item
  283.   ;    if
  284.   ;      There's no data encoded(determined by checking if the first pixel of the center line)
  285.   ;        return a disabled 'Save' menu item
  286.   ;    else
  287.   ;      return a 'Save' menu item
  288.   elseif ($1 == 3) {
  289.     if (!$getdot(@FancyEncode, 10, 264)) {
  290.       return Style(2) $+ Save MIDI: FancyEncodeSaveMidi
  291.     }
  292.     return Save MIDI: FancyEncodeSaveMidi
  293.   }
  294. }
  295.  
  296. ; Toggles the playing sound when called
  297. ;   If the currently playing sound is the FancyEncode.mid file, stop the playing
  298. ;   elseif there's a sound being played that isn't FancyEncode.mid do nothing
  299. ;   elseif the FancyEncode.mid file exists, play it
  300. alias -l FancyEncodeToggleSound {
  301.   if ($inmidi.fname == $scriptdirFancyEncode.mid) {
  302.     splay stop
  303.   }
  304.   elseif ($insong || $inwave || $inmidi) {
  305.     return
  306.   }
  307.   elseif ($isfile($scriptdirFancyEncode.mid)) {
  308.     var %Start = 10
  309.     var %Max = $calc($window(@FancyEncodeBuffer).bw - 10)
  310.     var %Next
  311.     var %Cur = %Start
  312.     var %Block = $calc(%Max - 10)
  313.     while (%Block > 0) {
  314.       %Next = $calc(%Cur + %Block)
  315.       if (%Next > %Max) {
  316.         %Cur = %Max
  317.         break
  318.       }
  319.       elseif ($getdot(@FancyEncodeBuffer, %Next, 264)) {
  320.         %Cur = %Next
  321.       }
  322.       else {
  323.         %Block = $int($calc(%Block / 2))
  324.       }
  325.     }
  326.  
  327.     .timerFancyEncodePlayPosition -m 1 100 FancyEncodePlayPosition %Cur
  328.     splay -m $qt($scriptdirFancyEncode.mid)
  329.   }
  330. }
  331.  
  332. ; Saves the temporily generated midi
  333. ;   If data was encoded and the FancyEncode.mid file exists
  334. ;     copy the temporary MIDI to a user-specified directory
  335. alias -l FancyEncodeSaveMidi {
  336.   if ($getdot(@FancyEncode, 10, 264) && $isfile($scriptdirFancyEncode.mid)) {
  337.     copy $qt($scriptdirFancyEncode.mid) $qt($$sfile($envvar(userprofile) $+ FancyEncode $asctime(yyyy-mm-dd HH.nn.ss) $+ .mid, Save Midi, Save))
  338.   }
  339. }
  340.  
  341.  
  342.  
  343. ;***************;
  344. ;    ENCODER    ;
  345. ;***************;
  346.  
  347. ; /FancyEncoder &InputBvar
  348. ;     Encodes the bytes contained in &InputBvar
  349. alias FancyEncoder {
  350.  
  351.   if ($inmidi.fname == $scriptdirFancyEncode.mid) {
  352.     splay stop
  353.   }
  354.  
  355.   ; Variable setup
  356.   var %WinW 1164
  357.   var %WinH 557
  358.   var %EBText Input text here and press enter to encode
  359.   var %OptionsText Right-Click for Options
  360.   var %ColorsList 255,0,0 255,127,0 255,255,0 0,255,0 0,0,255 75,0,130 139,0,255
  361.   var %NoteList 48 50 52 53 55 57 59 60 62 64 65 67 69 71 72 74 76 77 79 81 83
  362.   var %StartTime $ticks,%7BitLength,%InputLength,%ColorBlock,%ColorsCount $numtok(%ColorsList, 32),%InputIndex 0,%BitBuffer,%7BitIndex 0,%7BitValue,%NoteCount $numtok(%NoteList, 32),%NoteChordAdds 84 86 88 89 91 93 95,%NoteDurationBlock 21,%NoteDuration,%NoteA,%NoteB,%NoteC,%ColorIndex,%ColorEnd,%ColorPercent,%ColorRed,%ColorGreen,%ColorBlue,%XCoord,%LineLength,%YCoord,%Color
  363.  
  364.  
  365.  
  366.   ;***************************;
  367.   ;    BUFFER WINDOW SETUP    ;
  368.   ;***************************;
  369.  
  370.   ; Setup buffer window
  371.   if (!$window(@FancyEncodeBuffer)) {
  372.     window -nBCdfhpz @FancyEncodeBuffer -1 -1 %WinW %WinH
  373.   }
  374.  
  375.   ; fill with black background
  376.   drawrect -fr @FancyEncodeBuffer 0 1 0 0 %WinW %WinH
  377.  
  378.   ; draw "Right-Click for Options" text to the Buffer window
  379.   drawtext -r @FancyEncodeBuffer $rgb(0,128,255) Courier 15 $calc(%WinW - 5 - $width(%OptionsText, Courier, 15)) 537 %OptionsText
  380.  
  381.  
  382.  
  383.   ;*************************;
  384.   ;    MAIN WINDOW SETUP    ;
  385.   ;*************************;
  386.  
  387.   ; If the main window doesn't exist
  388.   ;     1. Create the window
  389.   ;     2. Start a timer to fill the editbox with default text
  390.   ;
  391.   ; Otherwise activate the window
  392.   if (!$window(@FancyEncode)) {
  393.     window -BCdefk0pz +bt @FancyEncode -1 -1 %WinW %WinH
  394.     .timerFancyEncodeEBSelect 1 0 if ($window(@FancyEncode) && $!editbox(@FancyEncode) == $!null) $({) editbox -b1e $+ $calc(1+ $len(%EBText)) @FancyEncode %EBText $(})
  395.   }
  396.   else {
  397.     window -a @FancyEncode
  398.   }
  399.  
  400.   ;; Fill main window with black background
  401.   drawrect -fr @FancyEncode 0 1 0 0 %WinW %WinH
  402.  
  403.   ;; Nothing to encode  
  404.   ;;     Draw "Nothing to Encode" mess to main window and exit processing
  405.   if ($0 !== 1 || $left($1,1) !== & || !$bvar($1,0)) {
  406.     drawtext -r @FancyEncode $rgb(0,128,255) Arial 20 10 10 Nothing to Encode
  407.     return
  408.   }
  409.  
  410.   ;; Otherwise, draw "Encoding..." to main window
  411.   drawtext -r @FancyEncode $rgb(0,128,255) Arial 20 10 10 Encoding...
  412.  
  413.  
  414.  
  415.   ;**********************;
  416.   ;    ENCODING SETUP    ;
  417.   ;**********************;
  418.  
  419.   ; Number of bytes to be encoded
  420.   %InputLength = $bvar($1, 0)
  421.  
  422.   ; Setup the MIDI:
  423.   ;     LeftByte[1-4]   = "MThd"        (File-Header)
  424.   ;     LeftByte[5-8]   =   6 as uint32 (File-Header's Data Length; always 6)
  425.   ;     LeftByte[9-10]  =   0 as uint16 (Format; 0 for single track)
  426.   ;     LeftByte[11-12] =   1 as uint16 (Number of Tracks)
  427.   ;     LeftByte[13-14] = 128 as uint16 (MIDI ticks per quarter note)
  428.   ;
  429.   ;     LeftByte(15-18] = "MTrk"        (Track-Header)
  430.   ;     LeftByte[19-22] = 0 as uint32   (Track-Length; filled in after encoding)
  431.   ;
  432.   ; All bytes beyond LeftByte[22] are event-related and formated as: <delay_after_last_event><event>[<params...>]
  433.   ;
  434.   ;     LeftByte[23-25] = <delay:0><SET_INSTRUMENT(192) + Channel(0))><Instrument:1 (piano)>
  435.   bset -c &FancyEncodeMidi 1 77 84 104 100 0 0 0 6 0 0 0 1 0 128 77 84 114 107 0 0 0 0 0 192 1
  436.  
  437.   ; Number of 7bit values that will be created from the 8bit input values; more info under "ENCODING: Byte conversion"
  438.   %7BitLength  = $ceil($calc(%InputLength * 8 / 7))
  439.  
  440.   ; Color Block size
  441.   %ColorBlock = %7BitLength / %ColorsCount
  442.  
  443.  
  444.  
  445.   ;**********************;
  446.   ;    ENCODING START    ;
  447.   ;**********************;
  448.   ; The encoder processes the input into 7bit values as needed. This is done to:
  449.   ; ...add variance between the input and what is displayed
  450.   ; ...add variance between similar but not exact inputs
  451.   ; ...make the resulting MIDI less chaotic
  452.  
  453.   ; Loop while their are bytes from the input, or bits in the bit buffer to be consumed
  454.   while (%InputIndex < %InputLength || %BitBuffer !== $null) {
  455.  
  456.  
  457.  
  458.     ;*********************************;
  459.     ;    ENCODING: Byte conversion    ;
  460.     ;*********************************;
  461.     ; The 8bit input values are converted to 7bit equivulants as such
  462.     ; 1. When the bit buffer variable has less than 7 bits (characters):
  463.     ;     1. The next 8bit byte from the input is read
  464.     ;     2. The byte is converted to binary represented as text
  465.     ;     3. The binary text is appended to bit buffer
  466.     ;     4. If, after appending the binary text, the bit buffer has less than 7 bits:
  467.     ;          The end of the input has been reached so the bit buffer is right-padded with 0s
  468.     ;          to make it 7 characters long
  469.     ;    
  470.     ; 2. The first 7 bits (characters) of the bit buffer are converted to an integer and stored
  471.     ; 3. The first 7 bits (characters) of the bit buffer are removed
  472.  
  473.     ; if the bit buffer has less than 7 'bits'
  474.     ; 1. Read the next byte from the input and convert it to binary represented as text
  475.     ; 2. If the bit buffer still doesn't have 7 bytes:
  476.     ;        The end of the input has been reached so right-pad the bit buffer with 0s
  477.     if ($len(%BitBuffer) < 7) {
  478.       inc %InputIndex
  479.       %BitBuffer = %BitBuffer $+ $base($bvar($1, %InputIndex, 1), 10, 2, 8)
  480.       if ($len(%BitBuffer) < 7) {
  481.         %BitBuffer = %BitBuffer $+ $str(0, $calc(7 - $v1))
  482.       }
  483.     }
  484.  
  485.     ; Increase the current-value-index
  486.     inc %7BitIndex
  487.  
  488.     ; Convert the first 7 'bits' in the bit buffer to an integer
  489.     ; then remove them from the bit buffer
  490.     %7bitValue  = $base($left(%BitBuffer, 7), 2, 10)
  491.     %BitBuffer  = $mid(%BitBuffer, 8-)
  492.  
  493.  
  494.  
  495.     ;*************************************;
  496.     ;    ENCODING: MIDI Note Additions    ;
  497.     ;*************************************;
  498.  
  499.     ; Calculate the chord duration
  500.     ; 1. Divide the value by the number of notes
  501.     ; 2. Floor the value
  502.     ; 3. Add 1 to the value
  503.     ; 4. Multiple by the Note duration block size
  504.     ; 5. If the duration ended up being larger than 127 ticks, cap it to 127
  505.     ;        This limits the resulting MIDI to 1/4 notes or shorter. Any duration larger than this causes the MIDI
  506.     ;        to be unplayable. If anyone has information on how to fix this, let me know
  507.     %NoteDuration = $calc(($floor($calc(%7BitValue / %NoteCount)) +1) * %NoteDurationBlock)
  508.     if (%NoteDur > 127) {
  509.       %NoteDur = 127
  510.     }
  511.  
  512.     ; Retrieve each note for the chord
  513.     ; 1. Get the note index by: retrieving the remainder of value / number of quotes and then adding one
  514.     ; 2. Use that index to get the note from the lists of applicable notes and store the result
  515.     ; 3. repeat steps 1&2 for the 2nd and 3rd chord note but add 2 and 4, respectively to the 7bit value prior to division
  516.     %NoteA = $gettok(%NoteList %NoteChordAdds, $calc(%7BitValue % %NoteCount +1), 32)    
  517.     %NoteB = $gettok(%NoteList %NoteChordAdds, $calc((%7BitValue + 2) % %NoteCount +1), 32)    
  518.     %NoteC = $gettok(%NoteList %NoteChordAdds, $calc((%7BitValue + 4) % %NoteCount +1), 32)
  519.  
  520.     ; Add the note_on event for the chord to the MIDI bvar:
  521.     ;     <delay> <NOTE_ON(144) + Channel(0)> <note> <volume>
  522.     badd &FancyEncodeMidi 0 144 %NoteA 90
  523.     badd &FancyEncodeMidi 0 144 %NoteB 90
  524.     badd &FancyEncodeMidi 0 144 %NoteC 90
  525.  
  526.     ; Add the notes_off event for the chord to the MIDI bvar:
  527.     ;    <delay> <NOTE_OFF(128) + Channel(0)> <note> <volume>
  528.     badd &FancyEncodeMidi %NoteDuration 128 %NoteA 90
  529.     badd &FancyEncodeMidi 0 128 %NoteB 90
  530.     badd &FancyEncodeMidi 0 128 %NoteC 90
  531.  
  532.  
  533.  
  534.     ;************************************;
  535.     ;    INTERMISSION: Get Color Base    ;
  536.     ;************************************;
  537.  
  538.     ; Get the start-color percentage(as a decimal):
  539.     ;     1. Divide the value by the color block size and get the remainder
  540.     ;     2. Divide the remainder by the color block size
  541.     ;     3. subtract from 1
  542.     ;
  543.     ; 1.0 = All of start color, None of end color
  544.     ; 0.0 = None of start color, all of end color
  545.     %ColorPercent = $calc(1 - ( %7BitIndex % %ColorBlock )/ %ColorBlock )
  546.  
  547.     ; If this is the last value to be processed
  548.     ; Use the first color
  549.     if (%7BitIndex == %7BitLength) {
  550.       %ColorPercent = 0
  551.     }
  552.  
  553.     ; Otherwise calculate the color index by dividing the bit index by the color block size, the rounding up
  554.     %ColorIndex = $ceil($calc(%7BitIndex / %ColorBlock))
  555.  
  556.     ; If the color index is at the end of the list use the first color in the list as the end color
  557.     ; otherwise use the next color in the list
  558.     if (%ColorIndex == %ColorsCount) {
  559.       %ColorEnd = $gettok(%ColorsList, 1, 32)
  560.     }
  561.     else {
  562.       %ColorEnd = $gettok(%ColorsList, $calc(%ColorIndex + 1), 32)
  563.     }
  564.  
  565.     ; Blend the two colors then extract the R,G,B values
  566.     %Color      = $BlendColors($gettok(%ColorsList, %ColorIndex, 32), %ColorEnd, %ColorPercent).rgb
  567.     %ColorRed   = $gettok(%Color, 1, 44)
  568.     %ColorGreen = $gettok(%Color, 2, 44)
  569.     %ColorBlue  = $gettok(%Color, 3, 44)
  570.  
  571.  
  572.  
  573.     ;****************************;
  574.     ;    ENCODING: Draw Lines    ;
  575.     ;****************************;
  576.  
  577.     ; Calculate the x coord
  578.     ;   1. subtrack 1 from bit index: this is an offset to insure the bottom lines align with those on top
  579.     ;   2. divide by 2 and round down: done to account for alternating between top and bottom
  580.     ;   3. multiple by 2; done because the line for each value is 2px wide
  581.     ;   4. add 10; left-side offset so there's space between the left-side and the start of lines
  582.     %XCoord = $calc($floor($calc((%7BitIndex - 1) /2)) *2 + 10)
  583.  
  584.     ; Draw the center-line
  585.     ;   The color is modified to brighten it compared to the top & bottom half colors
  586.     ;   The line's 2nd x-coord is 1 pixel longer than expected due to drawline drawing TO the coordinate but not including it  
  587.     drawline -fnr @FancyEncodeBuffer $ModifyColor(%ColorRed, %ColorGreen, %ColorBlue, 92).add 1 %XCoord 264 $calc(%XCoord +2) 264
  588.  
  589.     ; if the 7bit value is not zero or null
  590.     if (%7BitValue) {
  591.  
  592.       ; calculate the line length by multiplying the 7bit value by 2
  593.       %LineLength = $calc(%7BitValue * 2)
  594.  
  595.       ; if the index is a multiple of two
  596.       ;     1. The line is a bottom line so it should start just below center-line
  597.       ;     2. Modify the base color to be darker
  598.       if (2 // %7BitIndex) {
  599.         %YCoord   = 265
  600.         %Color    = $ModifyColor(%ColorRed, %ColorGreen, %ColorBlue, .5)
  601.       }
  602.  
  603.       ; If the index is not a multiple of two    
  604.       ;     1. The line is a top-line, so subtrack the length from where it should stop at
  605.       ;     2. Convert the RGB directly to a color
  606.       else {
  607.         %YCoord = $calc(264 - %LineLength)
  608.         %Color  = $rgb(%ColorRed, %ColorGreen, %ColorBlue)
  609.       }
  610.  
  611.       ; Draw the first line as %Color indicates to the buffer window
  612.       ; Then draw the second line after modifying the color to be slightly darker
  613.       drawrect -nr @FancyEncodeBuffer %Color 1 %XCoord %YCoord 2 %LineLength
  614.       drawrect -nr @FancyEncodeBuffer $ModifyColor(%Color, .7).multiply 1 $calc(%XCoord +1) %YCoord 1 %LineLength
  615.     }
  616.   }
  617.  
  618.  
  619.  
  620.   ;******************************;
  621.   ;    ENCODING: MIDI Wrap up    ;
  622.   ;******************************;
  623.  
  624.   ; Add the "track finished" event to the MIDI
  625.   badd &FancyEncodeMidi 1 255 47 0
  626.  
  627.   ; Fill in the track length by:
  628.   ;    1. Subtracting 22 from the MIDI bvar length
  629.   ;    2. Using longip to get a 32bit uint formatted as x.x.x.x
  630.   ;    3. Replace the .'s in the longip result with space
  631.   ;    4. Insert the bytes into the bvar
  632.   bset &FancyEncodeMidi 19 $replace($longip($calc($bvar(&FancyEncodeMidi, 0) - 22)), ., $chr(32))
  633.  
  634.   ; If a FancyEncode.mid exists, remove it
  635.   if ($isfile($scriptdirFancyEncode.mid)) {
  636.     .remove $qt($scriptdirFancyEncode.mid)
  637.   }
  638.  
  639.   ; Write the midi to file
  640.   bwrite $qt($scriptdirFancyEncode.mid) -1 &FancyEncodeMidi 1 -1
  641.  
  642.  
  643.  
  644.   ;******************************;
  645.   ;    ENCODING: Draw Wrap up    ;
  646.   ;******************************;
  647.  
  648.   ; Copy the buffer window's contents to the main window
  649.   drawcopy @FancyEncodeBuffer 0 0 %WinW %WinH @FancyEncode 0 0
  650.  
  651.   ; Generate the info text
  652.   %StartTime = $ticks - %StartTime
  653.   var %InfoText = Time: $bytes(%StartTime,b) $+ ms - Bytes In: $bvar(&FancyEncodeInput, 0) - Bytes Out: %7BitIndex
  654.  
  655.   ; Draw the info text to the main window
  656.   drawtext -r @FancyEncode $rgb(0,128,255) Courier 15 5 537 %InfoText
  657. }
  658.  
  659.  
  660.  
  661. ;***************;
  662. ;    DECODER    ;
  663. ;***************;
  664.  
  665. ; $FancyDecoder
  666. ;   Returns a bvar containing the decoded text
  667.  
  668. alias FancyDecoder {
  669.   ;; cleanup any existing bvars
  670.   bunset &FancyDecodeOutput
  671.  
  672.   ; variable setup
  673.   var %buffer, %x = 10
  674.  
  675.   ; Loop while the center dot of the Buffer window is NOT black
  676.   while ($getdot(@FancyEncodeBuffer, %x, 264)) {
  677.  
  678.     ; Get the line values for the top and bottom line
  679.     ;   Convert to a binary value represented as a string of 0's and 1's
  680.     ;   Append the strings to the buffer
  681.     %Buffer = %Buffer $+ $base($LineValue(%x, -1),10, 2, 7) $+ $base($LineValue(%x, 1), 10, 2, 7)
  682.  
  683.     ; Loop over the bit buffer while there's atleast 7 'bits'
  684.     ;   Grab the first 7 bits, convert to an integer and append the value to the output bvar
  685.     ;   Remove the 7bits from the buffer
  686.     while ($len(%Buffer) > 7) {
  687.       badd &FancyDecodeOutput $base($left(%Buffer, 8), 2, 10)
  688.       %Buffer = $mid(%Buffer, 9-)
  689.     }
  690.  
  691.     ; Move to the next set of lines
  692.     inc %x 2
  693.   }
  694.  
  695.   ; return the output bvar
  696.   return &FancyDecodeOutput
  697. }
  698.  
  699. ; $LineValue(@xcoord, @modifier)
  700. ;   Returns the value the line represents
  701. ;
  702. ;   @XCoord : The Xcoord of @FancyEncode of the line to get
  703. ;
  704. ;   @Modifier
  705. ;     -1: top line
  706. ;      1: Bottom line
  707. alias -l LineValue {
  708.  
  709.   ; Calculate the current y position and block size and store the start and max positions
  710.   var %Cur   = 264
  711.   var %Block = 254 * $2
  712.   var %Next
  713.   var %Start = %Cur + $2
  714.   var %Max   = 264 + %Block
  715.  
  716.   ; If start y position is black there's nothing to decode so return 0
  717.   if (!$getdot(@FancyEncodeBuffer, $1, $calc(%Cur + $2))) {
  718.     return 0
  719.   }
  720.  
  721.   ; loop while the block size is NOT 0
  722.   while (%Block !== 0) {
  723.  
  724.     ; Calculate the next y position to validate
  725.     %Next = %Cur + %Block
  726.  
  727.     ; If the next y-position is out of the max bounds, return the max-bound as the result
  728.     if (%Start < %Max && %next > %Max) || (%Start > %Max && %Next < %Max) {
  729.       %Cur = %Max
  730.       break
  731.     }
  732.  
  733.     ; If the next y-position is not black set the current position to it
  734.     elseif ($getdot(@FancyEncodeBuffer, $1, %Next)) {
  735.       %Cur = %Next
  736.     }
  737.  
  738.     ; Otherwise divide the block in half and try again
  739.     else {
  740.       %Block = $int($calc(%Block / 2))
  741.     }
  742.   }
  743.  
  744.   ; Return the line-length divided by 2
  745.   return $abs($calc((264 - %Cur )/2))
  746. }
  747.  
  748.  
  749. ;********************;
  750. ;    MIDI PLAYING    ;
  751. ;********************;
  752. alias -l FancyEncodePlayPosition {
  753.   if (!$window(@FancyEncode) || !$window(@FancyEncodeBuffer)) {
  754.     cleanup
  755.   }
  756.  
  757.   if ($inmidi.fname !== $scriptdirFancyEncode.mid) {
  758.     drawcopy @FancyEncodeBuffer 0 0 $window(@FancyEncodeBuffer).bw $calc($window(@FancyEncodeBuffer).bh - 25) @FancyEncode 0 0
  759.   }
  760.   else {
  761.     var %Percent, %XCoord, %NextXCoord
  762.  
  763.     %Percent = $calc($inmidi.pos / $inmidi.length)
  764.     if (!%Percent) {
  765.       %Percent = 0
  766.     }
  767.     elseif (%Percent > 1) {
  768.       %Percent = 1
  769.     }
  770.  
  771.     %XCoord = 9
  772.     if ($0 > 1) {
  773.       %XCoord = $2
  774.     }
  775.  
  776.     %NextXCoord = $round($calc( ($1 -10) * %Percent + 10), 0)
  777.     if (%NextXCoord > $1) {
  778.       %NextXCoord = $v2
  779.     }
  780.     while (%XCoord < %NextXCoord) {
  781.       inc %XCoord
  782.       drawline -rn @FancyEncode $rgb(8,16,16) 1 %XCoord $calc(263 - $LineValue(%XCoord, -1) * 2) %XCoord 264
  783.       drawline -rn @FancyEncode $rgb(8,8,8) 1 %XCoord 265 %XCoord $calc(265 + $LineValue(%XCoord, 1) * 2)
  784.       drawdot -rn @FancyEncode $rgb(32,32,32) 1 %XCoord 264
  785.     }
  786.     drawdot @FancyEncode
  787.     .timerFancyEncodePlayPosition -m 1 100 FancyEncodePlayPosition $1 %NextXCoord
  788.   }
  789. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement