diff --git a/.gitignore b/.gitignore index 243eb9ab..71239be2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ Gemfile.lock .bundle/ -vendor/ benchmark/ lib/linguist/samples.json diff --git a/.travis.yml b/.travis.yml index a964fa81..ac6800a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ before_install: rvm: - 1.9.3 - 2.0.0 - - 2.1.1 + - 2.1 + - 2.2 notifications: disabled: true diff --git a/Gemfile b/Gemfile index 851fabc2..b92cab78 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,3 @@ source 'https://rubygems.org' gemspec +gem 'test-unit', require: false if RUBY_VERSION >= '2.2' diff --git a/README.md b/README.md index 2950f269..94430f4d 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,8 @@ See [Linguist::Generated#generated?](https://github.com/github/linguist/blob/mas Linguist supports custom overrides for language definitions and vendored paths. Add a `.gitattributes` file to your project using the keys `linguist-language` and `linguist-vendored` with the standard git-style path matchers for the files you want to override. +Please note that the overrides currently only affect the language statistics for a repository and not the syntax-highlighting of files. + ``` $ cat .gitattributes *.rb linguist-language=Java diff --git a/Rakefile b/Rakefile index 8a044135..09fa0d8a 100644 --- a/Rakefile +++ b/Rakefile @@ -1,8 +1,8 @@ require 'bundler/setup' -require 'json' require 'rake/clean' require 'rake/testtask' require 'yaml' +require 'yajl' task :default => :test @@ -20,15 +20,13 @@ end task :samples do require 'linguist/samples' - require 'yajl' - data = Linguist::Samples.data - json = Yajl::Encoder.encode(data, :pretty => true) - File.open('lib/linguist/samples.json', 'w') { |io| io.write json } + json = Yajl.dump(Linguist::Samples.data, :pretty => true) + File.write 'lib/linguist/samples.json', json end task :build_gem => :samples do languages = YAML.load_file("lib/linguist/languages.yml") - File.write("lib/linguist/languages.json", JSON.dump(languages)) + File.write("lib/linguist/languages.json", Yajl.dump(languages)) `gem build github-linguist.gemspec` File.delete("lib/linguist/languages.json") end @@ -72,11 +70,11 @@ namespace :benchmark do reference_file = ENV["REFERENCE"] candidate_file = ENV["CANDIDATE"] - reference = JSON.parse(File.read(reference_file)) + reference = Yajl.load(File.read(reference_file)) reference_counts = Hash.new(0) reference.each { |filename, language| reference_counts[language] += 1 } - candidate = JSON.parse(File.read(candidate_file)) + candidate = Yajl.load(File.read(candidate_file)) candidate_counts = Hash.new(0) candidate.each { |filename, language| candidate_counts[language] += 1 } @@ -126,14 +124,12 @@ namespace :classifier do def each_public_gist require 'open-uri' - require 'json' - url = "https://api.github.com/gists/public" loop do resp = open(url) url = resp.meta['link'][/<([^>]+)>; rel="next"/, 1] - gists = JSON.parse(resp.read) + gists = Yajl.load(resp.read) for gist in gists for filename, attrs in gist['files'] diff --git a/github-linguist.gemspec b/github-linguist.gemspec index 6a06a6f2..4e918f30 100644 --- a/github-linguist.gemspec +++ b/github-linguist.gemspec @@ -19,7 +19,6 @@ Gem::Specification.new do |s| s.add_dependency 'pygments.rb', '~> 0.6.0' s.add_dependency 'rugged', '~> 0.21.1b2' - s.add_development_dependency 'json' s.add_development_dependency 'mocha' s.add_development_dependency 'pry' s.add_development_dependency 'rake' diff --git a/lib/linguist/heuristics.rb b/lib/linguist/heuristics.rb index e1b520b4..c7519881 100644 --- a/lib/linguist/heuristics.rb +++ b/lib/linguist/heuristics.rb @@ -28,6 +28,12 @@ module Linguist if languages.all? { |l| ["Hack", "PHP"].include?(l) } result = disambiguate_hack(data, languages) end + if languages.all? { |l| ["Scala", "SuperCollider"].include?(l) } + result = disambiguate_sc(data, languages) + end + if languages.all? { |l| ["AsciiDoc", "AGS Script"].include?(l) } + result = disambiguate_asc(data, languages) + end return result end end @@ -93,8 +99,28 @@ module Linguist def self.disambiguate_hack(data, languages) matches = [] - matches << Language["Hack"] if data.include?("' + Page,←⊂⍬,'' + Page,←⊂⍬,'' + Page,←⊂⍬,CoverageText + Page,←⊂⍬,'
'
+      Page,←ColorizedCode
+      Page,←⊂⍬,'
' + Page,←Timestamp + Page,←⊂⍬,'' + Z←Page + ∇ + + ∇ Z←colorize_code_by_coverage CoverResult;Colors;Ends;Code + :If 3.1=⊃CoverResult + Colors←(2+3⊃CoverResult)⍴⊂'' + Colors[1]←⊂'' + Colors[⍴Colors]←⊂'' + Ends←(2+3⊃CoverResult)⍴⊂'' + Ends[1]←⊂'' + Ends[⍴Ends]←⊂'' + :Else + Colors←(3⊃CoverResult)⍴⊂'' + Ends←(3⊃CoverResult)⍴⊂'' + :EndIf + Colors[1+4⊃CoverResult]←⊂'' + Ends[1+4⊃CoverResult]←⊂'' + Code←↓5⊃CoverResult + Z←Colors,[1.5]Code + Z←{⍺,(⎕UCS 13),⍵}/Z,Ends + ∇ + + ∇ Z←generate_timestamp_text;TS;YYMMDD;HHMMSS + TS←⎕TS + YYMMDD←⊃{⍺,'-',⍵}/3↑TS + HHMMSS←⊃{⍺,':',⍵}/3↑3↓TS + Z←'Page generated: ',YYMMDD,'|',HHMMSS + ∇ + + ∇ Conf write_html_to_page Page;tie;filename + filename←(⊃'cover_out'in Conf),(⊃'cover_file'in Conf) + :Trap 22 + tie←filename ⎕NTIE 0 + filename ⎕NERASE tie + filename ⎕NCREATE tie + :Else + tie←filename ⎕NCREATE 0 + :EndTrap + Simple_array←⍕⊃,/Page + (⎕UCS'UTF-8'⎕UCS Simple_array)⎕NAPPEND tie + ∇ + + ∇ Z←is_function Argument + Z←'_TEST'≡¯5↑Argument + ∇ + + ∇ Z←is_list_of_functions Argument + Z←2=≡Argument + ∇ + + ∇ Z←is_file Argument + Z←'.dyalog'≡¯7↑Argument + ∇ + + ∇ Z←is_dir Argument;attr + :If 'Linux'≡5↑⊃'.'⎕WG'APLVersion' + Z←'yes'≡⊃⎕CMD'test -d ',Argument,' && echo yes || echo no' + :Else + 'gfa'⎕NA'I kernel32|GetFileAttributes* <0t' + :If Z←¯1≠attr←gfa⊂Argument ⍝ If file exists + Z←⊃2 16⊤attr ⍝ Return bit 4 + :EndIf + :EndIf + ∇ + + + ∇ Z←test_files_in_dir Argument + :If 'Linux'≡5↑⊃'.'⎕WG'APLVersion' + Z←⎕SH'find ',Argument,' -name \*_tests.dyalog' + :Else + #.⎕CY'files' + Z←#.Files.Dir Argument,'\*_tests.dyalog' + Z←(Argument,'\')∘,¨Z + :EndIf + ∇ + + ∇ Z←run_ut ut_data;returned;crashed;pass;crash;fail;message + (returned crashed time)←execute_function ut_data + (pass crash fail)←determine_pass_crash_or_fail returned crashed + message←determine_message pass fail crashed(2⊃ut_data)returned time + print_message_to_screen message + Z←(pass crash fail) + ∇ + + ∇ Z←execute_function ut_data;function;t + reset_UT_globals + function←(⍕(⊃ut_data[1])),'.',⊃ut_data[2] + :Trap sac + :If 3.2≡⎕NC⊂function + t←⎕TS + Z←(⍎function,' ⍬')0 + t←⎕TS-t + :Else + t←⎕TS + Z←(⍎function)0 + t←⎕TS-t + :EndIf + + :Else + Z←(↑⎕DM)1 + :If exception≢⍬ + expect←exception + Z[2]←0 + t←⎕TS-t + :EndIf + :EndTrap + Z,←⊂t + ∇ + + ∇ reset_UT_globals + expect_orig ← expect← ⎕NS⍬ + exception←⍬ + nexpect_orig ← nexpect← ⎕NS⍬ + ∇ + + ∇ Z←is_test FunctionName;wsIndex + wsIndex←FunctionName⍳' ' + FunctionName←(wsIndex-1)↑FunctionName + Z←'_TEST'≡¯5↑FunctionName + ∇ + + ∇ Heading print_passed_crashed_failed(ArrayRes time) + ⎕←'-----------------------------------------' + ⎕←Heading + ⎕←' ⍋ Passed: ',+/{1⊃⍵}¨ArrayRes + ⎕←' ⍟ Crashed: ',+/{2⊃⍵}¨ArrayRes + ⎕←' ⍒ Failed: ',+/{3⊃⍵}¨ArrayRes + ⎕←' ○ Runtime: ',time[5],'m',time[6],'s',time[7],'ms' + ∇ + + determine_pass_crash_or_fail←{ + r c←⍵ ⋄ 0≠c:0 1 0 ⋄ z←(0 0 1)(1 0 0) + expect_orig≢expect:(⎕IO+expect≡r)⊃z ⋄ (⎕IO+nexpect≢r)⊃z + } + + ∇ Z←determine_message(pass fail crashed name returned time) + :If crashed + Z←'CRASHED: 'failure_message name returned + :ElseIf pass + Z←'Passed ',time[5],'m',time[6],'s',time[7],'ms' + :Else + Z←'FAILED: 'failure_message name returned + :EndIf + ∇ + + ∇ print_message_to_screen message + ⎕←message + ∇ + + ∇ Z←term_to_text Term;Text;Rows + Text←#.DISPLAY Term + Rows←1⊃⍴Text + Z←(Rows 4⍴''),Text + ∇ + + ∇ Z←Cause failure_message(name returned);hdr;exp;expterm;got;gotterm + hdr←Cause,name + exp←'Expected' + expterm←term_to_text #.UT.expect + got←'Got' + gotterm←term_to_text returned + Z←align_and_join_message_parts hdr exp expterm got gotterm + ∇ + + ∇ Z←align_and_join_message_parts Parts;hdr;exp;expterm;got;gotterm;R1;C1;R2;C2;W + (hdr exp expterm got gotterm)←Parts + (R1 C1)←⍴expterm + (R2 C2)←⍴gotterm + W←⊃⊃⌈/C1 C2(⍴hdr)(⍴exp)(⍴got) + Z←(W↑hdr),[0.5](W↑exp) + Z←Z⍪(R1 W↑expterm) + Z←Z⍪(W↑got) + Z←Z⍪(R2 W↑gotterm) + ∇ + + ∇ Z←confparam in config + Z←1↓⊃({confparam≡⊃⍵}¨config)/config + ∇ + + ∇ Z←config has confparam + Z←∨/{confparam≡⊃⍵}¨config + ∇ + +:EndNameSpace diff --git a/samples/LOLCODE/LOLTracer.lol b/samples/LOLCODE/LOLTracer.lol new file mode 100644 index 00000000..9d8a6d20 --- /dev/null +++ b/samples/LOLCODE/LOLTracer.lol @@ -0,0 +1,795 @@ +HAI 1.3 + OBTW + Author: Logan Kelly (logan.kelly@gmail.com) + Github: https://github.com/LoganKelly/LOLTracer + TLDR + + OBTW prev is the number used in the randin function. + I had to declare it in global scope so that it + would retain its value between calls to randin. + TLDR + I HAS A prev ITZ 0 + I HAS A rand_max ITZ 104729 + + + OBTW Equivalent to C's rand() function, except returns + a number in the range of 0 to rand_max. + TLDR + HOW IZ I randin + I HAS A a ITZ 33083 + I HAS A c ITZ 67607 + prev R MOD OF SUM OF PRODUKT OF prev AN a AN c AN rand_max + FOUND YR prev + IF U SAY SO + + + BTW Returns a random number within the range of 0-1. + HOW IZ I rand_onein + I HAS A rand_num ITZ I IZ randin MKAY + rand_num IS NOW A NUMBAR + I HAS A rand_max_float ITZ MAEK rand_max A NUMBAR + FOUND YR QUOSHUNT OF rand_num AN rand_max_float + IF U SAY SO + + + OBTW Equivalent to C ceil() function. Returns the next + largest integer for the given number. + TLDR + HOW IZ I ceilin YR num + I HAS A int_num ITZ num + int_num IS NOW A NUMBR + BOTH SAEM int_num AN num, O RLY? + YA RLY, FOUND YR num + OIC + DIFFRINT num AN SMALLR OF num AN 0, O RLY? + YA RLY + int_num R SUM OF int_num AN 1 + FOUND YR MAEK int_num A NUMBAR + OIC + DIFFRINT num AN BIGGR OF num AN 0, O RLY? + YA RLY + FOUND YR MAEK int_num A NUMBAR + OIC + IF U SAY SO + + + OBTW Convert a number to hexadecimal. This + is returned as a string. + TLDR + HOW IZ I decimal_to_hex YR num + I HAS A i ITZ 0 + I HAS A rem + I HAS A hex_num ITZ A BUKKIT + I HAS A decimal_num ITZ num + IM IN YR num_loop + rem R MOD OF decimal_num AN 16 + I HAS A hex_digit + rem, WTF? + OMG 10, hex_digit R "A", GTFO + OMG 11, hex_digit R "B", GTFO + OMG 12, hex_digit R "C", GTFO + OMG 13, hex_digit R "D", GTFO + OMG 14, hex_digit R "E", GTFO + OMG 15, hex_digit R "F", GTFO + OMGWTF, hex_digit R rem + OIC + hex_num HAS A SRS i ITZ hex_digit + decimal_num R QUOSHUNT OF decimal_num AN 16 + BOTH SAEM decimal_num AN 0, O RLY? + YA RLY, GTFO + NO WAI, i R SUM OF i AN 1 + OIC + IM OUTTA YR num_loop + I HAS A hex_string ITZ A YARN + IM IN YR string_reverse + DIFFRINT i AN BIGGR OF i AN 0, O RLY? + YA RLY, GTFO + OIC + hex_string R SMOOSH hex_string AN hex_num'Z SRS i MKAY + i R DIFF OF i AN 1 + IM OUTTA YR string_reverse + FOUND YR hex_string + IF U SAY SO + + + OBTW Convert a number to binary. This is returned + as a bukkit which has slots number 0-N where + n is equal to the number of binary digits - 1. + It also has a length slot which is equal to + the number of binary digits. + TLDR + HOW IZ I decimal_to_binary YR num + I HAS A i ITZ 0 + I HAS A decimal_num ITZ num + I HAS A binary_num ITZ A BUKKIT + IM IN YR num_loop + binary_num HAS A SRS i ITZ MOD OF decimal_num AN 2 + decimal_num R QUOSHUNT OF decimal_num AN 2 + BOTH SAEM decimal_num AN 0, O RLY? + YA RLY + I HAS A length ITZ SUM OF i AN 1 + binary_num HAS A length ITZ length + GTFO + NO WAI, i R SUM OF i AN 1 + OIC + IM OUTTA YR num_loop + FOUND YR binary_num + IF U SAY SO + + + OBTW Bitwise and two binary numbers. The numbers + must be provided in the format returned by + decimal_to_binary. + TLDR + HOW IZ I bitwise_andin YR first_num AN YR second_num + I HAS A binary_first_num ITZ I IZ decimal_to_binary YR first_num MKAY + I HAS A binary_second_num ITZ I IZ decimal_to_binary YR second_num MKAY + I HAS A first_length ITZ binary_first_num'Z length + I HAS A second_length ITZ binary_second_num'Z length + I HAS A max_length ITZ BIGGR OF first_length AN second_length + I HAS A final_binary ITZ A BUKKIT + I HAS A final_length ITZ 0 + I HAS A i ITZ 0 + IM IN YR num_loop + BOTH SAEM i AN max_length, O RLY? + YA RLY, GTFO + OIC + I HAS A first_binary ITZ 0 + I HAS A second_binary ITZ 0 + DIFFRINT i AN BIGGR OF i AN first_length, O RLY? + YA RLY, first_binary R binary_first_num'Z SRS i + OIC + DIFFRINT i AN BIGGR OF i AN second_length, O RLY? + YA RLY, second_binary R binary_second_num'Z SRS i + OIC + EITHER OF BOTH SAEM first_binary AN 0 AN ... + BOTH SAEM second_binary AN 0, O RLY? + YA RLY, final_binary HAS A SRS i ITZ 0 + NO WAI + final_binary HAS A SRS i ITZ 1 + final_length R SUM OF i AN 1 + OIC + i R SUM OF i AN 1 + IM OUTTA YR num_loop + final_binary HAS A length ITZ final_length + FOUND YR final_binary + IF U SAY SO + + + OBTW Bitshift left a binary number by num_bits. + The binary number must be provided in the format + returned by decimal_to_binary. + TLDR + HOW IZ I bit_shift_leftin YR num AN YR num_bits + I HAS A binary_num ITZ num + I HAS A length ITZ binary_num'Z length + I HAS A i ITZ SUM OF DIFF OF length AN 1 AN num_bits + I HAS A shifted_binary_num ITZ A BUKKIT + IM IN YR num_loop + BOTH SAEM i AN -1, O RLY? + YA RLY, GTFO + OIC + I HAS A unshifted_index ITZ DIFF OF i AN num_bits + BOTH SAEM unshifted_index AN BIGGR OF unshifted_index AN 0, O RLY? + YA RLY + shifted_binary_num HAS A SRS i ITZ binary_num'Z SRS unshifted_index + NO WAI + shifted_binary_num HAS A SRS i ITZ 0 + OIC + i R DIFF OF i AN 1 + IM OUTTA YR num_loop + shifted_binary_num HAS A length ITZ SUM OF binary_num'Z length AN num_bits + FOUND YR shifted_binary_num + IF U SAY SO + + + OBTW Convert a binary number into a decimal number. + The binary number must be provided in the format + return by decimal_to_binary. + TLDR + HOW IZ I binary_to_decimal YR binary_num + I HAS A length ITZ binary_num'Z length + I HAS A decimal_num ITZ 0 + I HAS A i ITZ 0 + IM IN YR num_loop + BOTH SAEM i AN length, O RLY? + YA RLY, GTFO + OIC + I HAS A binary_value ITZ binary_num'Z SRS i + I HAS A decimal_value ITZ 0 + BOTH SAEM binary_value AN 1, O RLY? + YA RLY, decimal_value R I IZ power_of YR 2 AN YR i MKAY + OIC + decimal_num R SUM OF decimal_num AN decimal_value + i R SUM OF i AN 1 + IM OUTTA YR num_loop + FOUND YR decimal_num + IF U SAY SO + + + OBTW Equivalent to C's pow() function. Raises + base to the power of exponent. + TLDR + HOW IZ I power_of YR base AN YR exponent + I HAS A i ITZ 0 + I HAS A num ITZ 1 + IM IN YR num_loop + BOTH SAEM i AN exponent, O RLY? + YA RLY, GTFO + OIC + num R PRODUKT OF num AN base + i R SUM OF i AN 1 + IM OUTTA YR num_loop + FOUND YR num + IF U SAY SO + + + OBTW Return a binary number as a YARN. + The binary number must be provided in the format + return by decimal_to_binary. + TLDR + HOW IZ I binary_to_string YR binary_num + I HAS A binary_string ITZ A YARN + I HAS A i ITZ DIFF OF binary_num'Z length AN 1 + IM IN YR string_reverse + DIFFRINT i AN BIGGR OF i AN 0, O RLY? + YA RLY, GTFO + OIC + binary_string R SMOOSH binary_string AN binary_num'Z SRS i MKAY + i R DIFF OF i AN 1 + IM OUTTA YR string_reverse + FOUND YR binary_string + IF U SAY SO + + OBTW Converts a hexadecimal number to the character + equivalent in UNICODE. This was originally used + in an attempt to write out to the P6 format of PPM, + but the string produced by VISIBLE didn't seem to be + properly formatted for some reason. Instead I fell back + to P3 of PPM and wrote out to regular ascii format. + TLDR + HOW IZ I hex_to_char YR hex_string + OBTW This is a hack I found for converting hexadecimal strings + into their unicode character equivalents. Instead of using + the ":" character directly, we escape it and get it using its + unicode hex value (3A). This allows us to assemble the string + with our inserted hex value without errors. + TLDR + FOUND YR SMOOSH ":(3A)" AN "(" AN hex_string AN ")" MKAY + IF U SAY SO + + + OBTW Equivalent to C's square() function. However it will only + produce accurate results if the number is no larger than + 1048576. See the note below. This is based upon Newton's + Approximation Method as adapted in C at this website (#11): + + http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi + TLDR + HOW IZ I square_rootin YR number + OBTW Forcing a comparison between the accuracy and a number + which is so big that its precision is larger than the + accuracy causes an infinite loop to occur. For this + reason we have to set any number larger than 2^20 to + a value below it. + TLDR + BOTH SAEM number AN BIGGR OF number AN 1048576.00, O RLY? + YA RLY, number R 1048575.00 + OIC + I HAS A accuracy ITZ 0.0001 + I HAS A lower ITZ A NUMBAR + I HAS A upper ITZ A NUMBAR + I HAS A guess ITZ A NUMBAR + DIFFRINT number AN BIGGR OF number AN 1.0, O RLY? + YA RLY + lower R number + upper R 1.0 + NO WAI + lower R 1.0 + upper R number + OIC + IM IN YR LOOP + I HAS A delta ITZ DIFF OF upper AN lower + BOTH SAEM delta AN SMALLR OF delta AN accuracy, O RLY? + YA RLY, GTFO + OIC + I HAS A guess ITZ QUOSHUNT OF SUM OF lower AN upper AN 2.0 + I HAS A guess_squared ITZ PRODUKT OF guess AN guess + DIFFRINT guess_squared AN SMALLR OF guess_squared AN number, O RLY? + YA RLY + upper R guess + NO WAI + lower R guess + OIC + IM OUTTA YR LOOP + FOUND YR QUOSHUNT OF SUM OF lower AN upper AN 2.0 + IF U SAY SO + + + OBTW + The intersection test for line [o, d] + Return 2 if a hit was found (and also return distance t and bouncing ray n). + Return 0 if no hit was found but ray goes upward + Return 1 if no hit was found but ray goes downward + TLDR + HOW IZ I tracin YR o AN YR d + I HAS A t ITZ 1000000000 + I HAS A m ITZ 0 + BOTH SAEM d'Z z AN 0, O RLY? + YA RLY, d'Z z R 0.00001 + OIC + I HAS A p ITZ QUOSHUNT OF DIFF OF 0 AN o'Z z AN d'Z z + I HAS A n ITZ LIEK A Vector + DIFFRINT p AN SMALLR OF p AN 0.01, O RLY? + YA RLY + t R p + n R Vector IZ constructin YR 0.0 AN YR 0.0 AN YR 1.0 MKAY + m R 1 + OIC + + BTW The world is encoded in sphere_positions, with 9 lines and 19 columns + I HAS A k ITZ 18 + IM IN YR column_loop BTW For each column of objects + BOTH SAEM k AN -1, O RLY? + YA RLY, GTFO + OIC + + I HAS A j ITZ 8 + IM IN YR line_loop BTW For each line on that column + BOTH SAEM j AN -1, O RLY? + YA RLY, GTFO + OIC + + I HAS A sphere_positions_line ITZ sphere_positions'Z SRS j + sphere_positions_line'Z SRS k, O RLY? + YA RLY + BTW There is a sphere, but does the ray hit it? + p R Vector IZ addin YR o AN YR ... + Vector IZ constructin YR DIFF OF 0 AN k AN ... + YR 0 AN ... + YR DIFF OF DIFF OF 0 AN j AN 4 MKAY ... + MKAY + I HAS A b ITZ Vector IZ dot_productin YR p AN YR d MKAY + I HAS A q_c ITZ DIFF OF Vector IZ dot_productin YR p AN YR p MKAY AN 1 + I HAS A q ITZ DIFF OF PRODUKT OF b AN b AN q_c + + + DIFFRINT q AN SMALLR OF q AN 0, O RLY? + YA RLY + BTW It does, compute the distance camera-sphere + I HAS A s ITZ DIFF OF DIFF OF 0 AN b AN I IZ square_rootin YR q MKAY + + + BOTH OF DIFFRINT s AN BIGGR OF s AN t AN ... + DIFFRINT s AN SMALLR OF s AN 0.01, O RLY? + YA RLY + BTW So far this is the minimum distance, save it. And + BTW also compute the bouncing ray vector into 'n' + t R s + I HAS A bouncing_ray ITZ Vector IZ scalin YR direction AN YR t MKAY + bouncing_ray R Vector IZ addin YR p AN YR bouncing_ray MKAY + n R Vector IZ normalizin YR bouncing_ray MKAY + m R 2 + OIC + OIC + OIC + j R DIFF OF j AN 1 + IM OUTTA YR line_loop + k R DIFF OF k AN 1 + IM OUTTA YR column_loop + I HAS A result ITZ A BUKKIT + result HAS A m ITZ m + result HAS A t ITZ t + result HAS A n ITZ n + FOUND YR result + IF U SAY SO + + + OBTW + Sample the world and return the pixel color for + a ray [o, d] + TLDR + HOW IZ I samplin YR o AN YR d + + BTW Search for an intersection ray Vs. world + I HAS A result ITZ I IZ tracin YR o AN YR d MKAY + I HAS A m ITZ result'Z m + I HAS A t ITZ result'Z t + I HAS A n ITZ result'Z n + + BOTH SAEM m AN 0, O RLY? + YA RLY + BTW No sphere found and the ray goes upward: Generate a sky color + I HAS A vec_result ITZ Vector IZ constructin YR 0.7 AN YR 0.6 AN YR 1.0 MKAY + + I HAS A z_component ITZ d'Z z + DIFFRINT z_component AN BIGGR OF z_component AN 0, O RLY? + YA RLY, z_component R 0 + OIC + I HAS A vec_num ITZ DIFF OF 1 AN z_component + vec_num R I IZ power_of YR vec_num AN YR 4 MKAY + FOUND YR Vector IZ scalin YR vec_result AN YR vec_num MKAY + OIC + + BTW h = intersection coordinate + I HAS A h ITZ Vector IZ scalin YR d AN YR t MKAY + h R Vector IZ addin YR o AN YR h MKAY + BTW l = direction to light (with random delta for soft shadows) + I HAS A l ITZ LIEK A Vector + l HAS A x ITZ SUM OF 9 AN I IZ rand_onein MKAY + l HAS A y ITZ SUM OF 9 AN I IZ rand_onein MKAY + l HAS A z ITZ 16 + I HAS A l_two ITZ Vector IZ scalin YR h AN YR -1.0 MKAY + l R Vector IZ addin YR l AN YR l_two MKAY + l R Vector IZ normalizin YR l MKAY + BTW r = The half-vector + I HAS A r ITZ Vector IZ dot_productin YR n AN YR d MKAY + r R PRODUKT OF r AN -2 + r R Vector IZ scalin YR n AN YR r MKAY + r R Vector IZ addin YR d AN YR r MKAY + + BTW Calculate the lambertian factor + I HAS A b ITZ Vector IZ dot_productin YR l AN YR n MKAY + + BTW Calculate illumination factor (lambertian coefficient > 0 or in shadow)? + I HAS A illumination_result ITZ I IZ tracin YR h AN YR l MKAY + I HAS A i_m ITZ illumination_result'Z m + EITHER OF DIFFRINT b AN BIGGR OF b AN 0 AN BOTH SAEM i_m AN 2, O RLY? + YA RLY, b R 0 + OIC + + BTW Calculate the color 'p' with diffuse and specular component + I HAS A base + DIFFRINT b AN SMALLR OF b AN 0, O RLY? + YA RLY, base R 1 + NO WAI, base R 0 + OIC + base R Vector IZ scalin YR r AN YR base MKAY + base R Vector IZ dot_productin YR l AN YR r MKAY + I HAS A p ITZ I IZ power_of YR base AN YR 99 MKAY + + BOTH SAEM m AN 1, O RLY? + YA RLY + BTW No sphere was hit and the ray was going downward: Generate a floor color + h R Vector IZ scalin YR h AN YR 0.2 MKAY + I HAS A ceil_h_x ITZ I IZ ceilin YR h'Z x MKAY + I HAS A ceil_h_y ITZ I IZ ceilin YR h'Z y MKAY + I HAS A ceil_h ITZ SUM OF ceil_h_x AN ceil_h_y + ceil_h IS NOW A NUMBR + I HAS A color_choice ITZ MOD OF ceil_h AN 2 + I HAS A color ITZ LIEK A Vector + color_choice, O RLY? + YA RLY + color HAS A x ITZ 3 + color HAS A y ITZ 1 + color HAS A z ITZ 1 + NO WAI + color HAS A x ITZ 3 + color HAS A y ITZ 3 + color HAS A z ITZ 3 + OIC + FOUND YR Vector IZ scalin YR color AN YR SUM OF PRODUKT OF b AN 0.2 AN 0.1 MKAY + OIC + + BTW m == 2 A sphere was hit. Cast a ray bouncing from the sphere surface. + I HAS A sphere_color ITZ LIEK A Vector + sphere_color HAS A x ITZ p + sphere_color HAS A y ITZ p + sphere_color HAS A z ITZ p + I HAS A recursive_color ITZ I IZ samplin YR h AN YR r MKAY + BTW Attenuate color by 50% since it is bouncing (* .5) + recursive_color R Vector IZ scalin YR recursive_color AN YR 0.5 MKAY + FOUND YR Vector IZ addin YR sphere_color AN YR recursive_color MKAY + IF U SAY SO + + + OBTW The vector class provides functionality for all the common + linear algebra operations performed on vectors. + TLDR + O HAI IM Vector + I HAS A x ITZ 0 + I HAS A y ITZ 0 + I HAS A z ITZ 0 + + BTW Add vector_one and vector_two + HOW IZ I addin YR vector_one AN YR vector_two + I HAS A result ITZ LIEK A Vector + result HAS A x ITZ 0 + result HAS A y ITZ 0 + result HAS A z ITZ 0 + result'Z x R SUM OF vector_one'Z x AN vector_two'Z x + result'Z y R SUM OF vector_one'Z y AN vector_two'Z y + result'Z z R SUM OF vector_one'Z z AN vector_two'Z z + FOUND YR result + IF U SAY SO + + BTW Scale vector_one by value + HOW IZ I scalin YR vector_one AN YR value + I HAS A result ITZ LIEK A Vector + result HAS A x ITZ 0 + result HAS A y ITZ 0 + result HAS A z ITZ 0 + result'Z x R PRODUKT OF vector_one'Z x AN value + result'Z y R PRODUKT OF vector_one'Z y AN value + result'Z z R PRODUKT OF vector_one'Z z AN value + FOUND YR result + IF U SAY SO + + BTW Dot product of vector_one and vector_two + HOW IZ I dot_productin YR vector_one AN YR vector_two + FOUND YR SUM OF SUM OF PRODUKT OF vector_one'Z x AN vector_two'Z x AN ... + PRODUKT OF vector_one'Z y AN vector_two'Z y AN ... + PRODUKT OF vector_one'Z z AN vector_two'Z z + IF U SAY SO + + BTW Cross product of vector_one and vector_two + HOW IZ I cross_productin YR vector_one AN YR vector_two + I HAS A result ITZ LIEK A Vector + result HAS A x ITZ 0 + result HAS A y ITZ 0 + result HAS A z ITZ 0 + result'Z x R DIFF OF PRODUKT OF vector_one'Z y AN vector_two'Z z AN ... + PRODUKT OF vector_one'Z z AN vector_two'Z y + result'Z y R DIFF OF PRODUKT OF vector_one'Z z AN vector_two'Z x AN ... + PRODUKT OF vector_one'Z x AN vector_two'Z z + result'Z z R DIFF OF PRODUKT OF vector_one'Z x AN vector_two'Z y AN ... + PRODUKT OF vector_one'Z y AN vector_two'Z x + FOUND YR result + IF U SAY SO + + BTW Length of vector_one + HOW IZ I lengthin YR vector_one + FOUND YR I IZ square_rootin YR ... + SUM OF SUM OF PRODUKT OF vector_one'Z x AN vector_one'Z x AN ... + PRODUKT OF vector_one'Z y AN vector_one'Z y AN ... + PRODUKT OF vector_one'Z z AN vector_one'Z z MKAY + IF U SAY SO + + BTW Normalize vector_one + HOW IZ I normalizin YR vector_one + I HAS A result ITZ LIEK A Vector + result HAS A x ITZ 0 + result HAS A y ITZ 0 + result HAS A z ITZ 0 + I HAS A length ITZ Vector IZ lengthin YR vector_one MKAY + BOTH SAEM length AN 0, O RLY? + YA RLY + length R 1 + OIC + result'Z x R QUOSHUNT OF vector_one'Z x AN length + result'Z y R QUOSHUNT OF vector_one'Z y AN length + result'Z z R QUOSHUNT OF vector_one'Z z AN length + FOUND YR result + IF U SAY SO + + BTW Printable YARN version of vector + HOW IZ I to_stringin YR vector + FOUND YR SMOOSH "[" AN vector'Z x AN ", " ... + AN vector'Z y AN ", " ... + AN vector'Z z AN "]" MKAY + IF U SAY SO + + BTW Create and return a vector with components x, y, and z + HOW IZ I constructin YR x AN YR y AN YR z + I HAS A result ITZ LIEK A Vector + result HAS A x ITZ x + result HAS A y ITZ y + result HAS A z ITZ z + FOUND YR result + IF U SAY SO + KTHX + + OBTW The positions of the spheres are essentially + stored in a 2-D array. This differs from Kensler's + version where he used bit flags to store the + positions in a compressed and quickly accessed + manner. Unfortunately for us, bit operations + in LOLCODE were too slow for this to be a tenable + solution. + TLDR + I HAS A sphere_positions ITZ A BUKKIT + I HAS A sphere_positions_0 ITZ A BUKKIT + IM IN YR LOOP UPPIN YR pos_index TIL BOTH SAEM pos_index AN 19 + sphere_positions_0 HAS A SRS pos_index ITZ FAIL + IM OUTTA YR LOOP + sphere_positions HAS A SRS 0 ITZ sphere_positions_0 + I HAS A sphere_positions_1 ITZ A BUKKIT + sphere_positions_1 HAS A SRS 0 ITZ WIN + BTW sphere_positions_1 HAS A SRS 0 ITZ FAIL + sphere_positions_1 HAS A SRS 1 ITZ FAIL + sphere_positions_1 HAS A SRS 2 ITZ WIN + BTW sphere_positions_1 HAS A SRS 2 ITZ FAIL + sphere_positions_1 HAS A SRS 3 ITZ FAIL + sphere_positions_1 HAS A SRS 4 ITZ WIN + BTW sphere_positions_1 HAS A SRS 4 ITZ FAIL + sphere_positions_1 HAS A SRS 5 ITZ FAIL + sphere_positions_1 HAS A SRS 6 ITZ FAIL + sphere_positions_1 HAS A SRS 7 ITZ WIN + BTW sphere_positions_1 HAS A SRS 7 ITZ FAIL + sphere_positions_1 HAS A SRS 8 ITZ FAIL + sphere_positions_1 HAS A SRS 9 ITZ WIN + BTW sphere_positions_1 HAS A SRS 9 ITZ FAIL + sphere_positions_1 HAS A SRS 10 ITZ FAIL + sphere_positions_1 HAS A SRS 11 ITZ WIN + BTW sphere_positions_1 HAS A SRS 11 ITZ FAIL + sphere_positions_1 HAS A SRS 12 ITZ FAIL + sphere_positions_1 HAS A SRS 13 ITZ FAIL + sphere_positions_1 HAS A SRS 14 ITZ WIN + BTWsphere_positions_1 HAS A SRS 14 ITZ FAIL + sphere_positions_1 HAS A SRS 15 ITZ FAIL + sphere_positions_1 HAS A SRS 16 ITZ WIN + BTW sphere_positions_1 HAS A SRS 16 ITZ FAIL + sphere_positions_1 HAS A SRS 17 ITZ FAIL + sphere_positions_1 HAS A SRS 18 ITZ WIN + BTW sphere_positions_1 HAS A SRS 18 ITZ FAIL + sphere_positions HAS A SRS 1 ITZ sphere_positions_1 + I HAS A sphere_positions_2 ITZ A BUKKIT + IM IN YR LOOP UPPIN YR pos_index TIL BOTH SAEM pos_index AN 19 + sphere_positions_2 HAS A SRS pos_index ITZ FAIL + IM OUTTA YR LOOP + sphere_positions HAS A SRS 2 ITZ sphere_positions_2 + I HAS A sphere_positions_3 ITZ A BUKKIT + sphere_positions_3 HAS A SRS 0 ITZ FAIL + sphere_positions_3 HAS A SRS 1 ITZ FAIL + sphere_positions_3 HAS A SRS 2 ITZ FAIL + sphere_positions_3 HAS A SRS 3 ITZ FAIL + sphere_positions_3 HAS A SRS 4 ITZ WIN + BTW sphere_positions_3 HAS A SRS 4 ITZ FAIL + sphere_positions_3 HAS A SRS 5 ITZ FAIL + sphere_positions_3 HAS A SRS 6 ITZ FAIL + sphere_positions_3 HAS A SRS 7 ITZ WIN + BTW sphere_positions_3 HAS A SRS 7 ITZ FAIL + sphere_positions_3 HAS A SRS 8 ITZ FAIL + sphere_positions_3 HAS A SRS 9 ITZ FAIL + sphere_positions_3 HAS A SRS 10 ITZ FAIL + sphere_positions_3 HAS A SRS 11 ITZ WIN + sphere_positions_3 HAS A SRS 12 ITZ FAIL + sphere_positions_3 HAS A SRS 13 ITZ FAIL + sphere_positions_3 HAS A SRS 14 ITZ FAIL + sphere_positions_3 HAS A SRS 15 ITZ FAIL + sphere_positions_3 HAS A SRS 16 ITZ FAIL + sphere_positions_3 HAS A SRS 17 ITZ FAIL + sphere_positions_3 HAS A SRS 18 ITZ WIN + BTW sphere_positions_3 HAS A SRS 18 ITZ FAIL + sphere_positions HAS A SRS 3 ITZ sphere_positions_3 + I HAS A sphere_positions_4 ITZ A BUKKIT + IM IN YR LOOP UPPIN YR pos_index TIL BOTH SAEM pos_index AN 19 + sphere_positions_4 HAS A SRS pos_index ITZ FAIL + IM OUTTA YR LOOP + sphere_positions HAS A SRS 4 ITZ sphere_positions_4 + I HAS A sphere_positions_5 ITZ A BUKKIT + sphere_positions_5 HAS A SRS 0 ITZ FAIL + sphere_positions_5 HAS A SRS 1 ITZ FAIL + sphere_positions_5 HAS A SRS 2 ITZ FAIL + sphere_positions_5 HAS A SRS 3 ITZ FAIL + sphere_positions_5 HAS A SRS 4 ITZ WIN + BTW sphere_positions_5 HAS A SRS 4 ITZ FAIL + sphere_positions_5 HAS A SRS 5 ITZ FAIL + sphere_positions_5 HAS A SRS 6 ITZ FAIL + sphere_positions_5 HAS A SRS 7 ITZ WIN + BTW sphere_positions_5 HAS A SRS 7 ITZ FAIL + sphere_positions_5 HAS A SRS 8 ITZ FAIL + sphere_positions_5 HAS A SRS 9 ITZ WIN + BTW sphere_positions_5 HAS A SRS 9 ITZ FAIL + sphere_positions_5 HAS A SRS 10 ITZ FAIL + sphere_positions_5 HAS A SRS 11 ITZ WIN + BTW sphere_positions_5 HAS A SRS 11 ITZ FAIL + sphere_positions_5 HAS A SRS 12 ITZ FAIL + sphere_positions_5 HAS A SRS 13 ITZ FAIL + sphere_positions_5 HAS A SRS 14 ITZ FAIL + sphere_positions_5 HAS A SRS 15 ITZ FAIL + sphere_positions_5 HAS A SRS 16 ITZ FAIL + sphere_positions_5 HAS A SRS 17 ITZ FAIL + sphere_positions_5 HAS A SRS 18 ITZ WIN + BTW sphere_positions_5 HAS A SRS 18 ITZ FAIL + sphere_positions HAS A SRS 5 ITZ sphere_positions_5 + I HAS A sphere_positions_6 ITZ A BUKKIT + IM IN YR LOOP UPPIN YR pos_index TIL BOTH SAEM pos_index AN 19 + sphere_positions_6 HAS A SRS pos_index ITZ FAIL + IM OUTTA YR LOOP + sphere_positions HAS A SRS 6 ITZ sphere_positions_6 + I HAS A sphere_positions_7 ITZ A BUKKIT + IM IN YR LOOP UPPIN YR pos_index TIL BOTH SAEM pos_index AN 19 + sphere_positions_7 HAS A SRS pos_index ITZ FAIL + IM OUTTA YR LOOP + sphere_positions HAS A SRS 7 ITZ sphere_positions_7 + I HAS A sphere_positions_8 ITZ A BUKKIT + IM IN YR LOOP UPPIN YR pos_index TIL BOTH SAEM pos_index AN 19 + sphere_positions_8 HAS A SRS pos_index ITZ FAIL + IM OUTTA YR LOOP + sphere_positions HAS A SRS 8 ITZ sphere_positions_8 + + BTW Camera direction + I HAS A g ITZ Vector IZ constructin YR -6.0 AN YR -16.0 AN YR 0.0 MKAY + g R Vector IZ normalizin YR g MKAY + + BTW Camera up vector + I HAS A a ITZ Vector IZ constructin YR 0.0 AN YR 0.0 AN YR 1.0 MKAY + a R Vector IZ cross_productin YR a AN YR g MKAY + a R Vector IZ normalizin YR a MKAY + a R Vector IZ scalin YR a AN YR 0.002 MKAY + BTW Camera right vector + I HAS A b ITZ Vector IZ cross_productin YR g AN YR a MKAY + b R Vector IZ normalizin YR b MKAY + b R Vector IZ scalin YR b AN YR 0.002 MKAY + BTW Camera eye offset + I HAS A c ITZ Vector IZ addin YR a AN YR b MKAY + c R Vector IZ scalin YR c AN YR -256.0 MKAY + c R Vector IZ addin YR c AN YR g MKAY + + I HAS A max_x ITZ 511 + I HAS A max_y ITZ max_x + BTW Issue the PPM Header info + VISIBLE "P3 " SUM OF max_x AN 1 " " SUM OF max_y AN 1 " 255"! + + I HAS A viewpoint ITZ Vector IZ constructin YR 17 AN YR 16 AN YR 8 MKAY + + I HAS A y ITZ max_y + IM IN YR y_loop + BOTH SAEM y AN -1, O RLY? + YA RLY, GTFO + OIC + I HAS A x ITZ max_x + IM IN YR x_loop + BOTH SAEM x AN -1, O RLY? + YA RLY, GTFO + OIC + I HAS A pixel_color ITZ Vector IZ constructin YR 13 AN YR 13 AN YR 13 MKAY + + I HAS A rays ITZ 64 + IM IN YR ray_loop + BOTH SAEM rays AN 0, O RLY? + YA RLY, GTFO + OIC + + BTW The delta to apply to the origin of the view (For Depth of View blur). + I HAS A a_rand ITZ DIFF OF I IZ rand_onein MKAY AN 0.5 + I HAS A t_a ITZ Vector IZ scalin YR a AN YR a_rand MKAY + t_a R Vector IZ scalin YR t_a AN YR 99.0 MKAY + I HAS A b_rand ITZ DIFF OF I IZ rand_onein MKAY AN 0.5 + I HAS A t_b ITZ Vector IZ scalin YR b AN YR b_rand MKAY + t_b R Vector IZ scalin YR t_b AN YR 99.0 MKAY + I HAS A t ITZ Vector IZ addin YR t_a AN YR t_b MKAY + + I HAS A origin ITZ Vector IZ addin YR viewpoint AN YR t MKAY + + BTW Ray direction with random deltas for stochastic sampling + I HAS A direction_up ITZ SUM OF I IZ rand_onein MKAY AN x + direction_up R Vector IZ scalin YR a AN YR direction_up MKAY + I HAS A direction_right ITZ SUM OF I IZ rand_onein MKAY AN y + direction_right R Vector IZ scalin YR b AN YR direction_right MKAY + I HAS A direction_t ITZ Vector IZ scalin YR t AN YR -1 MKAY + I HAS A direction ITZ Vector IZ addin YR direction_right AN YR direction_up MKAY + direction R Vector IZ addin YR direction AN YR c MKAY + direction R Vector IZ scalin YR direction AN YR 16 MKAY + direction R Vector IZ addin YR direction AN YR direction_t MKAY + direction R Vector IZ normalizin YR direction MKAY + + I HAS A sample_color ITZ I IZ samplin YR origin AN YR direction MKAY + sample_color R Vector IZ scalin YR sample_color AN YR 3.5 MKAY + BTW + pixel_color for color accumulation + pixel_color R Vector IZ addin YR sample_color AN YR pixel_color MKAY + rays R DIFF OF rays AN 1 + IM OUTTA YR ray_loop + I HAS A write_color ITZ pixel_color + write_color'Z x IS NOW A NUMBR + write_color'Z y IS NOW A NUMBR + write_color'Z z IS NOW A NUMBR + DIFFRINT write_color'Z x AN BIGGR OF write_color'Z x AN 0, O RLY? + YA RLY, write_color'Z x R 0 + OIC + DIFFRINT write_color'Z y AN BIGGR OF write_color'Z y AN 0, O RLY? + YA RLY, write_color'Z y R 0 + OIC + DIFFRINT write_color'Z z AN BIGGR OF write_color'Z z AN 0, O RLY? + YA RLY, write_color'Z z R 0 + OIC + VISIBLE " " write_color'Z x " " ... + " " write_color'Z y " " ... + " " write_color'Z z " "! + x R DIFF OF x AN 1 + IM OUTTA YR x_loop + y R DIFF OF y AN 1 + IM OUTTA YR y_loop + +KTHXBYE diff --git a/samples/Papyrus/CAMTEST_OverShoulderME.psc b/samples/Papyrus/CAMTEST_OverShoulderME.psc new file mode 100644 index 00000000..716a9a1b --- /dev/null +++ b/samples/Papyrus/CAMTEST_OverShoulderME.psc @@ -0,0 +1,68 @@ +Scriptname CAMTEST_OverShoulderME extends activemagiceffect +{Play with camera effects} + +;--=== Imports ===-- + +Import Utility +Import Game + +;--=== Properties ===-- + +Actor Property PlayerRef Auto +ActorBase Property CAMTEST_CameraActor Auto + +;--=== Variables ===-- + +Actor Player + +Actor Camera + +Actor Target + +Float PosX +Float PosY +Float PosZ +Float SpeedMult + +ObjectReference Mist +ObjectReference Fog + +;--=== Events ===-- + +Event OnInit() + Player = PlayerRef +EndEvent + +Event onEffectStart(Actor akTarget, Actor akCaster) + Camera = Player.PlaceActorAtMe(CAMTEST_CameraActor) + Camera.EnableAI(False) + Camera.SetScale(0.1) + Camera.TranslateTo(Player.X + 40,Player.Y,Player.Z,0,0,0,800,30) + DisablePlayerControls(abMovement = true, abFighting = true, abCamSwitch = true, abLooking = true, abSneaking = true, abMenu = true, abActivate = true, abJournalTabs = false) + SetPlayerAIDriven(True) + ForceThirdPerson() + SetHUDCartMode() + SetInChargen(True, True, False) + SetCameraTarget(Camera) + ForceFirstPerson() + Wait(1) + Camera.SplineTranslateTo(Player.X + 4000,Player.Y,Player.Z + 1000,15,0,Camera.GetHeadingAngle(Player) + Camera.GetAngleZ(),1800,800,100) +; Camera.SetLookAt(Player) + Wait(10) + Camera.SplineTranslateTo(Player.X + 1000,Player.Y - 500,Player.Z + 500,25,0,Camera.GetHeadingAngle(Player) + Camera.GetAngleZ(),1800,800,100) + Wait(10) + SetHUDCartMode(False) + SetCameraTarget(Player) + SetInChargen(False, False, False) + EnablePlayerControls() + SetPlayerAIDriven(False) +EndEvent + +Event onUpdate() +EndEvent + +Event onEffectFinish(Actor akTarget, Actor akCaster) +EndEvent + +;--=== Functions ===-- + diff --git a/samples/Papyrus/vMFX_FXPlugin.psc b/samples/Papyrus/vMFX_FXPlugin.psc new file mode 100644 index 00000000..a806a048 --- /dev/null +++ b/samples/Papyrus/vMFX_FXPlugin.psc @@ -0,0 +1 @@ +Scriptname vMFX_FXPlugin extends Quest diff --git a/samples/Papyrus/vSCM_MetaQuestScript.psc b/samples/Papyrus/vSCM_MetaQuestScript.psc new file mode 100644 index 00000000..d073a508 --- /dev/null +++ b/samples/Papyrus/vSCM_MetaQuestScript.psc @@ -0,0 +1,120 @@ +Scriptname vSCM_MetaQuestScript extends Quest +{Do initialization and track variables for scripts} + +;--=== Imports ===-- + +Import Utility +Import Game + +;--=== Properties ===-- + +Actor Property PlayerRef Auto + +Float Property ModVersion Auto Hidden + +String Property ModName = "Smarter Combat Music" Auto Hidden + +Message Property vSCM_ModLoadedMSG Auto +Message Property vSCM_ModUpdatedMSG Auto + +;--=== Variables ===-- + +Float _CurrentVersion +String _sCurrentVersion + +Bool _Running + +Float _ScriptLatency +Float _StartTime +Float _EndTime + +;--=== Events ===-- + +Event OnInit() + If ModVersion == 0 + DoUpkeep(True) + EndIf +EndEvent + +Event OnReset() + Debug.Trace("SCM: Metaquest event: OnReset") +EndEvent + +Event OnGameReloaded() + Debug.Trace("SCM: Metaquest event: OnGameReloaded") +EndEvent + +;--=== Functions ===-- + +Function DoUpkeep(Bool DelayedStart = True) + ;FIXME: CHANGE THIS WHEN UPDATING! + _CurrentVersion = 0.01 + _sCurrentVersion = GetVersionString(_CurrentVersion) + String sErrorMessage + If DelayedStart + Wait(RandomFloat(2,4)) + EndIf + Debug.Trace("SCM: " + ModName) + Debug.Trace("SCM: Performing upkeep...") + Debug.Trace("SCM: Loaded version is " + GetVersionString(ModVersion) + ", Current version is " + _sCurrentVersion) + If ModVersion == 0 + Debug.Trace("SCM: Newly installed, doing initialization...") + DoInit() + If ModVersion == _CurrentVersion + Debug.Trace("SCM: Initialization succeeded.") + Else + Debug.Trace("SCM: WARNING! Initialization had a problem!") + EndIf + ElseIf ModVersion < _CurrentVersion + Debug.Trace("SCM: Installed version is older. Starting the upgrade...") + DoUpgrade() + If ModVersion != _CurrentVersion + Debug.Trace("SCM: WARNING! Upgrade failed!") + Debug.MessageBox("WARNING! " + ModName + " upgrade failed for some reason. You should report this to the mod author.") + EndIf + Debug.Trace("SCM: Upgraded to " + _CurrentVersion) + vSCM_ModUpdatedMSG.Show(_CurrentVersion) + Else + Debug.Trace("SCM: Loaded, no updates.") + ;CheckForOrphans() + EndIf + CheckForExtras() + UpdateConfig() + Debug.Trace("SCM: Upkeep complete!") +EndFunction + +Function DoInit() + Debug.Trace("SCM: Initializing...") + _Running = True + ModVersion = _CurrentVersion + vSCM_ModLoadedMSG.Show(_CurrentVersion) +EndFunction + +Function DoUpgrade() + _Running = False + If ModVersion < 0.01 + Debug.Trace("SCM: Upgrading to 0.01...") + ModVersion = 0.01 + EndIf + _Running = True + Debug.Trace("SCM: Upgrade complete!") +EndFunction + +Function UpdateConfig() + Debug.Trace("SCM: Updating configuration...") + + Debug.Trace("SCM: Updated configuration values, some scripts may update in the background!") +EndFunction + +String Function GetVersionString(Float fVersion) + Int Major = Math.Floor(fVersion) as Int + Int Minor = ((fVersion - (Major as Float)) * 100.0) as Int + If Minor < 10 + Return Major + ".0" + Minor + Else + Return Major + "." + Minor + EndIf +EndFunction + +Function CheckForExtras() +EndFunction diff --git a/samples/Shell/build.command b/samples/Shell/build.command new file mode 100644 index 00000000..8e793c3a --- /dev/null +++ b/samples/Shell/build.command @@ -0,0 +1,30 @@ +set -e + +echo "/************/" +echo "/* BUILDING */" +echo "/************/" +echo "" + +cd `dirname $0` + +cd build + +cmake .. + +make + +echo "" +echo "/***********/" +echo "/* TESTING */" +echo "/***********/" +echo "" + +# ctest .. + +make Experimental + +echo "" +echo "/***********/" +echo "/* SUCCESS */" +echo "/***********/" +echo "" diff --git a/samples/SuperCollider/WarpPreset.sc b/samples/SuperCollider/WarpPreset.sc new file mode 100644 index 00000000..93aed4e7 --- /dev/null +++ b/samples/SuperCollider/WarpPreset.sc @@ -0,0 +1,19 @@ +WarpPreset { + *new {|path| + if(path.notNil) { + ^Object.readArchive(path); + }; + + ^super.new.init(); + } + + init { + + } + + save { + Dialog.savePanel({|path| + this.writeArchive(path); + }); + } +} \ No newline at end of file diff --git a/samples/SuperCollider/WarpTate.sc b/samples/SuperCollider/WarpTate.sc new file mode 100644 index 00000000..73c09e6d --- /dev/null +++ b/samples/SuperCollider/WarpTate.sc @@ -0,0 +1,286 @@ +WarpTate { + classvar tempoChannel; + var <>tempoControl; + var sections; + var sensorMinAdj; + var <>sensorMaxAdj; + var IdentityDictionary['notes' -> List[42]], + // '808_1' -> IdentityDictionary['notes' -> List[24]] + // ] + // ] + sensorKeys = ['303a', '303b', '808a', '808b']; + + // channel 16 reserved for tempo changes + availableControls = 15.collect {|channel| + (0..120).reject({|item, i| + [ 0, 1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 84, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 102 ].includes(item) + }); + }; + + controls = (0..127).collect { IdentityDictionary[] }; + + this.addOSCdefs(); + + CmdPeriod.add({this.stop}); + } + + tempo_ {|argTempo| + if(argTempo >= 50 && argTempo <= 177) { + tempo = argTempo; + clock.tempo = tempo / 60; + + out.control(tempoChannel, tempoControl, tempo - 50); + } { + "Tempo out of Logic's range :(".postln; + }; + } + + addTrack {|trackKey, channel, type| + tracks[trackKey] = WarpTrack(this, trackKey, channel, type); + ^tracks[trackKey]; + } + + loadTrack {|preset, checkAvailable| + var track = WarpTrack.load(this, preset, checkAvailable), + trackKey = track.settings['key']; + + tracks[trackKey] = track; + ^tracks[trackKey]; + } + + readTrack {|path| + var track = WarpTrack.read(this, path), + trackKey = track.settings['key']; + + tracks[trackKey] = track; + ^tracks[trackKey]; + } + + removeTrack {|trackKey| + tracks[trackKey].allOff(); + tracks[trackKey] = nil; + } + + removeAllTracks { + tracks = IdentityDictionary[]; + } + + on {|trackKey, note| + tracks[trackKey].on(note); + } + + off {|trackKey, note| + tracks[trackKey].off(note); + } + + hit {|trackKey, note=60, vel=127, dur=1| + tracks[trackKey].hit(note, vel, dur); + } + + noteOn {|midiChannel, note, vel| + out.noteOn(midiChannel, note, vel); + } + + noteOff {|midiChannel, note, vel| + out.noteOff(midiChannel, note, vel); + } + + control {|midiChannel, num, val| + out.control(midiChannel, num, val); + } + + isControlAvailable {|channel, controlNum| + ^controls[channel].keys.includes(controlNum.asSymbol).not; + } + + setControl {|channel, num, key| + controls[channel][num.asSymbol] = key; + availableControls[channel].remove(num); + } + + assign {|trackKey, paramKey, controlNum, learn=false| + var channel = tracks[trackKey].settings['midiChannel']; + + if(controlNum.notNil && this.isControlAvailable(channel, controlNum)) { + tracks[trackKey].assign(paramKey, controlNum, learn); + availableControls[channel].removeAt(0); + + } { + if(availableControls[channel].size > 0) { + tracks[trackKey].assign(paramKey, availableControls[channel][0], learn); + availableControls[channel].removeAt(0); + } { + "no controls left!".postln; + }; + }; + + "Don't forget to turn off MIDI learn".postln + } + + setParam {|trackKey, paramKey, val| + var track, param; + + if((track = tracks[trackKey]).notNil) { + if(track.params[paramKey].notNil) { + track.setParam(paramKey, val); + } { + "paramKey doesn't exist".postln; + }; + } { + "track key doesn't exist".postln; + }; + } + + // sec takes IdentityDictionarys of WarpTrack settings + addSection {|index, tempo=120, presets| + // Add section with tempo + sections[index] = IdentityDictionary[ + 'tempo' -> tempo, + 'tracks' -> presets + ]; + + presets.do {|preset, i| + // create track if there ain't one with this key + if(tracks.includesKey(preset['key']).not) { + this.loadTrack(preset, true); + }; + + // store the preset + // sections[index]['tracks'][preset['key']] = preset; + }; + + ^sections; + } + + play { + + if(sections.any {|item, i| item.notNil; }) { + playRout = Routine { + inf.do {|i| + sections.do {|section| + if(section.notNil) { + if(i !== 0) { + tracks.do {|track| + track.allOff(); + }; + this.removeAllTracks(); + }; + + this.tempo = section['tempo']; + + section['tracks'].do {|track, i| + var newTrack = this.loadTrack(track, false); + newTrack.play(); + }; + sectionDur.wait; + }; + }; + } + }; + clock.playNextBar(playRout); + } { + "no sections added!".postln; + }; + + } + + stop { + playRout.stop; + + tracks.do {|track| + track.allOff(); + out.allNotesOff(track.settings['midiChannel']); + } + } + + addOSCdefs { + sensorVals = 0!sensorKeys.size; + sensorPrevs = 0!sensorKeys.size; + sensorMins = 9999!sensorKeys.size; + sensorMaxs = 0!sensorKeys.size; + sensorMinAdj = sensorMinAdj ?? { 0.005 }; + sensorMaxAdj = sensorMaxAdj ?? { 0.01 }; + doAdjusts = false!sensorKeys.size; + + sensorKeys.do {|sensorKey, i| + OSCdef(("sensor_" ++ sensorKey).asSymbol, {|msg, time, addr, recvPort| + var val = msg[1]; + + + sensorPrevs[i] = sensorVals[i]; + sensorVals[i] = val; + + if(doAdjusts[i]) { + sensorMins[i] = min(val, sensorMins[i]); + sensorMaxs[i] = max(val, sensorMaxs[i]); + + if(val < sensorMaxs[i]) { + sensorMaxs[i] = sensorMaxs[i] - sensorMaxAdj; + }; + + if(val > sensorMins[i]) { + sensorMins[i] = sensorMins[i] + sensorMinAdj; + }; + } { + val = val.clip(sensorMins[i], sensorMaxs[i]); + }; + + + tracks.do {|track, j| + if(track.settings['sensorFuncs'].includesKey(sensorKey)) { + track.sensor( + sensorKey, + val.linlin( + sensorMins[i], + sensorMaxs[i], + 127, + 0 + ) + ); + }; + } + }, ("/prox/" ++ sensorKey).asSymbol); + } + } +} \ No newline at end of file diff --git a/samples/SuperCollider/WarpTrack.sc b/samples/SuperCollider/WarpTrack.sc new file mode 100644 index 00000000..d7521353 --- /dev/null +++ b/samples/SuperCollider/WarpTrack.sc @@ -0,0 +1,263 @@ +WarpTrack { + classvar argKey, + 'midiChannel' -> argMidiChannel, + 'notes' -> Set[], + 'params' -> IdentityDictionary[], + 'paramControls' -> IdentityDictionary[], + 'patternTrack' -> true, + 'sensorFuncs' -> IdentityDictionary[] + ]; + + if(argType.notNil) { + settings['type'] = argType; + if(WarpTrack.defaults.keys.includes(argType)) { + ['paramControls', 'params'].do {|key, i| + settings[key] = WarpTrack.defaults[argType][key]; + } + }; + + this.initParams(); + }; + } + + on {|note| + var clock = parent.clock; + var sub = 1 / (parent.clock.tempo * 16); // one sub division + + clock.schedAbs(clock.nextBar - sub, { + if(settings['patternTrack']) { + this.allOff(); + } { + this.off(note); + }; + }); + + parent.clock.playNextBar({ + settings['notes'].add(note); + parent.noteOn(settings['midiChannel'], note, 127); + }); + } + + off {|note| + // settings['notes'].remove(note); + parent.noteOff(settings['midiChannel'], note, 0); + } + + hit {|note=60, vel=127, dur=1, quant=0| + { + parent.noteOn(settings['midiChannel'], note, vel); + dur.wait; + parent.noteOff(settings['midiChannel'], note, vel); + }.fork(parent.clock, quant:quant); + } + + allOff { + settings['notes'].do {|note, i| + this.off(note); + }; + } + + assign {|paramKey, num, learn=false, init=true, checkAvailable=true| + if(num.notNil) { + this.assignAll(IdentityDictionary[paramKey -> num], learn, init, checkAvailable); + } { + parent.assign(settings['key'], paramKey, nil, learn); + }; + } + + assignAll {|paramControls, learn=false, init=true, checkAvailable=true| + var action = { + var channel = settings['midiChannel']; + + paramControls.keysValuesDo { |paramKey, num| + if(checkAvailable.not || + (checkAvailable && parent.isControlAvailable(channel, num))) { + settings['paramControls'][paramKey] = num; + if(init) { + settings['params'][paramKey] = 0; + }; + parent.setControl(channel, num, paramKey); + if(learn) { + parent.control(channel, num, 127); + 0.05.wait; + parent.control(channel, num, 0); + }; + paramKey ++ " assigned to controlNum " ++ num; + } { + ("this controlNum " ++ num ++ " is already assigned!").postln; + }; + }; + }; + + if(learn) { + action.fork; + } { + action.(); + }; + + } + + initParams { + settings['params'].keysValuesDo { |key, value| + this.setParam(key, value); + }; + settings['paramControls'].keysValuesDo { |key, value| + parent.setControl(settings['midiChannel'], value, key); + }; + } + + setParam {|paramKey, val, quant| + var func = { + parent.control( + settings['midiChannel'], + settings['paramControls'][paramKey], + val + ); + + settings['params'][paramKey] = val; + }; + + if(quant.notNil) { + { + func.(); + }.fork(parent.clock, quant:quant); + } { + func.(); + }; + } + + readPreset {|path, checkAvailable=true| + this.loadPreset(Object.readArchive(path), checkAvailable); + } + + loadPreset {|preset, checkAvailable=true| + // copy all settings except notes and paramControls + preset.keys.reject({|settingKey, i| + ['notes', 'paramControls'].includes(settingKey); + }).do {|presetKey, i| + settings[presetKey] = preset[presetKey]; + }; + + // copy notes if it's a patternTrack + if(preset['patternTrack']) { + settings['notes'] = preset['notes']; + }; + + // assign all without learn or init + this.assignAll( + preset['paramControls'], + false, + false, + checkAvailable + ); + + this.initParams(); + + // if(settings['notes'].size > 0) { + // this.on(settings['notes'].asArray[0]); + // }; + } + + sensor {|sensorKey, val| + settings['sensorFuncs'][sensorKey].do {|func, i| + func.(this, val); + } + } + + addFunc {|sensorKey, funcKey, func| + if(parent.sensorKeys.includes(sensorKey)) { + if(settings['sensorFuncs'].includesKey(sensorKey).not) { + settings['sensorFuncs'][sensorKey] = IdentityDictionary[]; + }; + + settings['sensorFuncs'][sensorKey][funcKey] = func; + } { + "parent doesn't have that sensor key".postln; + }; + } + + removeFunc {|sensorKey, funcKey| + settings['sensorFuncs'][sensorKey].removeAt(funcKey); + + if(settings['sensorFuncs'][sensorKey].isEmpty) { + settings['sensorFuncs'].removeAt(sensorKey); + }; + } + + availableControls { + ^parent.availableControls[settings['midiChannel']].copy; + } + + save { + Dialog.savePanel({|path| + settings.writeArchive(path); + }); + } + + play { + if(settings['patternTrack'] && settings['notes'].notEmpty) { + this.on(settings['notes'].choose); + }; + } +} diff --git a/samples/SuperCollider/WarpUtil.sc b/samples/SuperCollider/WarpUtil.sc new file mode 100644 index 00000000..2d5d8ff9 --- /dev/null +++ b/samples/SuperCollider/WarpUtil.sc @@ -0,0 +1,127 @@ +WarpUtil { + var <>parent; + var true) + expected.write Yajl.dump(serialized, :pretty => true) expected.close actual = Tempfile.new('actual.json') - actual.write Yajl::Encoder.encode(latest, :pretty => true) + actual.write Yajl.dump(latest, :pretty => true) actual.close expected.unlink diff --git a/vendor/cache/charlock_holmes-0.7.3.gem b/vendor/cache/charlock_holmes-0.7.3.gem new file mode 100644 index 00000000..f07f5cba Binary files /dev/null and b/vendor/cache/charlock_holmes-0.7.3.gem differ diff --git a/vendor/cache/coderay-1.1.0.gem b/vendor/cache/coderay-1.1.0.gem new file mode 100644 index 00000000..20f29116 Binary files /dev/null and b/vendor/cache/coderay-1.1.0.gem differ diff --git a/vendor/cache/escape_utils-1.0.1.gem b/vendor/cache/escape_utils-1.0.1.gem new file mode 100644 index 00000000..08021101 Binary files /dev/null and b/vendor/cache/escape_utils-1.0.1.gem differ diff --git a/vendor/cache/json-1.8.1.gem b/vendor/cache/json-1.8.1.gem new file mode 100644 index 00000000..d903086b Binary files /dev/null and b/vendor/cache/json-1.8.1.gem differ diff --git a/vendor/cache/metaclass-0.0.4.gem b/vendor/cache/metaclass-0.0.4.gem new file mode 100644 index 00000000..b32424b0 Binary files /dev/null and b/vendor/cache/metaclass-0.0.4.gem differ diff --git a/vendor/cache/method_source-0.8.2.gem b/vendor/cache/method_source-0.8.2.gem new file mode 100644 index 00000000..842453a3 Binary files /dev/null and b/vendor/cache/method_source-0.8.2.gem differ diff --git a/vendor/cache/mime-types-1.25.1.gem b/vendor/cache/mime-types-1.25.1.gem new file mode 100644 index 00000000..877d8a97 Binary files /dev/null and b/vendor/cache/mime-types-1.25.1.gem differ diff --git a/vendor/cache/mocha-1.1.0.gem b/vendor/cache/mocha-1.1.0.gem new file mode 100644 index 00000000..39128ca4 Binary files /dev/null and b/vendor/cache/mocha-1.1.0.gem differ diff --git a/vendor/cache/posix-spawn-0.3.9.gem b/vendor/cache/posix-spawn-0.3.9.gem new file mode 100644 index 00000000..ba4f19e9 Binary files /dev/null and b/vendor/cache/posix-spawn-0.3.9.gem differ diff --git a/vendor/cache/pry-0.10.1.gem b/vendor/cache/pry-0.10.1.gem new file mode 100644 index 00000000..25868753 Binary files /dev/null and b/vendor/cache/pry-0.10.1.gem differ diff --git a/vendor/cache/pygments.rb-0.6.0.gem b/vendor/cache/pygments.rb-0.6.0.gem new file mode 100644 index 00000000..7146f3d8 Binary files /dev/null and b/vendor/cache/pygments.rb-0.6.0.gem differ diff --git a/vendor/cache/rake-10.3.2.gem b/vendor/cache/rake-10.3.2.gem new file mode 100644 index 00000000..59f5fb63 Binary files /dev/null and b/vendor/cache/rake-10.3.2.gem differ diff --git a/vendor/cache/rugged-0.21.1b2.gem b/vendor/cache/rugged-0.21.1b2.gem new file mode 100644 index 00000000..1d5a7dc8 Binary files /dev/null and b/vendor/cache/rugged-0.21.1b2.gem differ diff --git a/vendor/cache/slop-3.6.0.gem b/vendor/cache/slop-3.6.0.gem new file mode 100644 index 00000000..153a673d Binary files /dev/null and b/vendor/cache/slop-3.6.0.gem differ diff --git a/vendor/cache/yajl-ruby-1.1.0.gem b/vendor/cache/yajl-ruby-1.1.0.gem new file mode 100644 index 00000000..3fcb580e Binary files /dev/null and b/vendor/cache/yajl-ruby-1.1.0.gem differ