ruby2d 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/assets/README.md +1 -0
- data/assets/opal.js +19532 -0
- data/assets/simple2d.js +1180 -0
- data/assets/template.html +18 -0
- data/bin/ruby2d +161 -46
- data/ext/ruby2d/extconf.rb +17 -8
- data/ext/ruby2d/ruby2d-opal.rb +219 -0
- data/ext/ruby2d/ruby2d.c +665 -154
- data/lib/ruby2d.rb +7 -4
- data/lib/ruby2d/application.rb +14 -2
- data/lib/ruby2d/color.rb +56 -33
- data/lib/ruby2d/dsl.rb +21 -12
- data/lib/ruby2d/exceptions.rb +2 -3
- data/lib/ruby2d/image.rb +22 -9
- data/lib/ruby2d/music.rb +17 -0
- data/lib/ruby2d/quad.rb +24 -15
- data/lib/ruby2d/rectangle.rb +2 -5
- data/lib/ruby2d/sound.rb +6 -9
- data/lib/ruby2d/sprite.rb +91 -0
- data/lib/ruby2d/square.rb +2 -5
- data/lib/ruby2d/text.rb +19 -23
- data/lib/ruby2d/triangle.rb +29 -15
- data/lib/ruby2d/version.rb +1 -1
- data/lib/ruby2d/window.rb +121 -67
- metadata +27 -7
@@ -0,0 +1,18 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Ruby 2D App</title>
|
6
|
+
<style>
|
7
|
+
body { background-color: #ccc }
|
8
|
+
canvas {
|
9
|
+
display: block;
|
10
|
+
margin: auto;
|
11
|
+
}
|
12
|
+
</style>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<div id="ruby2d-app"></div>
|
16
|
+
<script src="app.js"></script>
|
17
|
+
</body>
|
18
|
+
</html>
|
data/bin/ruby2d
CHANGED
@@ -1,48 +1,155 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'ruby2d/version'
|
3
|
+
require 'fileutils'
|
3
4
|
|
5
|
+
# Extending `String` to include some fancy colors
|
4
6
|
class String
|
5
7
|
def colorize(c); "\e[#{c}m#{self}\e[0m" end
|
6
|
-
def
|
7
|
-
def
|
8
|
+
def bold; colorize('1') end
|
9
|
+
def error; colorize('4;31') end
|
8
10
|
end
|
9
11
|
|
12
|
+
# The installed gem directory
|
13
|
+
@gem_dir = "#{Gem::Specification.find_by_name('ruby2d').gem_dir}"
|
10
14
|
|
15
|
+
# The Ruby 2D library files
|
16
|
+
@lib_files = [
|
17
|
+
'exceptions',
|
18
|
+
'color',
|
19
|
+
'window',
|
20
|
+
'application',
|
21
|
+
'dsl',
|
22
|
+
'quad',
|
23
|
+
'rectangle',
|
24
|
+
'square',
|
25
|
+
'triangle',
|
26
|
+
'image',
|
27
|
+
'sprite',
|
28
|
+
'text',
|
29
|
+
'sound',
|
30
|
+
'music'
|
31
|
+
]
|
32
|
+
|
33
|
+
|
34
|
+
# Check if source file provided is good
|
35
|
+
def check_build_src_file(rb_file)
|
36
|
+
if !rb_file
|
37
|
+
puts "Please provide a Ruby file to build."
|
38
|
+
exit
|
39
|
+
elsif !File.exists? rb_file
|
40
|
+
puts "Can't find file: #{rb_file}"
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Assemble the Ruby 2D library in one `.rb` file
|
47
|
+
def make_lib
|
48
|
+
FileUtils.mkdir_p 'build'
|
49
|
+
|
50
|
+
lib_dir = "#{@gem_dir}/lib/ruby2d/"
|
51
|
+
|
52
|
+
lib = ""
|
53
|
+
@lib_files.each do |f|
|
54
|
+
lib << File.read("#{lib_dir + f}.rb") + "\n\n"
|
55
|
+
end
|
56
|
+
|
57
|
+
lib << "
|
58
|
+
include Ruby2D::DSL
|
59
|
+
include Ruby2D\n"
|
60
|
+
|
61
|
+
File.write('build/lib.rb', lib)
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Remove `require 'ruby2d'` from source file
|
66
|
+
def strip_require(file)
|
67
|
+
output = ''
|
68
|
+
File.foreach(file) do |line|
|
69
|
+
output << line unless line =~ /require ('|")ruby2d('|")/
|
70
|
+
end
|
71
|
+
return output
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# Build a native version of the provided Ruby application
|
11
76
|
def build_native(rb_file)
|
77
|
+
|
78
|
+
# Check if MRuby exists; if not, quit
|
12
79
|
if `which mruby`.empty?
|
13
|
-
puts ""
|
14
|
-
" mruby not found!".error, "",
|
15
|
-
" mruby is needed to build a native Ruby 2D applications.".bold, "",
|
16
|
-
" Install using Homebrew on OS X:",
|
17
|
-
" brew install mruby", ""
|
80
|
+
puts "#{'Error:'.error} Can't find MRuby, which is needed to build native Ruby 2D applications.\n"
|
18
81
|
exit
|
19
82
|
end
|
20
83
|
|
21
|
-
`
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
int main(void) {
|
30
|
-
mrb_state *mrb = mrb_open();
|
31
|
-
if (!mrb) { /* handle error */ }
|
32
|
-
mrb_load_irep(mrb, ruby2d_app_symbol);
|
33
|
-
mrb_close(mrb);
|
34
|
-
}
|
35
|
-
)
|
84
|
+
# Assemble the Ruby 2D library in one `.rb` file and compile to bytecode
|
85
|
+
make_lib
|
86
|
+
`mrbc -Bruby2d_lib -obuild/lib.c build/lib.rb`
|
87
|
+
|
88
|
+
# Read the provided Ruby source file, copy to build dir and compile to bytecode
|
89
|
+
|
90
|
+
File.open('build/src.rb', 'w') do |file|
|
91
|
+
file << strip_require(rb_file)
|
36
92
|
end
|
37
93
|
|
38
|
-
`
|
94
|
+
`mrbc -Bruby2d_app -obuild/src.c build/src.rb`
|
95
|
+
|
96
|
+
# Combine contents of C source files and bytecode into one file
|
97
|
+
open('build/app.c', 'w') do |f|
|
98
|
+
f << "#define MRUBY 1" << "\n\n"
|
99
|
+
f << File.read("build/lib.c") << "\n\n"
|
100
|
+
f << File.read("build/src.c") << "\n\n"
|
101
|
+
f << File.read("#{@gem_dir}/ext/ruby2d/ruby2d.c")
|
102
|
+
end
|
103
|
+
|
104
|
+
# Compile to native executable
|
105
|
+
`cc build/app.c -lmruby \`simple2d --libs\` -o build/app`
|
106
|
+
|
107
|
+
# Success!
|
108
|
+
puts "Native app created at `build/app`"
|
39
109
|
end
|
40
110
|
|
41
111
|
|
112
|
+
# Build a web-based version of the provided Ruby application
|
113
|
+
def build_web(rb_file)
|
114
|
+
|
115
|
+
# Assemble the Ruby 2D library in one `.rb` file and compile to JS
|
116
|
+
make_lib
|
117
|
+
`opal --compile --no-opal build/lib.rb > build/lib.js`
|
118
|
+
|
119
|
+
# Read the provided Ruby source file, copy to build dir, and compile to JS
|
120
|
+
|
121
|
+
File.open('build/src.rb', 'w') do |file|
|
122
|
+
file << strip_require(rb_file)
|
123
|
+
end
|
124
|
+
|
125
|
+
`opal --compile --no-opal build/src.rb > build/src.js`
|
126
|
+
|
127
|
+
FileUtils.cp "#{@gem_dir}/ext/ruby2d/ruby2d-opal.rb", "build/"
|
128
|
+
`opal --compile --no-opal build/ruby2d-opal.rb > build/ruby2d-opal.js`
|
129
|
+
|
130
|
+
# Combine contents of JS source files and compiled JS into one file
|
131
|
+
open('build/app.js', 'w') do |f|
|
132
|
+
f << File.read("#{@gem_dir}/assets/simple2d.js") << "\n\n"
|
133
|
+
f << File.read("#{@gem_dir}/assets/opal.js") << "\n\n"
|
134
|
+
f << File.read("build/lib.js") << "\n\n"
|
135
|
+
f << File.read("build/ruby2d-opal.js") << "\n\n"
|
136
|
+
f << File.read("build/src.js") << "\n\n"
|
137
|
+
end
|
138
|
+
|
139
|
+
# Copy over HTML template
|
140
|
+
FileUtils.cp "#{@gem_dir}/assets/template.html", "build/app.html"
|
141
|
+
|
142
|
+
# Success!
|
143
|
+
puts "Web app created at `build/app.js`",
|
144
|
+
" Run by opening `build/app.html`"
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# Build an application package for the current platform
|
42
149
|
def build_package
|
43
150
|
require 'fileutils'
|
44
151
|
|
45
|
-
icon_path = "#{
|
152
|
+
icon_path = "#{@gem_dir}/assets/app.icns"
|
46
153
|
|
47
154
|
FileUtils.mkpath "build/App.app/Contents/MacOS"
|
48
155
|
FileUtils.mkpath "build/App.app/Contents/Resources"
|
@@ -70,40 +177,50 @@ def build_package
|
|
70
177
|
)
|
71
178
|
|
72
179
|
File.open("build/App.app/Contents/Info.plist", 'w') { |f| f.write(info_plist) }
|
73
|
-
|
74
180
|
FileUtils.cp "build/app", "build/App.app/Contents/MacOS/"
|
75
|
-
|
76
181
|
puts "App written to `build/App.app`."
|
77
182
|
end
|
78
183
|
|
79
184
|
|
80
|
-
#
|
185
|
+
# Clean up unneeded build files
|
186
|
+
def clean_up
|
187
|
+
FileUtils.rm(
|
188
|
+
Dir.glob('build/{src,lib}.{rb,c,js}') +
|
189
|
+
Dir.glob('build/ruby2d-opal.{rb,js}') +
|
190
|
+
Dir.glob('build/app.c')
|
191
|
+
)
|
192
|
+
end
|
81
193
|
|
82
|
-
usage = "
|
83
|
-
Usage: ruby2d [-v|--version]
|
84
|
-
<command> <options>
|
85
194
|
|
86
|
-
|
87
|
-
build Build the application...
|
88
|
-
native ...compile with mruby.
|
89
|
-
web ...for web platform.
|
90
|
-
package Create application package.
|
91
|
-
-v|--version Prints the installed version.
|
195
|
+
# Check Command-line Arguments #################################################
|
92
196
|
|
93
|
-
"
|
197
|
+
usage = "Ruby 2D: Make cross-platform 2D applications in Ruby".bold + "\n
|
198
|
+
Usage: ruby2d <command> <options>
|
199
|
+
[-v|--version]
|
200
|
+
|
201
|
+
Summary of commands and options:
|
202
|
+
build Build the application both natively and for the web
|
203
|
+
--native Build only native
|
204
|
+
--web Build only web
|
205
|
+
--debug Build native and web, keeping all intermediate files
|
206
|
+
package Create application package for distribution (experimental)
|
207
|
+
-v|--version Prints the installed version\n\n"
|
94
208
|
|
95
209
|
case ARGV[0]
|
96
210
|
when 'build'
|
97
|
-
puts "
|
211
|
+
puts "Building..."
|
98
212
|
case ARGV[1]
|
99
|
-
when 'native'
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
puts "Running build web..."
|
213
|
+
when '--native'
|
214
|
+
build_native(ARGV[2])
|
215
|
+
when '--web'
|
216
|
+
build_web(ARGV[2])
|
104
217
|
else
|
105
|
-
puts usage
|
218
|
+
if ARGV[2]; puts usage; exit end
|
219
|
+
check_build_src_file(ARGV[1])
|
220
|
+
build_native(ARGV[1])
|
221
|
+
build_web(ARGV[1])
|
106
222
|
end
|
223
|
+
unless ARGV.include? '--debug'; clean_up end
|
107
224
|
when 'package'
|
108
225
|
puts "Running package..."
|
109
226
|
build_package
|
@@ -112,5 +229,3 @@ when '-v', '--version'
|
|
112
229
|
else
|
113
230
|
puts usage
|
114
231
|
end
|
115
|
-
|
116
|
-
exit
|
data/ext/ruby2d/extconf.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
S2D_VERSION = '0.
|
3
|
+
S2D_VERSION = '0.5.1' # Simple 2D minimum version required
|
4
4
|
$errors = []
|
5
5
|
|
6
6
|
class String
|
7
7
|
def colorize(c); "\e[#{c}m#{self}\e[0m" end
|
8
|
-
def bold; colorize('1')
|
9
|
-
def red;
|
8
|
+
def bold; colorize('1') end
|
9
|
+
def red; colorize('1;31') end
|
10
10
|
end
|
11
11
|
|
12
12
|
def print_errors
|
@@ -69,15 +69,24 @@ elsif RUBY_PLATFORM =~ /linux/
|
|
69
69
|
exit
|
70
70
|
end
|
71
71
|
|
72
|
-
$CFLAGS << ' -std=
|
72
|
+
$CFLAGS << ' -std=c11'
|
73
|
+
|
74
|
+
# Windows / MinGW
|
75
|
+
elsif RUBY_PLATFORM =~ /mingw/
|
76
|
+
# Add flags
|
77
|
+
$CFLAGS << ' -std=c11 -I/usr/local/include'
|
78
|
+
$LDFLAGS << ' -Dmain=SDL_main -L/usr/local/lib -lmingw32 -lsimple2d -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lopengl32 -lglew32 -mwindows'
|
73
79
|
end
|
74
80
|
|
75
|
-
|
76
|
-
|
81
|
+
unless RUBY_PLATFORM =~ /mingw/
|
82
|
+
# Simple 2D installed, check version
|
83
|
+
check_s2d_version
|
84
|
+
|
85
|
+
# Add flags
|
86
|
+
$LDFLAGS << ' ' << `simple2d --libs`
|
87
|
+
end
|
77
88
|
|
78
|
-
# Configure Simple 2D and create Makefile
|
79
89
|
|
80
|
-
$LDFLAGS << ' ' << `simple2d --libs`
|
81
90
|
$LDFLAGS.gsub!(/\n/, ' ') # Remove newlines in flags, they cause problems
|
82
91
|
|
83
92
|
create_makefile('ruby2d/ruby2d')
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# ruby2d-opal.rb
|
2
|
+
|
3
|
+
# Ruby 2D window
|
4
|
+
$R2D_WINDOW = nil
|
5
|
+
|
6
|
+
# Simple 2D window
|
7
|
+
`var win;`
|
8
|
+
|
9
|
+
|
10
|
+
`// ruby2d.js
|
11
|
+
|
12
|
+
// @type_id values for rendering
|
13
|
+
const $R2D_TRIANGLE = 1;
|
14
|
+
const $R2D_QUAD = 2;
|
15
|
+
const $R2D_IMAGE = 3;
|
16
|
+
const $R2D_SPRITE = 4;
|
17
|
+
const $R2D_TEXT = 5;
|
18
|
+
|
19
|
+
|
20
|
+
function on_key(e, key) {
|
21
|
+
switch (e) {
|
22
|
+
case S2D.KEYDOWN:
|
23
|
+
#{$R2D_WINDOW.key_down_callback(`key`)};
|
24
|
+
break;
|
25
|
+
|
26
|
+
case S2D.KEY:
|
27
|
+
#{$R2D_WINDOW.key_callback(`key`)};
|
28
|
+
break;
|
29
|
+
|
30
|
+
case S2D.KEYUP:
|
31
|
+
#{$R2D_WINDOW.key_up_callback(`key`)};
|
32
|
+
break;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
function on_mouse(x, y) {
|
38
|
+
#{$R2D_WINDOW.mouse_callback("any", `x`, `y`)};
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
function update() {
|
43
|
+
#{$R2D_WINDOW.mouse_x = `win.mouse.x`};
|
44
|
+
#{$R2D_WINDOW.mouse_y = `win.mouse.y`};
|
45
|
+
#{$R2D_WINDOW.frames = `win.frames`};
|
46
|
+
#{$R2D_WINDOW.fps = `win.fps`};
|
47
|
+
#{$R2D_WINDOW.update_callback};
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
function render() {
|
52
|
+
|
53
|
+
// Set background color
|
54
|
+
win.background.r = #{$R2D_WINDOW.get(:background).r};
|
55
|
+
win.background.g = #{$R2D_WINDOW.get(:background).g};
|
56
|
+
win.background.b = #{$R2D_WINDOW.get(:background).b};
|
57
|
+
win.background.a = #{$R2D_WINDOW.get(:background).a};
|
58
|
+
|
59
|
+
var objects = #{$R2D_WINDOW.objects};
|
60
|
+
|
61
|
+
for (var i = 0; i < objects.length; i++) {
|
62
|
+
|
63
|
+
var el = objects[i];
|
64
|
+
|
65
|
+
switch (el.type_id) {
|
66
|
+
|
67
|
+
case $R2D_TRIANGLE:
|
68
|
+
|
69
|
+
S2D.DrawTriangle(
|
70
|
+
el.x1, el.y1, el.c1.r, el.c1.g, el.c1.b, el.c1.a,
|
71
|
+
el.x2, el.y2, el.c2.r, el.c2.g, el.c2.b, el.c2.a,
|
72
|
+
el.x3, el.y3, el.c3.r, el.c3.g, el.c3.b, el.c3.a
|
73
|
+
);
|
74
|
+
break;
|
75
|
+
|
76
|
+
case $R2D_QUAD:
|
77
|
+
S2D.DrawQuad(
|
78
|
+
el.x1, el.y1, el.c1.r, el.c1.g, el.c1.b, el.c1.a,
|
79
|
+
el.x2, el.y2, el.c2.r, el.c2.g, el.c2.b, el.c2.a,
|
80
|
+
el.x3, el.y3, el.c3.r, el.c3.g, el.c3.b, el.c3.a,
|
81
|
+
el.x4, el.y4, el.c4.r, el.c4.g, el.c4.b, el.c4.a
|
82
|
+
);
|
83
|
+
break;
|
84
|
+
|
85
|
+
case $R2D_IMAGE:
|
86
|
+
el.data.x = el.x;
|
87
|
+
el.data.y = el.y;
|
88
|
+
|
89
|
+
if (el.width != Opal.nil) el.data.width = el.width;
|
90
|
+
if (el.height != Opal.nil) el.data.height = el.height;
|
91
|
+
|
92
|
+
el.data.color.r = el.color.r;
|
93
|
+
el.data.color.g = el.color.g;
|
94
|
+
el.data.color.b = el.color.b;
|
95
|
+
el.data.color.a = el.color.a;
|
96
|
+
|
97
|
+
S2D.DrawImage(el.data);
|
98
|
+
break;
|
99
|
+
|
100
|
+
case $R2D_SPRITE:
|
101
|
+
el.data.x = el.x;
|
102
|
+
el.data.y = el.y;
|
103
|
+
|
104
|
+
S2D.ClipSprite(
|
105
|
+
el.data,
|
106
|
+
el.clip_x,
|
107
|
+
el.clip_y,
|
108
|
+
el.clip_w,
|
109
|
+
el.clip_h
|
110
|
+
);
|
111
|
+
|
112
|
+
S2D.DrawSprite(el.data);
|
113
|
+
break;
|
114
|
+
|
115
|
+
case $R2D_TEXT:
|
116
|
+
el.data.x = el.x;
|
117
|
+
el.data.y = el.y;
|
118
|
+
|
119
|
+
el.data.color.r = el.color.r;
|
120
|
+
el.data.color.g = el.color.g;
|
121
|
+
el.data.color.b = el.color.b;
|
122
|
+
el.data.color.a = el.color.a;
|
123
|
+
|
124
|
+
S2D.DrawText(el.data);
|
125
|
+
break;
|
126
|
+
}
|
127
|
+
|
128
|
+
}
|
129
|
+
}`
|
130
|
+
|
131
|
+
|
132
|
+
module Ruby2D
|
133
|
+
|
134
|
+
class Image
|
135
|
+
def init(path)
|
136
|
+
`#{self}.data = S2D.CreateImage(path);`
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class Sprite
|
141
|
+
def init(path)
|
142
|
+
`#{self}.data = S2D.CreateSprite(path);`
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class Text
|
147
|
+
def init
|
148
|
+
`#{self}.data = S2D.CreateText(#{self}.font, #{self}.text, #{self}.size);`
|
149
|
+
end
|
150
|
+
|
151
|
+
def text=(t)
|
152
|
+
@text = t
|
153
|
+
`S2D.SetText(#{self}.data, #{self}.text);`
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class Sound
|
158
|
+
def init(path)
|
159
|
+
`#{self}.data = S2D.CreateSound(path);`
|
160
|
+
end
|
161
|
+
|
162
|
+
def play
|
163
|
+
`S2D.PlaySound(#{self}.data);`
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Music
|
168
|
+
def init(path)
|
169
|
+
`#{self}.data = S2D.CreateMusic(path);`
|
170
|
+
end
|
171
|
+
|
172
|
+
def play
|
173
|
+
`S2D.PlayMusic(#{self}.data, #{self}.loop);`
|
174
|
+
end
|
175
|
+
|
176
|
+
def pause
|
177
|
+
`S2D.PauseMusic();`
|
178
|
+
end
|
179
|
+
|
180
|
+
def resume
|
181
|
+
`S2D.ResumeMusic();`
|
182
|
+
end
|
183
|
+
|
184
|
+
def stop
|
185
|
+
`S2D.StopMusic();`
|
186
|
+
end
|
187
|
+
|
188
|
+
def fadeout(ms)
|
189
|
+
`S2D.FadeOutMusic(ms);`
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class Window
|
194
|
+
def show
|
195
|
+
$R2D_WINDOW = self
|
196
|
+
|
197
|
+
`
|
198
|
+
var width = #{$R2D_WINDOW.get(:width)};
|
199
|
+
var height = #{$R2D_WINDOW.get(:height)};
|
200
|
+
|
201
|
+
var vp_w = #{$R2D_WINDOW.get(:viewport_width)};
|
202
|
+
var viewport_width = vp_w != Opal.nil ? vp_w : width;
|
203
|
+
|
204
|
+
var vp_h = #{$R2D_WINDOW.get(:viewport_height)};
|
205
|
+
var viewport_height = vp_h != Opal.nil ? vp_h : height;
|
206
|
+
|
207
|
+
win = S2D.CreateWindow(
|
208
|
+
#{$R2D_WINDOW.get(:title)}, width, height, update, render, "ruby2d-app", {}
|
209
|
+
);
|
210
|
+
|
211
|
+
win.viewport.width = viewport_width;
|
212
|
+
win.viewport.height = viewport_height;
|
213
|
+
win.on_key = on_key;
|
214
|
+
win.on_mouse = on_mouse;
|
215
|
+
|
216
|
+
S2D.Show(win);`
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|