burn 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +56 -569
- data/lib/burn.rb +5 -3
- data/lib/burn/cli.rb +160 -199
- data/lib/burn/config.rb +4 -0
- data/lib/burn/config/app.rb +15 -0
- data/lib/burn/config/config_base.rb +16 -0
- data/lib/burn/config/loader.rb +23 -0
- data/lib/burn/config/server.rb +11 -0
- data/lib/burn/fuel.rb +11 -0
- data/lib/burn/{dsl → fuel}/dsl_base.rb +1 -1
- data/lib/burn/fuel/rom/channel_stream.rb +106 -0
- data/lib/burn/fuel/rom/declare.rb +43 -0
- data/lib/burn/fuel/rom/music.rb +37 -0
- data/lib/burn/fuel/rom/note.rb +126 -0
- data/lib/burn/fuel/rom/scene.rb +279 -0
- data/lib/burn/fuel/rom/sound.rb +31 -0
- data/lib/burn/fuel/rom/sound_effect.rb +92 -0
- data/lib/burn/fuel/telnet/declare.rb +26 -0
- data/lib/burn/fuel/telnet/scene.rb +112 -0
- data/lib/burn/generator.rb +10 -3
- data/lib/burn/generator/rom/assembly_music.rb +49 -0
- data/lib/burn/generator/rom/assembly_sound_effect.rb +35 -0
- data/lib/burn/generator/rom/c_source.rb +55 -0
- data/lib/burn/generator/{template → rom/template}/mus_template.s +0 -0
- data/lib/burn/generator/{template → rom/template}/template.c +0 -0
- data/lib/burn/generator/rom_builder.rb +67 -0
- data/lib/burn/generator/telnet/jit_compiler.rb +41 -0
- data/lib/burn/generator/telnet/screen.rb +86 -0
- data/lib/burn/generator/telnet/sprite.rb +16 -0
- data/lib/burn/generator/telnet/user_input.rb +25 -0
- data/lib/burn/generator/telnet_vm.rb +50 -0
- data/lib/burn/pxes.rb +3 -0
- data/lib/burn/{util/pxes.rb → pxes/cc65_transpiler.rb} +8 -14
- data/lib/burn/pxes/cruby_transpiler.rb +189 -0
- data/lib/burn/pxes/transpiler_base.rb +14 -0
- data/lib/burn/server.rb +2 -0
- data/lib/burn/server/rom.rb +24 -0
- data/lib/burn/server/telnet.rb +120 -0
- data/lib/burn/util.rb +1 -2
- data/lib/burn/util/logo.rb +68 -0
- data/lib/burn/util/os.rb +1 -1
- data/lib/burn/version.rb +1 -1
- metadata +53 -19
- data/lib/burn/builder.rb +0 -65
- data/lib/burn/dsl.rb +0 -8
- data/lib/burn/dsl/channel_stream.rb +0 -105
- data/lib/burn/dsl/declare.rb +0 -42
- data/lib/burn/dsl/music.rb +0 -36
- data/lib/burn/dsl/note.rb +0 -125
- data/lib/burn/dsl/scene.rb +0 -278
- data/lib/burn/dsl/sound.rb +0 -30
- data/lib/burn/dsl/sound_effect.rb +0 -91
- data/lib/burn/generator/assembly_music.rb +0 -47
- data/lib/burn/generator/assembly_sound_effect.rb +0 -33
- data/lib/burn/generator/c_source.rb +0 -54
- data/lib/burn/util/server.rb +0 -21
@@ -0,0 +1,41 @@
|
|
1
|
+
module Burn
|
2
|
+
module Generator
|
3
|
+
module Telnet
|
4
|
+
class JitCompiler
|
5
|
+
include Fuel::Telnet
|
6
|
+
include Debug
|
7
|
+
attr_reader :opcodes
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@opcodes = Array.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_context
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def compile(source)
|
18
|
+
instance_eval source
|
19
|
+
@opcodes
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(method_symbol, *args, &block)
|
23
|
+
log :method_symbol=>method_symbol, :args=>args, :block=>block
|
24
|
+
if method_symbol == :scene then
|
25
|
+
# preprocess
|
26
|
+
args[0] = "main" if args[0].nil?
|
27
|
+
|
28
|
+
# execute dsls
|
29
|
+
@opcodes << "##{args[0]}"
|
30
|
+
Scene.new(args[0], self).instance_eval(&block)
|
31
|
+
@opcodes << "#END"
|
32
|
+
|
33
|
+
elsif method_symbol == :declare then
|
34
|
+
Declare.new(args[0], self).instance_eval(&block)
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Burn
|
2
|
+
module Generator
|
3
|
+
module Telnet
|
4
|
+
class Screen
|
5
|
+
include Debug
|
6
|
+
ESC = 27.chr # equal to "\033"
|
7
|
+
CLEARSCREEN = ESC + "[2J"
|
8
|
+
JUMPTOHOME = ESC + "[H"
|
9
|
+
RESETALLATTR = ESC + "[0m"
|
10
|
+
CRLF = 13.chr + 10.chr
|
11
|
+
|
12
|
+
attr_accessor :display, :fg_color, :bg_color, :activated_sprite_objects
|
13
|
+
|
14
|
+
def initialize(conf)
|
15
|
+
@fg_color = 37
|
16
|
+
@bg_color = 40
|
17
|
+
@activated_sprite_objects = [] # activated sprite objects by #sprite method call during main_loop will be contained
|
18
|
+
@conf = conf
|
19
|
+
flush_screen
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_terminal
|
23
|
+
#CLEARSCREEN + escape_color(@fg_color) + escape_color(@bg_color) + @display.join("\r\n") + JUMPTOHOME + RESETALLATTR
|
24
|
+
#JUMPTOHOME + RESETALLATTR + CLEARSCREEN + escape_color(@fg_color) + escape_color(@bg_color) + @display.join("\r\n") + ESC + "[#{@conf.app.height};2H" + RESETALLATTR
|
25
|
+
#CLEARSCREEN + escape_color(@fg_color) + escape_color(@bg_color) + @display.join("\r\n") + ESC + "[#{@conf.app.height};2H" + RESETALLATTR
|
26
|
+
#JUMPTOHOME + crlf + crlf + crlf + crlf + crlf + crlf + @display.join(crlf)
|
27
|
+
#JUMPTOHOME + crlf + crlf + crlf + crlf + crlf + crlf + @display.join(crlf) + crlf
|
28
|
+
#JUMPTOHOME + @display.join(CRLF) + CRLF
|
29
|
+
|
30
|
+
JUMPTOHOME + escape_color(@fg_color) + escape_color(@bg_color) + ppu_emulate + CRLF + RESETALLATTR
|
31
|
+
#JUMPTOHOME + @display.join(CRLF) + CRLF
|
32
|
+
end
|
33
|
+
|
34
|
+
def flush_screen
|
35
|
+
@display = Array.new
|
36
|
+
@conf.app.height.times{ @display << Array.new(@conf.app.width){' '}.join }
|
37
|
+
@activated_sprite_objects = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_pressed(key, user_input)
|
41
|
+
log " ** program is waiting for:" + key.to_s
|
42
|
+
if !user_input.nil? then
|
43
|
+
log " **** confiremd user input:" + user_input.class.to_s, user_input.chr, user_input.to_s
|
44
|
+
if [*'0'..'9', *'a'..'z', *'A'..'Z'].include?(user_input.chr) && key.to_s == user_input.chr then
|
45
|
+
log "****** is_pressed() returned true"
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def escape_color(num)
|
55
|
+
ESC + "[" + num.to_s + ";1m"
|
56
|
+
end
|
57
|
+
|
58
|
+
def ppu_emulate
|
59
|
+
if @activated_sprite_objects.count == 0 then
|
60
|
+
@display.join(CRLF)
|
61
|
+
else
|
62
|
+
canvas = @display.map(&:dup) # deep copy
|
63
|
+
@activated_sprite_objects.each do |obj|
|
64
|
+
obj.tile.split("\n").each_with_index do |line, i|
|
65
|
+
canvas[(obj.y+ i) % @conf.app.height][obj.x % @conf.app.width,line.length] = line.chomp
|
66
|
+
end
|
67
|
+
|
68
|
+
# struct_var = "static sprite_schema #{key}={0, 0, {"
|
69
|
+
# @pattern_table_index[key.to_sym] = @pattern_table_pointer
|
70
|
+
# patternizer.patterns.each_with_index do |p, i|
|
71
|
+
# log p, i, patternizer.height, "aaaaaaaaaaaaaaaaaaa"
|
72
|
+
# struct_var += sprintf("%d, %d, %#x, 0,", (i % patternizer.width)*8 , (i / (patternizer.patterns.size / patternizer.height) )*8 , @pattern_table_pointer)
|
73
|
+
# @pattern_tables << p
|
74
|
+
# @pattern_table_pointer+=1
|
75
|
+
# end
|
76
|
+
# struct_var += "128}};"
|
77
|
+
|
78
|
+
end
|
79
|
+
canvas.join(CRLF)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Burn
|
2
|
+
module Generator
|
3
|
+
module Telnet
|
4
|
+
class UserInput
|
5
|
+
attr_reader :val
|
6
|
+
|
7
|
+
def initialize(conf)
|
8
|
+
@conf = conf
|
9
|
+
@signal = nil
|
10
|
+
@val = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_signal(signal)
|
14
|
+
@signal = signal if @conf.app.user_input ==:enable
|
15
|
+
end
|
16
|
+
|
17
|
+
def init_for_next_loop
|
18
|
+
@val = @signal
|
19
|
+
@signal = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Burn
|
2
|
+
module Generator
|
3
|
+
class TelnetVm
|
4
|
+
include Generator::Telnet
|
5
|
+
include Debug
|
6
|
+
attr_reader :screen
|
7
|
+
attr_accessor :wait
|
8
|
+
|
9
|
+
def initialize(source, conf)
|
10
|
+
@pc = 0 # Program Counter
|
11
|
+
@screen = Screen.new(conf)
|
12
|
+
@wait = 10
|
13
|
+
@opcodes = JitCompiler.new.compile(source) # compiled methods
|
14
|
+
log @opcodes.join(":::")
|
15
|
+
@user_input = UserInput.new(conf)
|
16
|
+
@conf = conf
|
17
|
+
@finish = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def next_frame
|
21
|
+
log @pc
|
22
|
+
if @wait > 0 then
|
23
|
+
@wait = @wait - 1
|
24
|
+
elsif !@finish then
|
25
|
+
log @user_input
|
26
|
+
if @opcodes[@pc] != "#END" && (@opcodes.count-1) > @pc then
|
27
|
+
@pc = @pc+1
|
28
|
+
# skipping comment out to speed up
|
29
|
+
while @opcodes[@pc-1][0] == '#' do
|
30
|
+
@pc = @pc+1
|
31
|
+
end
|
32
|
+
log @opcodes[@pc-1]
|
33
|
+
self.instance_eval @opcodes[@pc-1]
|
34
|
+
else
|
35
|
+
log "Program counter reached at the end of program. #END"
|
36
|
+
@finish = true
|
37
|
+
end
|
38
|
+
else # if @finish == true then
|
39
|
+
# do nothing
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def interrupt(signal)
|
44
|
+
log "INTTERUPT_SETTING:" + @conf.app.user_input.to_s
|
45
|
+
@user_input.receive_signal(signal)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/burn/pxes.rb
ADDED
@@ -1,14 +1,6 @@
|
|
1
1
|
module Burn
|
2
|
-
module
|
3
|
-
class
|
4
|
-
include Debug
|
5
|
-
attr_reader :sexp
|
6
|
-
|
7
|
-
def initialize(sexp, context=nil, resource_name=nil)
|
8
|
-
@sexp = sexp
|
9
|
-
@context = context || self
|
10
|
-
@resource_name = resource_name
|
11
|
-
end
|
2
|
+
module Pxes
|
3
|
+
class Cc65Transpiler < TranspilerBase
|
12
4
|
|
13
5
|
def to_c
|
14
6
|
parse_sexp(@sexp)
|
@@ -27,9 +19,10 @@ module Burn
|
|
27
19
|
# end
|
28
20
|
#end
|
29
21
|
|
22
|
+
|
30
23
|
def invoke_dsl_processing(exp)
|
31
|
-
generator = Generator::CSource.new(self)
|
32
|
-
|
24
|
+
generator = Generator::Rom::CSource.new(self)
|
25
|
+
Fuel::Rom::Scene.new(@resource_name, generator).instance_eval exp
|
33
26
|
# return the result
|
34
27
|
@context.instance_exec(generator.global) do |generator_global|
|
35
28
|
@global.concat generator_global
|
@@ -100,14 +93,14 @@ module Burn
|
|
100
93
|
|
101
94
|
# this is why you can't use pre-defined dsl name as a variable name. e.g) you are not allowed to declare variables like show or label or stop. these all are defined dsl.
|
102
95
|
when :vcall
|
103
|
-
if !
|
96
|
+
if !Fuel::Rom::Scene.new(@resource_name,self).methods.index(s[1][1].to_sym).nil? then
|
104
97
|
invoke_dsl_processing parse_sexp(s[1])
|
105
98
|
else
|
106
99
|
parse_sexp(s[1])
|
107
100
|
end
|
108
101
|
|
109
102
|
when :command
|
110
|
-
if !
|
103
|
+
if !Fuel::Rom::Scene.new(@resource_name,self).methods.index(s[1][1].to_sym).nil? then
|
111
104
|
#invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( replace_vcall_to_symbol(s[2]) ) + ")"
|
112
105
|
invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( s[2] ) + ")"
|
113
106
|
else
|
@@ -175,6 +168,7 @@ module Burn
|
|
175
168
|
log s[0].class.to_s
|
176
169
|
end
|
177
170
|
end
|
171
|
+
|
178
172
|
end
|
179
173
|
end
|
180
174
|
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Burn
|
2
|
+
module Pxes
|
3
|
+
class CrubyTranspiler < TranspilerBase
|
4
|
+
|
5
|
+
def to_rb
|
6
|
+
parse_sexp(@sexp)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
#def replace_vcall_to_symbol(sexp_array)
|
11
|
+
# sexp_array.map do |a|
|
12
|
+
# if a.instance_of?(Array) then
|
13
|
+
# replace_vcall_to_symbol(a)
|
14
|
+
# elsif a==:vcall then
|
15
|
+
# :symbol
|
16
|
+
# else
|
17
|
+
# a
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#end
|
21
|
+
|
22
|
+
def invoke_dsl_processing(exp)
|
23
|
+
generator = Generator::Telnet::JitCompiler.new
|
24
|
+
# class(@@)|instance(@) variable inside exp need to be stringified before the #instance_eval.
|
25
|
+
# Without this, variables will be evaluated immediately now (and will get disappered as a result of this) by #instance_eval
|
26
|
+
Fuel::Telnet::Scene.new(@resource_name, generator).instance_eval exp.gsub(/(@[@\w]*)/, "\"\\1\"")
|
27
|
+
generator.opcodes.join "\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse_sexp(s)
|
31
|
+
if s.instance_of?(String) then
|
32
|
+
s
|
33
|
+
elsif s.instance_of?(Array) && s[0].instance_of?(Symbol) then
|
34
|
+
log "--array and symbol--"
|
35
|
+
log s[0]
|
36
|
+
case s[0]
|
37
|
+
when :assign
|
38
|
+
parse_sexp(s[1]) + "=" + parse_sexp(s[2])
|
39
|
+
|
40
|
+
when :var_field, :var_ref
|
41
|
+
if s[1][0] == :@ident then
|
42
|
+
var_scope = "@___"
|
43
|
+
else
|
44
|
+
var_scope = ""
|
45
|
+
end
|
46
|
+
var_scope + s[1][1]
|
47
|
+
|
48
|
+
when :void_stmt
|
49
|
+
"" # this happens when rip "if true then # do nothing end" type of code
|
50
|
+
|
51
|
+
when :binary
|
52
|
+
case s[2]
|
53
|
+
when :or
|
54
|
+
operator = "||"
|
55
|
+
when :and
|
56
|
+
operator = "&&"
|
57
|
+
else
|
58
|
+
operator = s[2].to_s
|
59
|
+
end
|
60
|
+
parse_sexp(s[1]) + operator + parse_sexp(s[3])
|
61
|
+
|
62
|
+
when :opassign
|
63
|
+
parse_sexp(s[1]) + parse_sexp(s[2]) + parse_sexp(s[3])
|
64
|
+
|
65
|
+
when :unary
|
66
|
+
case s[1]
|
67
|
+
when :not, :!
|
68
|
+
"!" + parse_sexp(s[2])
|
69
|
+
else
|
70
|
+
parse_sexp(s[2])
|
71
|
+
end
|
72
|
+
|
73
|
+
when :paren
|
74
|
+
"(" + parse_sexp(s[1][0]) + ")"
|
75
|
+
|
76
|
+
when :symbol
|
77
|
+
':' + s[1][1]
|
78
|
+
|
79
|
+
when :field, :call
|
80
|
+
parse_sexp(s[1]) + "." + parse_sexp(s[3])
|
81
|
+
|
82
|
+
when :@ident, :@int, :@kw, :@op
|
83
|
+
s[1]
|
84
|
+
|
85
|
+
when :@tstring_content
|
86
|
+
'"' + s[1] + '"'
|
87
|
+
|
88
|
+
# this is why you can't use pre-defined dsl name as a variable name. e.g) you are not allowed to declare variables like show or label or stop. these all are defined dsl.
|
89
|
+
when :vcall
|
90
|
+
if s[1][0] == :@ident then
|
91
|
+
var_scope = "@___"
|
92
|
+
else
|
93
|
+
var_scope = ""
|
94
|
+
end
|
95
|
+
s[1][1] = var_scope + s[1][1]
|
96
|
+
parse_sexp(s[1])
|
97
|
+
|
98
|
+
# this is why you can't use pre-defined dsl name as a variable name. e.g) you are not allowed to declare variables like show or label or stop. these all are defined dsl.
|
99
|
+
when :command
|
100
|
+
if !Fuel::Telnet::Scene.new(@resource_name,@context).methods.index(s[1][1].to_sym).nil? then
|
101
|
+
#invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( replace_vcall_to_symbol(s[2]) ) + ")"
|
102
|
+
invoke_dsl_processing parse_sexp(s[1]) + "(" + parse_sexp( s[2] ) + ")"
|
103
|
+
else
|
104
|
+
parse_sexp(s[1]) + "(" + parse_sexp(s[2]) + ")"
|
105
|
+
end
|
106
|
+
|
107
|
+
when :method_add_arg
|
108
|
+
command = s[1][1][1]
|
109
|
+
# check if it matches dsl.
|
110
|
+
case command
|
111
|
+
when "is_pressed"
|
112
|
+
"@screen.is_pressed(" + parse_sexp(s[2]) + ", @user_input.val)"
|
113
|
+
#when "rand"
|
114
|
+
# parse_sexp(s[1]) + "8()"
|
115
|
+
else
|
116
|
+
parse_sexp(s[1]) + "(" + parse_sexp(s[2]) + ")"
|
117
|
+
end
|
118
|
+
|
119
|
+
# Currently pssing block is not supported
|
120
|
+
#when :method_add_block
|
121
|
+
|
122
|
+
when :args_add_block
|
123
|
+
a = Array.new
|
124
|
+
s[1].each_with_index do |sexp,i|
|
125
|
+
log "<<<<<<<<<<<<<<<<<<NUM #{i}>>>>>>"
|
126
|
+
log sexp
|
127
|
+
a << parse_sexp(sexp)
|
128
|
+
end
|
129
|
+
a.join(",")
|
130
|
+
|
131
|
+
when :while
|
132
|
+
"while(" + parse_sexp(s[1]) + "){" + parse_sexp(s[2]) + "}"
|
133
|
+
|
134
|
+
when :if, :if_mod, :elsif
|
135
|
+
if s[0]==:elsif then
|
136
|
+
keyword = "else if"
|
137
|
+
else
|
138
|
+
keyword = "if"
|
139
|
+
end
|
140
|
+
additional_condition = parse_sexp(s[3]) if !s[3].nil?
|
141
|
+
#"#{keyword} (" + parse_sexp(s[1]) + "){" + parse_sexp(s[2]) + "} #{additional_condition}"
|
142
|
+
label = "##{@resource_name}-" + [*0-9, *'a'..'z', *'A'..'Z'].sample(10).join
|
143
|
+
#"@pc = @opcodes.index(\"#{label}\") if !(" + parse_sexp(s[1]) + ")\n" + parse_sexp(s[2]) + "\n#{label}"
|
144
|
+
if additional_condition then
|
145
|
+
# jump to else
|
146
|
+
# + script for if clause
|
147
|
+
# jump to end
|
148
|
+
# label for else
|
149
|
+
# + script for else
|
150
|
+
# label for end
|
151
|
+
"@pc = @opcodes.index(\"#{label}\") if !(" + parse_sexp(s[1]) + ")\n" \
|
152
|
+
+ parse_sexp(s[2]) + "\n" \
|
153
|
+
+ "@pc = @opcodes.index(\"#{label}-else\")\n" \
|
154
|
+
+ "#{label}\n" \
|
155
|
+
+ additional_condition + "\n" \
|
156
|
+
+ "#{label}-else"
|
157
|
+
else
|
158
|
+
"@pc = @opcodes.index(\"#{label}\") if !(" + parse_sexp(s[1]) + ")\n" + parse_sexp(s[2]) + "\n#{label}"
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
#when :def
|
163
|
+
# is not supported for to_c as return data type cannot be defined
|
164
|
+
|
165
|
+
when :else
|
166
|
+
parse_sexp(s[1])
|
167
|
+
|
168
|
+
else
|
169
|
+
parse_sexp(s[1])
|
170
|
+
|
171
|
+
end
|
172
|
+
# Safety net
|
173
|
+
elsif s.instance_of?(Array) && s[0].instance_of?(Array) then
|
174
|
+
a = Array.new
|
175
|
+
s.each_with_index do |sexp,i|
|
176
|
+
log "<<<<<<<<<<<<<<<<<<NUM #{i}>>>>>>"
|
177
|
+
log sexp
|
178
|
+
a << parse_sexp(sexp)
|
179
|
+
end
|
180
|
+
a.join("\n")
|
181
|
+
else
|
182
|
+
log "--else--"
|
183
|
+
log s.class.to_s
|
184
|
+
log s[0].class.to_s
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|