summaryrefslogtreecommitdiffhomepage
path: root/samples/07_advanced_rendering
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2021-08-07 00:13:33 -0500
committerAmir Rajan <[email protected]>2021-08-07 00:13:33 -0500
commita503afe87619ff82201c0a43818fa1c3f070a548 (patch)
tree0b228a6456d17f6d0c6ea54c9ecd6a045ddbdf59 /samples/07_advanced_rendering
parentbea150381f495630f92f89d23d5f3445ec289b2d (diff)
downloaddragonruby-game-toolkit-contrib-a503afe87619ff82201c0a43818fa1c3f070a548.tar.gz
dragonruby-game-toolkit-contrib-a503afe87619ff82201c0a43818fa1c3f070a548.zip
Samples folder synced.
Diffstat (limited to 'samples/07_advanced_rendering')
-rw-r--r--samples/07_advanced_rendering/02_render_targets_with_alphas/app/main.rb95
-rw-r--r--samples/07_advanced_rendering/02_render_targets_with_alphas/license-for-sample.txt9
-rw-r--r--samples/07_advanced_rendering/03_render_target_viewports/app/main.rb35
-rw-r--r--samples/07_advanced_rendering/04_render_primitive_hierarchies/app/main.rb2
-rw-r--r--samples/07_advanced_rendering/05_render_primitives_as_hash/app/main.rb15
-rw-r--r--samples/07_advanced_rendering/07_simple_camera/app/main.rb93
-rw-r--r--samples/07_advanced_rendering/07_simple_camera/replay.txt232
-rw-r--r--samples/07_advanced_rendering/07_splitscreen_camera/run.bat6
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/app/main.rb (renamed from samples/07_advanced_rendering/07_splitscreen_camera/app/main.rb)0
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/replay.txt226
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_down_standing.png (renamed from samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_down_standing.png)bin186 -> 186 bytes
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_left_standing.png (renamed from samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_left_standing.png)bin173 -> 173 bytes
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_right_standing.png (renamed from samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_right_standing.png)bin170 -> 170 bytes
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_up_standing.png (renamed from samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_up_standing.png)bin165 -> 165 bytes
-rw-r--r--samples/07_advanced_rendering/08_splitscreen_camera/sprites/rooms/camera_room.png (renamed from samples/07_advanced_rendering/07_splitscreen_camera/sprites/rooms/camera_room.png)bin2469 -> 2469 bytes
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/app/main.rb (renamed from samples/07_advanced_rendering/08_z_targeting_camera/app/main.rb)0
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/metadata/game_metadata.txt (renamed from samples/07_advanced_rendering/08_z_targeting_camera/metadata/game_metadata.txt)0
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/metadata/icon.png (renamed from samples/07_advanced_rendering/08_z_targeting_camera/metadata/icon.png)bin14417 -> 14417 bytes
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/replay.txt185
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/sprites/arena.png (renamed from samples/07_advanced_rendering/08_z_targeting_camera/sprites/arena.png)bin1072678 -> 1072678 bytes
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/sprites/player.png (renamed from samples/07_advanced_rendering/08_z_targeting_camera/sprites/player.png)bin9510 -> 9510 bytes
-rw-r--r--samples/07_advanced_rendering/09_z_targeting_camera/sprites/square/black.png (renamed from samples/07_advanced_rendering/08_z_targeting_camera/sprites/square/black.png)bin250 -> 250 bytes
-rw-r--r--samples/07_advanced_rendering/10_blend_modes/app/main.rb49
-rw-r--r--samples/07_advanced_rendering/10_blend_modes/sprites/blue-feathered.pngbin0 -> 7204 bytes
24 files changed, 817 insertions, 130 deletions
diff --git a/samples/07_advanced_rendering/02_render_targets_with_alphas/app/main.rb b/samples/07_advanced_rendering/02_render_targets_with_alphas/app/main.rb
deleted file mode 100644
index 2caec43..0000000
--- a/samples/07_advanced_rendering/02_render_targets_with_alphas/app/main.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# This sample is meant to show you how to do that dripping transition thing
-# at the start of the original Doom. Most of this file is here to animate
-# a scene to wipe away; the actual wipe effect is in the last 20 lines or
-# so.
-
-$gtk.reset # reset all game state if reloaded.
-
-def circle_of_blocks pass, xoffset, yoffset, angleoffset, blocksize, distance
- numblocks = 10
-
- for i in 1..numblocks do
- angle = ((360 / numblocks) * i) + angleoffset
- radians = angle * (Math::PI / 180)
- x = (xoffset + (distance * Math.cos(radians))).round
- y = (yoffset + (distance * Math.sin(radians))).round
- pass.solids << [ x, y, blocksize, blocksize, 255, 255, 0 ]
- end
-end
-
-def draw_scene args, pass
- pass.solids << [0, 360, 1280, 360, 0, 0, 200]
- pass.solids << [0, 0, 1280, 360, 0, 127, 0]
-
- blocksize = 100
- angleoffset = args.state.tick_count * 2.5
- centerx = (1280 - blocksize) / 2
- centery = (720 - blocksize) / 2
-
- circle_of_blocks pass, centerx, centery, angleoffset, blocksize * 2, 500
- circle_of_blocks pass, centerx, centery, angleoffset, blocksize, 325
- circle_of_blocks pass, centerx, centery, angleoffset, blocksize / 2, 200
- circle_of_blocks pass, centerx, centery, angleoffset, blocksize / 4, 100
-end
-
-def tick args
- segments = 160
-
- # On the first tick, initialize some stuff.
- if !args.state.yoffsets
- args.state.baseyoff = 0
- args.state.yoffsets = []
- for i in 0..segments do
- args.state.yoffsets << rand * 100
- end
- end
-
- # Just draw some random stuff for a few seconds.
- args.state.static_debounce ||= 60 * 2.5
- if args.state.static_debounce > 0
- last_frame = args.state.static_debounce == 1
- target = last_frame ? args.render_target(:last_frame) : args.outputs
- draw_scene args, target
- args.state.static_debounce -= 1
- return unless last_frame
- end
-
- # build up the wipe...
-
- # this is the thing we're wiping to.
- args.outputs.sprites << [ 0, 0, 1280, 720, 'dragonruby.png' ]
-
- return if (args.state.baseyoff > (1280 + 100)) # stop when done sliding
-
- segmentw = 1280 / segments
-
- x = 0
- for i in 0..segments do
- yoffset = 0
- if args.state.yoffsets[i] < args.state.baseyoff
- yoffset = args.state.baseyoff - args.state.yoffsets[i]
- end
-
- # (720 - yoffset) flips the coordinate system, (- 720) adjusts for the height of the segment.
- args.outputs.sprites << [ x, (720 - yoffset) - 720, segmentw, 720, 'last_frame', 0, 255, 255, 255, 255, x, 0, segmentw, 720 ]
- x += segmentw
- end
-
- args.state.baseyoff += 4
-
- tick_instructions args, "Sample app shows an advanced usage of render_target."
-end
-
-def tick_instructions args, text, y = 715
- return if args.state.key_event_occurred
- if args.inputs.mouse.click ||
- args.inputs.keyboard.directional_vector ||
- args.inputs.keyboard.key_down.enter ||
- args.inputs.keyboard.key_down.escape
- args.state.key_event_occurred = true
- end
-
- args.outputs.debug << [0, y - 50, 1280, 60].solid
- args.outputs.debug << [640, y, text, 1, 1, 255, 255, 255].label
- args.outputs.debug << [640, y - 25, "(click to dismiss instructions)" , -2, 1, 255, 255, 255].label
-end
diff --git a/samples/07_advanced_rendering/02_render_targets_with_alphas/license-for-sample.txt b/samples/07_advanced_rendering/02_render_targets_with_alphas/license-for-sample.txt
deleted file mode 100644
index 100dcec..0000000
--- a/samples/07_advanced_rendering/02_render_targets_with_alphas/license-for-sample.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Copyright 2019 DragonRuby LLC
-
-MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/samples/07_advanced_rendering/03_render_target_viewports/app/main.rb b/samples/07_advanced_rendering/03_render_target_viewports/app/main.rb
index 0dd6c18..dbceab3 100644
--- a/samples/07_advanced_rendering/03_render_target_viewports/app/main.rb
+++ b/samples/07_advanced_rendering/03_render_target_viewports/app/main.rb
@@ -25,7 +25,7 @@
would print "How are you, Ruby?" to the console.
(Remember, string interpolation only works with double quotes!)
- - Ternary operator (?): Similar to if statement; first evaluates whether a statement is
+ - Ternary operator (?): Similar to if statement; first evalulates whether a statement is
true or false, and then executes a command depending on that result.
For example, if we had a variable
grade = 75
@@ -39,7 +39,7 @@
720 p screen (Dragon Ruby Game Toolkits's virtual resolution is always 1280x720).
- Numeric#shift_(left|right|up|down): Shifts the Numeric in the correct direction
- by adding or subtracting.
+ by adding or subracting.
- ARRAY#inside_rect?: An array with at least two values is considered a point. An array
with at least four values is considered a rect. The inside_rect? function returns true
@@ -48,10 +48,12 @@
- ARRAY#intersect_rect?: Returns true or false depending on if the two rectangles intersect.
- args.inputs.mouse.click: This property will be set if the mouse was clicked.
+ For more information about the mouse, go to mygame/documentation/07-mouse.md.
- args.inputs.keyboard.key_up.KEY: The value of the properties will be set
to the frame that the key_up event occurred (the frame correlates
to args.state.tick_count).
+ For more information about the keyboard, go to mygame/documentation/06-keyboard.md.
- args.state.labels:
The parameters for a label are
@@ -61,6 +63,7 @@
4. the alignment
5. the color (red, green, and blue saturations)
6. the alpha (or transparency)
+ For more information about labels, go to mygame/documentation/02-labels.md.
- args.state.lines:
The parameters for a line are
@@ -68,6 +71,7 @@
2. the ending position (x2, y2)
3. the color (red, green, and blue saturations)
4. the alpha (or transparency)
+ For more information about lines, go to mygame/documentation/04-lines.md.
- args.state.solids (and args.state.borders):
The parameters for a solid (or border) are
@@ -76,6 +80,7 @@
3. the height (h)
4. the color (r, g, b)
5. the alpha (or transparency)
+ For more information about solids and borders, go to mygame/documentation/03-solids-and-borders.md.
- args.state.sprites:
The parameters for a sprite are
@@ -85,7 +90,7 @@
4. the image path
5. the angle
6. the alpha (or transparency)
-
+ For more information about sprites, go to mygame/documentation/05-sprites.md.
=end
# This sample app shows different objects that can be used when making games, such as labels,
@@ -111,7 +116,7 @@ class TechDemo
button_tech_demo
export_game_state_demo
window_state_demo
- render_separators
+ render_seperators
end
# Shows output of different kinds of labels on the screen
@@ -408,28 +413,28 @@ class TechDemo
end
#Sets values for the horizontal separator (divides demo sections)
- def horizontal_separator y, x, x2
+ def horizontal_seperator y, x, x2
[x, y, x2, y, 150, 150, 150]
end
#Sets the values for the vertical separator (divides demo sections)
- def vertical_separator x, y, y2
+ def vertical_seperator x, y, y2
[x, y, x, y2, 150, 150, 150]
end
# Outputs vertical and horizontal separators onto the screen to separate each demo section.
- def render_separators
- outputs.lines << horizontal_separator(505, grid.left, 445)
- outputs.lines << horizontal_separator(353, grid.left, 445)
- outputs.lines << horizontal_separator(264, grid.left, 445)
- outputs.lines << horizontal_separator(174, grid.left, 445)
+ def render_seperators
+ outputs.lines << horizontal_seperator(505, grid.left, 445)
+ outputs.lines << horizontal_seperator(353, grid.left, 445)
+ outputs.lines << horizontal_seperator(264, grid.left, 445)
+ outputs.lines << horizontal_seperator(174, grid.left, 445)
- outputs.lines << vertical_separator(445, grid.top, grid.bottom)
+ outputs.lines << vertical_seperator(445, grid.top, grid.bottom)
- outputs.lines << horizontal_separator(690, 445, 820)
- outputs.lines << horizontal_separator(426, 445, 820)
+ outputs.lines << horizontal_seperator(690, 445, 820)
+ outputs.lines << horizontal_seperator(426, 445, 820)
- outputs.lines << vertical_separator(820, grid.top, grid.bottom)
+ outputs.lines << vertical_seperator(820, grid.top, grid.bottom)
end
end
diff --git a/samples/07_advanced_rendering/04_render_primitive_hierarchies/app/main.rb b/samples/07_advanced_rendering/04_render_primitive_hierarchies/app/main.rb
index 7f345ac..aedd830 100644
--- a/samples/07_advanced_rendering/04_render_primitive_hierarchies/app/main.rb
+++ b/samples/07_advanced_rendering/04_render_primitive_hierarchies/app/main.rb
@@ -39,6 +39,7 @@
Here is an example of a (red) border or solid definition:
[100, 100, 400, 500, 255, 0, 0]
It will be a solid or border depending on if it is added to args.outputs.solids or args.outputs.borders.
+ For more information about solids and borders, go to mygame/documentation/03-solids-and-borders.md.
- args.outputs.sprites: An array. The values generate a sprite.
The parameters for sprites are
@@ -49,6 +50,7 @@
Here is an example of a sprite definition:
[100, 100, 400, 500, 'sprites/dragonruby.png']
+ For more information about sprites, go to mygame/documentation/05-sprites.md.
=end
diff --git a/samples/07_advanced_rendering/05_render_primitives_as_hash/app/main.rb b/samples/07_advanced_rendering/05_render_primitives_as_hash/app/main.rb
index 53e0f3d..907b0fb 100644
--- a/samples/07_advanced_rendering/05_render_primitives_as_hash/app/main.rb
+++ b/samples/07_advanced_rendering/05_render_primitives_as_hash/app/main.rb
@@ -16,18 +16,23 @@
- args.outputs.sprites: An array. The values generate a sprite.
The parameters are [X, Y, WIDTH, HEIGHT, PATH, ANGLE, ALPHA, RED, GREEN, BLUE]
+ For more information about sprites, go to mygame/documentation/05-sprites.md.
- args.outputs.labels: An array. The values generate a label.
The parameters are [X, Y, TEXT, SIZE, ALIGNMENT, RED, GREEN, BLUE, ALPHA, FONT STYLE]
+ For more information about labels, go to mygame/documentation/02-labels.md.
- args.outputs.solids: An array. The values generate a solid.
The parameters are [X, Y, WIDTH, HEIGHT, RED, GREEN, BLUE, ALPHA]
+ For more information about solids, go to mygame/documentation/03-solids-and-borders.md.
- args.outputs.borders: An array. The values generate a border.
The parameters are the same as a solid.
+ For more information about borders, go to mygame/documentation/03-solids-and-borders.md.
- args.outputs.lines: An array. The values generate a line.
The parameters are [X1, Y1, X2, Y2, RED, GREEN, BLUE]
+ For more information about labels, go to mygame/documentation/02-labels.md.
=end
@@ -131,7 +136,7 @@ def tick args
flip_horizontally: false,
angle_anchor_x: 0.5, # rotation center set to middle
angle_anchor_y: 0.5
- }.sprite
+ }.sprite!
# Outputs label as primitive using a hash
args.outputs.primitives << {
@@ -145,7 +150,7 @@ def tick args
b: 50,
a: 255, # transparency
font: "fonts/manaspc.ttf" # font style
- }.label
+ }.label!
# Outputs solid as primitive using a hash
args.outputs.primitives << {
@@ -157,7 +162,7 @@ def tick args
g: 50,
b: 50,
a: 255 # transparency
- }.solid
+ }.solid!
# Outputs border as primitive using a hash
# Same parameters as solid
@@ -170,7 +175,7 @@ def tick args
g: 50,
b: 50,
a: 255 # transparency
- }.border
+ }.border!
# Outputs line as primitive using a hash
args.outputs.primitives << {
@@ -182,5 +187,5 @@ def tick args
g: 50,
b: 50,
a: 255 # transparency
- }.line
+ }.line!
end
diff --git a/samples/07_advanced_rendering/07_simple_camera/app/main.rb b/samples/07_advanced_rendering/07_simple_camera/app/main.rb
new file mode 100644
index 0000000..e8d96ea
--- /dev/null
+++ b/samples/07_advanced_rendering/07_simple_camera/app/main.rb
@@ -0,0 +1,93 @@
+def tick args
+ # variables you can play around with
+ args.state.world.w ||= 1280
+ args.state.world.h ||= 720
+
+ args.state.player.x ||= 0
+ args.state.player.y ||= 0
+ args.state.player.size ||= 32
+
+ args.state.enemy.x ||= 700
+ args.state.enemy.y ||= 700
+ args.state.enemy.size ||= 16
+
+ args.state.camera.x ||= 640
+ args.state.camera.y ||= 300
+ args.state.camera.scale ||= 1.0
+ args.state.camera.show_empty_space ||= :yes
+
+ # instructions
+ args.outputs.primitives << { x: 0, y: 80.from_top, w: 360, h: 80, r: 0, g: 0, b: 0, a: 128 }.solid!
+ args.outputs.primitives << { x: 10, y: 10.from_top, text: "arrow keys to move around", r: 255, g: 255, b: 255}.label!
+ args.outputs.primitives << { x: 10, y: 30.from_top, text: "+/- to change zoom of camera", r: 255, g: 255, b: 255}.label!
+ args.outputs.primitives << { x: 10, y: 50.from_top, text: "tab to change camera edge behavior", r: 255, g: 255, b: 255}.label!
+
+ # render scene
+ args.outputs[:scene].w = args.state.world.w
+ args.outputs[:scene].h = args.state.world.h
+
+ args.outputs[:scene].solids << { x: 0, y: 0, w: args.state.world.w, h: args.state.world.h, r: 20, g: 60, b: 80 }
+ args.outputs[:scene].solids << { x: args.state.player.x, y: args.state.player.y,
+ w: args.state.player.size, h: args.state.player.size, r: 80, g: 155, b: 80 }
+ args.outputs[:scene].solids << { x: args.state.enemy.x, y: args.state.enemy.y,
+ w: args.state.enemy.size, h: args.state.enemy.size, r: 155, g: 80, b: 80 }
+
+ # render camera
+ scene_position = calc_scene_position args
+ args.outputs.sprites << { x: scene_position.x,
+ y: scene_position.y,
+ w: scene_position.w,
+ h: scene_position.h,
+ path: :scene }
+
+ # move player
+ if args.inputs.directional_angle
+ args.state.player.x += args.inputs.directional_angle.vector_x * 5
+ args.state.player.y += args.inputs.directional_angle.vector_y * 5
+ args.state.player.x = args.state.player.x.clamp(0, args.state.world.w - args.state.player.size)
+ args.state.player.y = args.state.player.y.clamp(0, args.state.world.h - args.state.player.size)
+ end
+
+ # +/- to zoom in and out
+ if args.inputs.keyboard.plus && args.state.tick_count.zmod?(3)
+ args.state.camera.scale += 0.05
+ elsif args.inputs.keyboard.hyphen && args.state.tick_count.zmod?(3)
+ args.state.camera.scale -= 0.05
+ elsif args.inputs.keyboard.key_down.tab
+ if args.state.camera.show_empty_space == :yes
+ args.state.camera.show_empty_space = :no
+ else
+ args.state.camera.show_empty_space = :yes
+ end
+ end
+
+ args.state.camera.scale = args.state.camera.scale.greater(0.1)
+end
+
+def calc_scene_position args
+ result = { x: args.state.camera.x - (args.state.player.x * args.state.camera.scale),
+ y: args.state.camera.y - (args.state.player.y * args.state.camera.scale),
+ w: args.state.world.w * args.state.camera.scale,
+ h: args.state.world.h * args.state.camera.scale,
+ scale: args.state.camera.scale }
+
+ return result if args.state.camera.show_empty_space == :yes
+
+ if result.w < args.grid.w
+ result.merge!(x: (args.grid.w - result.w).half)
+ elsif (args.state.player.x * result.scale) < args.grid.w.half
+ result.merge!(x: 10)
+ elsif (result.x + result.w) < args.grid.w
+ result.merge!(x: - result.w + (args.grid.w - 10))
+ end
+
+ if result.h < args.grid.h
+ result.merge!(y: (args.grid.h - result.h).half)
+ elsif (result.y) > 10
+ result.merge!(y: 10)
+ elsif (result.y + result.h) < args.grid.h
+ result.merge!(y: - result.h + (args.grid.h - 10))
+ end
+
+ result
+end
diff --git a/samples/07_advanced_rendering/07_simple_camera/replay.txt b/samples/07_advanced_rendering/07_simple_camera/replay.txt
new file mode 100644
index 0000000..532f46c
--- /dev/null
+++ b/samples/07_advanced_rendering/07_simple_camera/replay.txt
@@ -0,0 +1,232 @@
+replay_version 2.0
+stopped_at 1551
+seed 100
+recorded_at Sat Jul 17 09:21:44 2021
+[:mouse_button_up, 1, 0, 1, 1, 6]
+[:mouse_button_pressed, 1, 0, 1, 2, 140]
+[:mouse_button_up, 1, 0, 1, 3, 146]
+[:key_down_raw, 1073741903, 0, 2, 4, 245]
+[:key_down_raw, 1073741903, 0, 2, 5, 259]
+[:key_down_raw, 1073741903, 0, 2, 6, 261]
+[:key_down_raw, 1073741903, 0, 2, 7, 263]
+[:key_down_raw, 1073741903, 0, 2, 8, 265]
+[:key_down_raw, 1073741903, 0, 2, 9, 267]
+[:key_down_raw, 1073741903, 0, 2, 10, 269]
+[:key_down_raw, 1073741906, 0, 2, 11, 269]
+[:key_up_raw, 1073741903, 0, 2, 12, 280]
+[:key_down_raw, 1073741903, 0, 2, 13, 284]
+[:key_down_raw, 1073741903, 0, 2, 14, 299]
+[:key_down_raw, 1073741903, 0, 2, 15, 301]
+[:key_down_raw, 1073741903, 0, 2, 16, 303]
+[:key_down_raw, 1073741903, 0, 2, 17, 305]
+[:key_down_raw, 1073741903, 0, 2, 18, 307]
+[:key_down_raw, 1073741903, 0, 2, 19, 309]
+[:key_down_raw, 1073741903, 0, 2, 20, 311]
+[:key_down_raw, 1073741903, 0, 2, 21, 313]
+[:key_down_raw, 1073741903, 0, 2, 22, 315]
+[:key_down_raw, 1073741903, 0, 2, 23, 317]
+[:key_down_raw, 1073741903, 0, 2, 24, 319]
+[:key_down_raw, 1073741903, 0, 2, 25, 321]
+[:key_down_raw, 1073741903, 0, 2, 26, 323]
+[:key_down_raw, 1073741903, 0, 2, 27, 325]
+[:key_down_raw, 1073741903, 0, 2, 28, 327]
+[:key_down_raw, 1073741903, 0, 2, 29, 329]
+[:key_down_raw, 1073741903, 0, 2, 30, 331]
+[:key_down_raw, 1073741903, 0, 2, 31, 333]
+[:key_down_raw, 1073741903, 0, 2, 32, 335]
+[:key_down_raw, 1073741903, 0, 2, 33, 337]
+[:key_down_raw, 1073741903, 0, 2, 34, 339]
+[:key_up_raw, 1073741906, 0, 2, 35, 341]
+[:key_down_raw, 1073741903, 0, 2, 36, 341]
+[:key_down_raw, 1073741903, 0, 2, 37, 343]
+[:key_down_raw, 1073741903, 0, 2, 38, 345]
+[:key_down_raw, 1073741903, 0, 2, 39, 347]
+[:key_down_raw, 1073741903, 0, 2, 40, 349]
+[:key_down_raw, 1073741903, 0, 2, 41, 351]
+[:key_down_raw, 1073741903, 0, 2, 42, 353]
+[:key_down_raw, 1073741903, 0, 2, 43, 355]
+[:key_down_raw, 1073741906, 0, 2, 44, 357]
+[:key_down_raw, 1073741906, 0, 2, 45, 372]
+[:key_down_raw, 1073741906, 0, 2, 46, 374]
+[:key_down_raw, 1073741906, 0, 2, 47, 376]
+[:key_down_raw, 1073741906, 0, 2, 48, 378]
+[:key_down_raw, 1073741906, 0, 2, 49, 380]
+[:key_down_raw, 1073741906, 0, 2, 50, 382]
+[:key_down_raw, 1073741906, 0, 2, 51, 384]
+[:key_down_raw, 1073741906, 0, 2, 52, 386]
+[:key_down_raw, 1073741906, 0, 2, 53, 388]
+[:key_down_raw, 1073741906, 0, 2, 54, 390]
+[:key_down_raw, 1073741906, 0, 2, 55, 392]
+[:key_down_raw, 1073741906, 0, 2, 56, 395]
+[:key_up_raw, 1073741906, 0, 2, 57, 396]
+[:key_up_raw, 1073741903, 0, 2, 58, 397]
+[:key_down_raw, 8, 0, 2, 59, 466]
+[:key_up_raw, 8, 0, 2, 60, 466]
+[:key_down_raw, 8, 0, 2, 61, 470]
+[:key_up_raw, 8, 0, 2, 62, 475]
+[:key_down_raw, 45, 0, 2, 63, 540]
+[:key_up_raw, 45, 0, 2, 64, 545]
+[:key_down_raw, 45, 0, 2, 65, 551]
+[:key_up_raw, 45, 0, 2, 66, 556]
+[:key_down_raw, 45, 0, 2, 67, 566]
+[:key_up_raw, 45, 0, 2, 68, 571]
+[:key_down_raw, 45, 0, 2, 69, 577]
+[:key_up_raw, 45, 0, 2, 70, 581]
+[:key_down_raw, 45, 0, 2, 71, 595]
+[:key_up_raw, 45, 0, 2, 72, 600]
+[:key_down_raw, 1073741905, 0, 2, 73, 715]
+[:key_down_raw, 1073741905, 0, 2, 74, 730]
+[:key_down_raw, 1073741905, 0, 2, 75, 732]
+[:key_down_raw, 1073741905, 0, 2, 76, 734]
+[:key_down_raw, 1073741905, 0, 2, 77, 736]
+[:key_down_raw, 1073741905, 0, 2, 78, 738]
+[:key_down_raw, 1073741904, 0, 2, 79, 739]
+[:key_up_raw, 1073741905, 0, 2, 80, 743]
+[:key_down_raw, 1073741904, 0, 2, 81, 754]
+[:key_down_raw, 1073741904, 0, 2, 82, 756]
+[:key_down_raw, 1073741904, 0, 2, 83, 758]
+[:key_down_raw, 1073741904, 0, 2, 84, 760]
+[:key_down_raw, 1073741904, 0, 2, 85, 762]
+[:key_down_raw, 1073741904, 0, 2, 86, 764]
+[:key_down_raw, 1073741904, 0, 2, 87, 766]
+[:key_down_raw, 1073741904, 0, 2, 88, 768]
+[:key_down_raw, 1073741904, 0, 2, 89, 770]
+[:key_down_raw, 1073741904, 0, 2, 90, 772]
+[:key_down_raw, 1073741905, 0, 2, 91, 774]
+[:key_down_raw, 1073741906, 0, 2, 92, 781]
+[:key_up_raw, 1073741904, 0, 2, 93, 785]
+[:key_up_raw, 1073741905, 0, 2, 94, 791]
+[:key_down_raw, 1073741906, 0, 2, 95, 796]
+[:key_down_raw, 1073741903, 0, 2, 96, 797]
+[:key_up_raw, 1073741906, 0, 2, 97, 804]
+[:key_up_raw, 1073741903, 0, 2, 98, 810]
+[:key_down_raw, 1073742049, 1, 2, 99, 884]
+[:key_down_raw, 61, 1, 2, 100, 885]
+[:key_up_raw, 61, 1, 2, 101, 888]
+[:key_up_raw, 1073742049, 0, 2, 102, 888]
+[:key_down_raw, 1073742049, 1, 2, 103, 898]
+[:key_down_raw, 61, 1, 2, 104, 899]
+[:key_up_raw, 61, 1, 2, 105, 903]
+[:key_up_raw, 1073742049, 0, 2, 106, 903]
+[:key_down_raw, 1073742049, 1, 2, 107, 909]
+[:key_down_raw, 61, 1, 2, 108, 909]
+[:key_up_raw, 61, 1, 2, 109, 912]
+[:key_up_raw, 1073742049, 0, 2, 110, 913]
+[:key_down_raw, 1073742049, 1, 2, 111, 918]
+[:key_down_raw, 61, 1, 2, 112, 918]
+[:key_up_raw, 61, 1, 2, 113, 921]
+[:key_up_raw, 1073742049, 0, 2, 114, 922]
+[:key_down_raw, 1073742049, 1, 2, 115, 926]
+[:key_down_raw, 61, 1, 2, 116, 926]
+[:key_up_raw, 61, 1, 2, 117, 930]
+[:key_up_raw, 1073742049, 0, 2, 118, 931]
+[:key_down_raw, 1073742049, 1, 2, 119, 935]
+[:key_down_raw, 61, 1, 2, 120, 935]
+[:key_up_raw, 61, 1, 2, 121, 940]
+[:key_up_raw, 1073742049, 0, 2, 122, 941]
+[:key_down_raw, 1073742049, 1, 2, 123, 947]
+[:key_down_raw, 61, 1, 2, 124, 947]
+[:key_up_raw, 61, 1, 2, 125, 950]
+[:key_up_raw, 1073742049, 0, 2, 126, 951]
+[:key_down_raw, 1073742049, 1, 2, 127, 955]
+[:key_down_raw, 61, 1, 2, 128, 956]
+[:key_up_raw, 61, 1, 2, 129, 960]
+[:key_up_raw, 1073742049, 0, 2, 130, 960]
+[:key_down_raw, 9, 0, 2, 131, 986]
+[:key_up_raw, 9, 0, 2, 132, 991]
+[:key_down_raw, 1073741904, 0, 2, 133, 1015]
+[:key_down_raw, 1073741904, 0, 2, 134, 1030]
+[:key_down_raw, 1073741904, 0, 2, 135, 1032]
+[:key_down_raw, 1073741904, 0, 2, 136, 1034]
+[:key_down_raw, 1073741904, 0, 2, 137, 1036]
+[:key_down_raw, 1073741904, 0, 2, 138, 1038]
+[:key_down_raw, 1073741904, 0, 2, 139, 1040]
+[:key_down_raw, 1073741904, 0, 2, 140, 1042]
+[:key_up_raw, 1073741904, 0, 2, 141, 1044]
+[:key_down_raw, 1073741903, 0, 2, 142, 1048]
+[:key_down_raw, 1073741903, 0, 2, 143, 1063]
+[:key_down_raw, 1073741903, 0, 2, 144, 1065]
+[:key_down_raw, 1073741903, 0, 2, 145, 1067]
+[:key_down_raw, 1073741903, 0, 2, 146, 1069]
+[:key_down_raw, 1073741903, 0, 2, 147, 1071]
+[:key_down_raw, 1073741903, 0, 2, 148, 1073]
+[:key_down_raw, 1073741903, 0, 2, 149, 1075]
+[:key_down_raw, 1073741903, 0, 2, 150, 1077]
+[:key_down_raw, 1073741903, 0, 2, 151, 1079]
+[:key_down_raw, 1073741903, 0, 2, 152, 1081]
+[:key_down_raw, 1073741903, 0, 2, 153, 1083]
+[:key_down_raw, 1073741903, 0, 2, 154, 1085]
+[:key_down_raw, 1073741903, 0, 2, 155, 1087]
+[:key_down_raw, 1073741903, 0, 2, 156, 1089]
+[:key_down_raw, 1073741903, 0, 2, 157, 1091]
+[:key_down_raw, 1073741903, 0, 2, 158, 1093]
+[:key_down_raw, 1073741903, 0, 2, 159, 1095]
+[:key_down_raw, 1073741903, 0, 2, 160, 1097]
+[:key_down_raw, 1073741903, 0, 2, 161, 1099]
+[:key_down_raw, 1073741903, 0, 2, 162, 1101]
+[:key_down_raw, 1073741903, 0, 2, 163, 1103]
+[:key_down_raw, 1073741903, 0, 2, 164, 1105]
+[:key_down_raw, 1073741903, 0, 2, 165, 1107]
+[:key_down_raw, 1073741903, 0, 2, 166, 1109]
+[:key_down_raw, 1073741903, 0, 2, 167, 1111]
+[:key_down_raw, 1073741903, 0, 2, 168, 1113]
+[:key_down_raw, 1073741903, 0, 2, 169, 1115]
+[:key_down_raw, 1073741903, 0, 2, 170, 1117]
+[:key_down_raw, 1073741903, 0, 2, 171, 1119]
+[:key_down_raw, 1073741903, 0, 2, 172, 1121]
+[:key_down_raw, 1073741903, 0, 2, 173, 1123]
+[:key_down_raw, 1073741903, 0, 2, 174, 1125]
+[:key_down_raw, 1073741903, 0, 2, 175, 1127]
+[:key_down_raw, 1073741903, 0, 2, 176, 1129]
+[:key_down_raw, 1073741903, 0, 2, 177, 1131]
+[:key_down_raw, 1073741903, 0, 2, 178, 1133]
+[:key_down_raw, 1073741903, 0, 2, 179, 1135]
+[:key_down_raw, 1073741903, 0, 2, 180, 1137]
+[:key_down_raw, 1073741903, 0, 2, 181, 1139]
+[:key_down_raw, 1073741903, 0, 2, 182, 1141]
+[:key_down_raw, 1073741903, 0, 2, 183, 1143]
+[:key_down_raw, 1073741903, 0, 2, 184, 1145]
+[:key_down_raw, 1073741903, 0, 2, 185, 1147]
+[:key_down_raw, 1073741903, 0, 2, 186, 1149]
+[:key_down_raw, 1073741903, 0, 2, 187, 1151]
+[:key_down_raw, 1073741903, 0, 2, 188, 1153]
+[:key_down_raw, 1073741903, 0, 2, 189, 1155]
+[:key_down_raw, 1073741903, 0, 2, 190, 1157]
+[:key_down_raw, 1073741903, 0, 2, 191, 1159]
+[:key_down_raw, 1073741903, 0, 2, 192, 1161]
+[:key_down_raw, 1073741903, 0, 2, 193, 1163]
+[:key_down_raw, 1073741905, 0, 2, 194, 1164]
+[:key_down_raw, 1073741905, 0, 2, 195, 1180]
+[:key_down_raw, 1073741905, 0, 2, 196, 1182]
+[:key_down_raw, 1073741905, 0, 2, 197, 1184]
+[:key_down_raw, 1073741905, 0, 2, 198, 1186]
+[:key_down_raw, 1073741905, 0, 2, 199, 1188]
+[:key_down_raw, 1073741905, 0, 2, 200, 1190]
+[:key_down_raw, 1073741905, 0, 2, 201, 1192]
+[:key_down_raw, 1073741905, 0, 2, 202, 1194]
+[:key_down_raw, 1073741905, 0, 2, 203, 1196]
+[:key_down_raw, 1073741905, 0, 2, 204, 1198]
+[:key_down_raw, 1073741905, 0, 2, 205, 1200]
+[:key_down_raw, 1073741905, 0, 2, 206, 1202]
+[:key_down_raw, 1073741905, 0, 2, 207, 1204]
+[:key_down_raw, 1073741905, 0, 2, 208, 1206]
+[:key_down_raw, 1073741905, 0, 2, 209, 1208]
+[:key_down_raw, 1073741905, 0, 2, 210, 1210]
+[:key_down_raw, 1073741905, 0, 2, 211, 1212]
+[:key_down_raw, 1073741905, 0, 2, 212, 1214]
+[:key_down_raw, 1073741905, 0, 2, 213, 1216]
+[:key_up_raw, 1073741903, 0, 2, 214, 1216]
+[:key_up_raw, 1073741905, 0, 2, 215, 1217]
+[:key_down_raw, 45, 0, 2, 216, 1263]
+[:key_up_raw, 45, 0, 2, 217, 1265]
+[:key_down_raw, 45, 0, 2, 218, 1271]
+[:key_up_raw, 45, 0, 2, 219, 1275]
+[:key_down_raw, 45, 0, 2, 220, 1282]
+[:key_up_raw, 45, 0, 2, 221, 1287]
+[:key_down_raw, 45, 0, 2, 222, 1296]
+[:key_up_raw, 45, 0, 2, 223, 1301]
+[:key_down_raw, 45, 0, 2, 224, 1308]
+[:key_up_raw, 45, 0, 2, 225, 1312]
+[:key_down_raw, 96, 0, 2, 226, 1386]
+[:key_up_raw, 96, 0, 2, 227, 1391]
+[:key_down_raw, 13, 0, 2, 228, 1551]
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/run.bat b/samples/07_advanced_rendering/07_splitscreen_camera/run.bat
deleted file mode 100644
index 08e7ed8..0000000
--- a/samples/07_advanced_rendering/07_splitscreen_camera/run.bat
+++ /dev/null
@@ -1,6 +0,0 @@
-cd /d %~dp0
-
-cd ..
-cd ..
-cd ..
-dragonruby samples/99_camera/splitscreen
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/app/main.rb b/samples/07_advanced_rendering/08_splitscreen_camera/app/main.rb
index 9b08e1e..9b08e1e 100644
--- a/samples/07_advanced_rendering/07_splitscreen_camera/app/main.rb
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/app/main.rb
diff --git a/samples/07_advanced_rendering/08_splitscreen_camera/replay.txt b/samples/07_advanced_rendering/08_splitscreen_camera/replay.txt
new file mode 100644
index 0000000..b0c548e
--- /dev/null
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/replay.txt
@@ -0,0 +1,226 @@
+replay_version 2.0
+stopped_at 1047
+seed 100
+recorded_at Sat Jul 17 09:23:22 2021
+[:mouse_button_up, 1, 0, 1, 1, 5]
+[:mouse_move, 795, 98, 2, 2, 75]
+[:mouse_move, 797, 100, 2, 3, 77]
+[:mouse_move, 799, 101, 2, 4, 78]
+[:mouse_move, 800, 101, 2, 5, 78]
+[:mouse_button_pressed, 1, 0, 1, 6, 88]
+[:mouse_button_up, 1, 0, 1, 7, 92]
+[:key_down_raw, 1073741903, 0, 2, 8, 124]
+[:key_down_raw, 1073741903, 0, 2, 9, 138]
+[:key_down_raw, 1073741903, 0, 2, 10, 141]
+[:key_down_raw, 1073741903, 0, 2, 11, 142]
+[:key_down_raw, 1073741903, 0, 2, 12, 144]
+[:key_down_raw, 1073741903, 0, 2, 13, 147]
+[:key_down_raw, 1073741903, 0, 2, 14, 148]
+[:key_down_raw, 1073741903, 0, 2, 15, 151]
+[:key_down_raw, 1073741906, 0, 2, 16, 151]
+[:key_down_raw, 1073741906, 0, 2, 17, 166]
+[:key_down_raw, 1073741906, 0, 2, 18, 169]
+[:key_down_raw, 1073741906, 0, 2, 19, 170]
+[:key_down_raw, 1073741906, 0, 2, 20, 172]
+[:key_down_raw, 1073741906, 0, 2, 21, 174]
+[:key_down_raw, 1073741906, 0, 2, 22, 177]
+[:key_down_raw, 1073741906, 0, 2, 23, 178]
+[:key_down_raw, 1073741906, 0, 2, 24, 180]
+[:key_down_raw, 1073741906, 0, 2, 25, 182]
+[:key_down_raw, 1073741906, 0, 2, 26, 184]
+[:key_down_raw, 1073741906, 0, 2, 27, 186]
+[:key_down_raw, 1073741906, 0, 2, 28, 188]
+[:key_down_raw, 1073741906, 0, 2, 29, 190]
+[:key_down_raw, 1073741906, 0, 2, 30, 193]
+[:key_down_raw, 1073741906, 0, 2, 31, 194]
+[:key_up_raw, 1073741906, 0, 2, 32, 195]
+[:key_up_raw, 1073741903, 0, 2, 33, 291]
+[:key_down_raw, 119, 0, 2, 34, 360]
+[:key_down_raw, 119, 0, 2, 35, 375]
+[:key_down_raw, 119, 0, 2, 36, 378]
+[:key_down_raw, 119, 0, 2, 37, 379]
+[:key_down_raw, 119, 0, 2, 38, 381]
+[:key_down_raw, 119, 0, 2, 39, 383]
+[:key_down_raw, 119, 0, 2, 40, 385]
+[:key_down_raw, 119, 0, 2, 41, 387]
+[:key_down_raw, 119, 0, 2, 42, 389]
+[:key_down_raw, 119, 0, 2, 43, 391]
+[:key_down_raw, 119, 0, 2, 44, 393]
+[:key_down_raw, 119, 0, 2, 45, 395]
+[:key_down_raw, 119, 0, 2, 46, 397]
+[:key_down_raw, 119, 0, 2, 47, 401]
+[:key_down_raw, 119, 0, 2, 48, 403]
+[:key_down_raw, 119, 0, 2, 49, 405]
+[:key_down_raw, 119, 0, 2, 50, 407]
+[:key_down_raw, 119, 0, 2, 51, 409]
+[:key_down_raw, 119, 0, 2, 52, 411]
+[:key_down_raw, 119, 0, 2, 53, 412]
+[:key_down_raw, 119, 0, 2, 54, 414]
+[:key_down_raw, 119, 0, 2, 55, 416]
+[:key_down_raw, 119, 0, 2, 56, 419]
+[:key_down_raw, 119, 0, 2, 57, 421]
+[:key_down_raw, 119, 0, 2, 58, 422]
+[:key_down_raw, 119, 0, 2, 59, 424]
+[:key_down_raw, 119, 0, 2, 60, 426]
+[:key_down_raw, 119, 0, 2, 61, 429]
+[:key_down_raw, 119, 0, 2, 62, 431]
+[:key_down_raw, 119, 0, 2, 63, 432]
+[:key_down_raw, 119, 0, 2, 64, 434]
+[:key_down_raw, 119, 0, 2, 65, 436]
+[:key_down_raw, 119, 0, 2, 66, 438]
+[:key_down_raw, 119, 0, 2, 67, 441]
+[:key_down_raw, 119, 0, 2, 68, 443]
+[:key_down_raw, 119, 0, 2, 69, 444]
+[:key_down_raw, 119, 0, 2, 70, 446]
+[:key_down_raw, 119, 0, 2, 71, 449]
+[:key_down_raw, 119, 0, 2, 72, 451]
+[:key_down_raw, 119, 0, 2, 73, 453]
+[:key_down_raw, 119, 0, 2, 74, 455]
+[:key_down_raw, 119, 0, 2, 75, 457]
+[:key_down_raw, 119, 0, 2, 76, 459]
+[:key_down_raw, 119, 0, 2, 77, 460]
+[:key_down_raw, 119, 0, 2, 78, 462]
+[:key_down_raw, 119, 0, 2, 79, 464]
+[:key_down_raw, 119, 0, 2, 80, 467]
+[:key_down_raw, 119, 0, 2, 81, 468]
+[:key_down_raw, 119, 0, 2, 82, 471]
+[:key_down_raw, 119, 0, 2, 83, 473]
+[:key_down_raw, 119, 0, 2, 84, 474]
+[:key_down_raw, 119, 0, 2, 85, 476]
+[:key_down_raw, 119, 0, 2, 86, 478]
+[:key_down_raw, 119, 0, 2, 87, 481]
+[:key_down_raw, 119, 0, 2, 88, 482]
+[:key_down_raw, 119, 0, 2, 89, 484]
+[:key_down_raw, 119, 0, 2, 90, 486]
+[:key_down_raw, 119, 0, 2, 91, 489]
+[:key_down_raw, 119, 0, 2, 92, 491]
+[:key_down_raw, 119, 0, 2, 93, 493]
+[:key_down_raw, 119, 0, 2, 94, 494]
+[:key_down_raw, 119, 0, 2, 95, 496]
+[:key_down_raw, 119, 0, 2, 96, 498]
+[:key_down_raw, 119, 0, 2, 97, 501]
+[:key_down_raw, 119, 0, 2, 98, 502]
+[:key_down_raw, 119, 0, 2, 99, 505]
+[:key_down_raw, 119, 0, 2, 100, 507]
+[:key_down_raw, 119, 0, 2, 101, 509]
+[:key_down_raw, 119, 0, 2, 102, 511]
+[:key_down_raw, 119, 0, 2, 103, 512]
+[:key_down_raw, 119, 0, 2, 104, 514]
+[:key_down_raw, 119, 0, 2, 105, 516]
+[:key_down_raw, 119, 0, 2, 106, 519]
+[:key_down_raw, 119, 0, 2, 107, 521]
+[:key_down_raw, 119, 0, 2, 108, 523]
+[:key_down_raw, 119, 0, 2, 109, 524]
+[:key_down_raw, 119, 0, 2, 110, 526]
+[:key_down_raw, 119, 0, 2, 111, 529]
+[:key_down_raw, 119, 0, 2, 112, 530]
+[:key_down_raw, 119, 0, 2, 113, 533]
+[:key_down_raw, 119, 0, 2, 114, 535]
+[:key_down_raw, 119, 0, 2, 115, 536]
+[:key_up_raw, 119, 0, 2, 116, 536]
+[:key_down_raw, 100, 0, 2, 117, 548]
+[:key_down_raw, 100, 0, 2, 118, 563]
+[:key_down_raw, 100, 0, 2, 119, 565]
+[:key_down_raw, 100, 0, 2, 120, 567]
+[:key_down_raw, 100, 0, 2, 121, 569]
+[:key_down_raw, 100, 0, 2, 122, 572]
+[:key_down_raw, 100, 0, 2, 123, 573]
+[:key_down_raw, 100, 0, 2, 124, 576]
+[:key_down_raw, 100, 0, 2, 125, 577]
+[:key_down_raw, 100, 0, 2, 126, 579]
+[:key_down_raw, 100, 0, 2, 127, 582]
+[:key_down_raw, 100, 0, 2, 128, 584]
+[:key_down_raw, 100, 0, 2, 129, 585]
+[:key_down_raw, 100, 0, 2, 130, 588]
+[:key_down_raw, 100, 0, 2, 131, 589]
+[:key_down_raw, 100, 0, 2, 132, 591]
+[:key_down_raw, 100, 0, 2, 133, 593]
+[:key_down_raw, 100, 0, 2, 134, 595]
+[:key_down_raw, 100, 0, 2, 135, 597]
+[:key_down_raw, 100, 0, 2, 136, 599]
+[:key_down_raw, 100, 0, 2, 137, 601]
+[:key_down_raw, 100, 0, 2, 138, 603]
+[:key_down_raw, 100, 0, 2, 139, 605]
+[:key_down_raw, 100, 0, 2, 140, 607]
+[:key_up_raw, 100, 0, 2, 141, 608]
+[:key_down_raw, 100, 0, 2, 142, 646]
+[:key_up_raw, 100, 0, 2, 143, 654]
+[:key_down_raw, 1073741906, 0, 2, 144, 696]
+[:key_down_raw, 1073741906, 0, 2, 145, 711]
+[:key_down_raw, 1073741906, 0, 2, 146, 713]
+[:key_down_raw, 1073741906, 0, 2, 147, 715]
+[:key_down_raw, 1073741906, 0, 2, 148, 717]
+[:key_down_raw, 1073741906, 0, 2, 149, 719]
+[:key_down_raw, 1073741906, 0, 2, 150, 721]
+[:key_down_raw, 1073741906, 0, 2, 151, 723]
+[:key_down_raw, 1073741906, 0, 2, 152, 725]
+[:key_down_raw, 1073741906, 0, 2, 153, 727]
+[:key_down_raw, 1073741906, 0, 2, 154, 729]
+[:key_down_raw, 1073741906, 0, 2, 155, 731]
+[:key_down_raw, 1073741906, 0, 2, 156, 733]
+[:key_down_raw, 1073741906, 0, 2, 157, 735]
+[:key_down_raw, 1073741906, 0, 2, 158, 737]
+[:key_down_raw, 1073741906, 0, 2, 159, 739]
+[:key_down_raw, 1073741906, 0, 2, 160, 741]
+[:key_down_raw, 1073741906, 0, 2, 161, 743]
+[:key_down_raw, 1073741906, 0, 2, 162, 745]
+[:key_down_raw, 1073741906, 0, 2, 163, 747]
+[:key_down_raw, 1073741906, 0, 2, 164, 749]
+[:key_down_raw, 1073741906, 0, 2, 165, 751]
+[:key_down_raw, 1073741906, 0, 2, 166, 753]
+[:key_down_raw, 1073741906, 0, 2, 167, 755]
+[:key_down_raw, 1073741906, 0, 2, 168, 757]
+[:key_down_raw, 1073741906, 0, 2, 169, 759]
+[:key_down_raw, 1073741906, 0, 2, 170, 761]
+[:key_down_raw, 1073741906, 0, 2, 171, 763]
+[:key_down_raw, 1073741906, 0, 2, 172, 765]
+[:key_down_raw, 1073741906, 0, 2, 173, 767]
+[:key_down_raw, 1073741906, 0, 2, 174, 769]
+[:key_down_raw, 1073741906, 0, 2, 175, 771]
+[:key_down_raw, 1073741906, 0, 2, 176, 773]
+[:key_down_raw, 1073741906, 0, 2, 177, 775]
+[:key_down_raw, 1073741906, 0, 2, 178, 777]
+[:key_down_raw, 1073741906, 0, 2, 179, 779]
+[:key_down_raw, 1073741906, 0, 2, 180, 781]
+[:key_down_raw, 1073741906, 0, 2, 181, 783]
+[:key_down_raw, 1073741904, 0, 2, 182, 784]
+[:key_down_raw, 1073741904, 0, 2, 183, 798]
+[:key_down_raw, 1073741904, 0, 2, 184, 800]
+[:key_down_raw, 1073741904, 0, 2, 185, 802]
+[:key_down_raw, 1073741904, 0, 2, 186, 804]
+[:key_down_raw, 1073741904, 0, 2, 187, 806]
+[:key_down_raw, 1073741904, 0, 2, 188, 810]
+[:key_down_raw, 1073741904, 0, 2, 189, 810]
+[:key_down_raw, 1073741904, 0, 2, 190, 814]
+[:key_down_raw, 1073741904, 0, 2, 191, 815]
+[:key_down_raw, 1073741904, 0, 2, 192, 818]
+[:key_down_raw, 1073741904, 0, 2, 193, 819]
+[:key_down_raw, 1073741904, 0, 2, 194, 822]
+[:key_down_raw, 1073741904, 0, 2, 195, 824]
+[:key_up_raw, 1073741906, 0, 2, 196, 824]
+[:key_down_raw, 1073741904, 0, 2, 197, 825]
+[:key_down_raw, 1073741904, 0, 2, 198, 828]
+[:key_up_raw, 1073741904, 0, 2, 199, 828]
+[:key_down_raw, 96, 0, 2, 200, 870]
+[:key_up_raw, 96, 0, 2, 201, 875]
+[:mouse_move, 802, 100, 2, 202, 933]
+[:mouse_move, 803, 100, 2, 203, 934]
+[:mouse_move, 806, 99, 2, 204, 935]
+[:mouse_move, 808, 98, 2, 205, 936]
+[:mouse_move, 813, 96, 2, 206, 937]
+[:mouse_move, 816, 95, 2, 207, 938]
+[:mouse_move, 824, 93, 2, 208, 939]
+[:mouse_move, 827, 92, 2, 209, 940]
+[:mouse_move, 837, 90, 2, 210, 941]
+[:mouse_move, 843, 90, 2, 211, 942]
+[:mouse_move, 857, 89, 2, 212, 943]
+[:mouse_move, 864, 89, 2, 213, 944]
+[:mouse_move, 874, 88, 2, 214, 945]
+[:mouse_move, 876, 88, 2, 215, 946]
+[:mouse_move, 878, 88, 2, 216, 947]
+[:mouse_move, 881, 87, 2, 217, 948]
+[:mouse_move, 882, 87, 2, 218, 950]
+[:mouse_move, 884, 87, 2, 219, 950]
+[:mouse_move, 885, 87, 2, 220, 951]
+[:mouse_move, 887, 87, 2, 221, 952]
+[:key_down_raw, 13, 0, 2, 222, 1047]
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_down_standing.png b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_down_standing.png
index 9e27489..9e27489 100644
--- a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_down_standing.png
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_down_standing.png
Binary files differ
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_left_standing.png b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_left_standing.png
index 2fea35b..2fea35b 100644
--- a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_left_standing.png
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_left_standing.png
Binary files differ
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_right_standing.png b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_right_standing.png
index 6f3402e..6f3402e 100644
--- a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_right_standing.png
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_right_standing.png
Binary files differ
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_up_standing.png b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_up_standing.png
index 9ebdca7..9ebdca7 100644
--- a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/player/player_up_standing.png
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/player/player_up_standing.png
Binary files differ
diff --git a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/rooms/camera_room.png b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/rooms/camera_room.png
index e0ca375..e0ca375 100644
--- a/samples/07_advanced_rendering/07_splitscreen_camera/sprites/rooms/camera_room.png
+++ b/samples/07_advanced_rendering/08_splitscreen_camera/sprites/rooms/camera_room.png
Binary files differ
diff --git a/samples/07_advanced_rendering/08_z_targeting_camera/app/main.rb b/samples/07_advanced_rendering/09_z_targeting_camera/app/main.rb
index ecdbfd3..ecdbfd3 100644
--- a/samples/07_advanced_rendering/08_z_targeting_camera/app/main.rb
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/app/main.rb
diff --git a/samples/07_advanced_rendering/08_z_targeting_camera/metadata/game_metadata.txt b/samples/07_advanced_rendering/09_z_targeting_camera/metadata/game_metadata.txt
index 3ad3a1a..3ad3a1a 100644
--- a/samples/07_advanced_rendering/08_z_targeting_camera/metadata/game_metadata.txt
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/metadata/game_metadata.txt
diff --git a/samples/07_advanced_rendering/08_z_targeting_camera/metadata/icon.png b/samples/07_advanced_rendering/09_z_targeting_camera/metadata/icon.png
index 57254fe..57254fe 100644
--- a/samples/07_advanced_rendering/08_z_targeting_camera/metadata/icon.png
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/metadata/icon.png
Binary files differ
diff --git a/samples/07_advanced_rendering/09_z_targeting_camera/replay.txt b/samples/07_advanced_rendering/09_z_targeting_camera/replay.txt
new file mode 100644
index 0000000..db9130a
--- /dev/null
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/replay.txt
@@ -0,0 +1,185 @@
+replay_version 2.0
+stopped_at 741
+seed 100
+recorded_at Sat Jul 17 09:24:36 2021
+[:mouse_button_up, 1, 0, 1, 1, 4]
+[:key_down_raw, 1073741906, 0, 2, 2, 104]
+[:key_down_raw, 1073741906, 0, 2, 3, 118]
+[:key_down_raw, 1073741906, 0, 2, 4, 120]
+[:key_down_raw, 1073741906, 0, 2, 5, 122]
+[:key_down_raw, 1073741906, 0, 2, 6, 124]
+[:key_down_raw, 1073741906, 0, 2, 7, 126]
+[:key_down_raw, 1073741906, 0, 2, 8, 128]
+[:key_down_raw, 1073741906, 0, 2, 9, 130]
+[:key_down_raw, 1073741906, 0, 2, 10, 132]
+[:key_down_raw, 1073741906, 0, 2, 11, 134]
+[:key_down_raw, 1073741906, 0, 2, 12, 136]
+[:key_down_raw, 1073741906, 0, 2, 13, 138]
+[:key_down_raw, 1073741906, 0, 2, 14, 140]
+[:key_down_raw, 1073741906, 0, 2, 15, 142]
+[:key_down_raw, 1073741906, 0, 2, 16, 144]
+[:key_down_raw, 1073741906, 0, 2, 17, 146]
+[:key_down_raw, 1073741906, 0, 2, 18, 148]
+[:key_down_raw, 1073741906, 0, 2, 19, 150]
+[:key_down_raw, 1073741906, 0, 2, 20, 152]
+[:key_down_raw, 1073741906, 0, 2, 21, 154]
+[:key_up_raw, 1073741906, 0, 2, 22, 156]
+[:key_down_raw, 1073741904, 0, 2, 23, 165]
+[:key_down_raw, 1073741904, 0, 2, 24, 180]
+[:key_down_raw, 1073741904, 0, 2, 25, 182]
+[:key_down_raw, 1073741904, 0, 2, 26, 184]
+[:key_down_raw, 1073741904, 0, 2, 27, 186]
+[:key_down_raw, 1073741904, 0, 2, 28, 188]
+[:key_down_raw, 1073741904, 0, 2, 29, 190]
+[:key_down_raw, 1073741904, 0, 2, 30, 192]
+[:key_down_raw, 1073741904, 0, 2, 31, 194]
+[:key_down_raw, 1073741904, 0, 2, 32, 196]
+[:key_down_raw, 1073741904, 0, 2, 33, 198]
+[:key_down_raw, 1073741904, 0, 2, 34, 200]
+[:key_down_raw, 1073741904, 0, 2, 35, 202]
+[:key_down_raw, 1073741904, 0, 2, 36, 204]
+[:key_down_raw, 1073741904, 0, 2, 37, 206]
+[:key_down_raw, 1073741904, 0, 2, 38, 208]
+[:key_down_raw, 1073741904, 0, 2, 39, 210]
+[:key_down_raw, 1073741904, 0, 2, 40, 212]
+[:key_down_raw, 1073741904, 0, 2, 41, 214]
+[:key_down_raw, 1073741904, 0, 2, 42, 216]
+[:key_down_raw, 1073741904, 0, 2, 43, 218]
+[:key_down_raw, 1073741904, 0, 2, 44, 220]
+[:key_down_raw, 1073741904, 0, 2, 45, 222]
+[:key_down_raw, 1073741904, 0, 2, 46, 224]
+[:key_down_raw, 1073741904, 0, 2, 47, 226]
+[:key_down_raw, 1073741904, 0, 2, 48, 228]
+[:key_down_raw, 1073741904, 0, 2, 49, 230]
+[:key_down_raw, 1073741904, 0, 2, 50, 232]
+[:key_down_raw, 1073741904, 0, 2, 51, 234]
+[:key_down_raw, 1073741904, 0, 2, 52, 236]
+[:key_down_raw, 1073741904, 0, 2, 53, 238]
+[:key_down_raw, 1073741904, 0, 2, 54, 240]
+[:key_down_raw, 1073741904, 0, 2, 55, 242]
+[:key_down_raw, 1073741904, 0, 2, 56, 244]
+[:key_down_raw, 1073741904, 0, 2, 57, 246]
+[:key_down_raw, 1073741904, 0, 2, 58, 248]
+[:key_down_raw, 1073741904, 0, 2, 59, 250]
+[:key_down_raw, 1073741904, 0, 2, 60, 252]
+[:key_down_raw, 1073741904, 0, 2, 61, 254]
+[:key_down_raw, 1073741906, 0, 2, 62, 256]
+[:key_down_raw, 1073741906, 0, 2, 63, 271]
+[:key_down_raw, 1073741906, 0, 2, 64, 273]
+[:key_down_raw, 1073741906, 0, 2, 65, 275]
+[:key_down_raw, 1073741906, 0, 2, 66, 277]
+[:key_down_raw, 1073741906, 0, 2, 67, 279]
+[:key_down_raw, 1073741906, 0, 2, 68, 281]
+[:key_down_raw, 1073741906, 0, 2, 69, 283]
+[:key_down_raw, 1073741906, 0, 2, 70, 285]
+[:key_down_raw, 1073741906, 0, 2, 71, 287]
+[:key_down_raw, 1073741906, 0, 2, 72, 289]
+[:key_down_raw, 1073741906, 0, 2, 73, 291]
+[:key_down_raw, 1073741906, 0, 2, 74, 293]
+[:key_down_raw, 1073741906, 0, 2, 75, 295]
+[:key_down_raw, 1073741906, 0, 2, 76, 297]
+[:key_down_raw, 1073741906, 0, 2, 77, 299]
+[:key_down_raw, 1073741906, 0, 2, 78, 301]
+[:key_down_raw, 1073741906, 0, 2, 79, 303]
+[:key_down_raw, 1073741906, 0, 2, 80, 305]
+[:key_down_raw, 1073741906, 0, 2, 81, 307]
+[:key_down_raw, 1073741906, 0, 2, 82, 309]
+[:key_down_raw, 1073741906, 0, 2, 83, 311]
+[:key_down_raw, 1073741906, 0, 2, 84, 313]
+[:key_up_raw, 1073741906, 0, 2, 85, 314]
+[:key_up_raw, 1073741904, 0, 2, 86, 316]
+[:key_down_raw, 1073741903, 0, 2, 87, 338]
+[:key_down_raw, 1073741903, 0, 2, 88, 353]
+[:key_down_raw, 1073741903, 0, 2, 89, 355]
+[:key_down_raw, 1073741903, 0, 2, 90, 357]
+[:key_down_raw, 1073741903, 0, 2, 91, 359]
+[:key_down_raw, 1073741903, 0, 2, 92, 361]
+[:key_down_raw, 1073741903, 0, 2, 93, 363]
+[:key_down_raw, 1073741903, 0, 2, 94, 365]
+[:key_down_raw, 1073741903, 0, 2, 95, 367]
+[:key_down_raw, 1073741903, 0, 2, 96, 369]
+[:key_down_raw, 1073741903, 0, 2, 97, 371]
+[:key_down_raw, 1073741903, 0, 2, 98, 373]
+[:key_down_raw, 1073741903, 0, 2, 99, 375]
+[:key_down_raw, 1073741903, 0, 2, 100, 377]
+[:key_down_raw, 1073741903, 0, 2, 101, 379]
+[:key_down_raw, 1073741903, 0, 2, 102, 381]
+[:key_down_raw, 1073741905, 0, 2, 103, 382]
+[:key_down_raw, 1073741905, 0, 2, 104, 397]
+[:key_down_raw, 1073741905, 0, 2, 105, 399]
+[:key_down_raw, 1073741905, 0, 2, 106, 401]
+[:key_down_raw, 1073741905, 0, 2, 107, 403]
+[:key_down_raw, 1073741905, 0, 2, 108, 405]
+[:key_down_raw, 1073741905, 0, 2, 109, 407]
+[:key_down_raw, 1073741905, 0, 2, 110, 409]
+[:key_down_raw, 1073741905, 0, 2, 111, 411]
+[:key_down_raw, 1073741905, 0, 2, 112, 413]
+[:key_down_raw, 1073741905, 0, 2, 113, 415]
+[:key_down_raw, 1073741905, 0, 2, 114, 417]
+[:key_down_raw, 1073741905, 0, 2, 115, 419]
+[:key_down_raw, 1073741905, 0, 2, 116, 421]
+[:key_down_raw, 1073741905, 0, 2, 117, 423]
+[:key_down_raw, 1073741905, 0, 2, 118, 425]
+[:key_down_raw, 1073741905, 0, 2, 119, 427]
+[:key_down_raw, 1073741905, 0, 2, 120, 429]
+[:key_down_raw, 1073741905, 0, 2, 121, 431]
+[:key_down_raw, 1073741905, 0, 2, 122, 433]
+[:key_up_raw, 1073741905, 0, 2, 123, 435]
+[:key_down_raw, 1073741905, 0, 2, 124, 447]
+[:key_up_raw, 1073741905, 0, 2, 125, 460]
+[:key_down_raw, 1073741905, 0, 2, 126, 485]
+[:key_down_raw, 1073741905, 0, 2, 127, 500]
+[:key_down_raw, 1073741905, 0, 2, 128, 502]
+[:key_down_raw, 1073741905, 0, 2, 129, 504]
+[:key_down_raw, 1073741905, 0, 2, 130, 506]
+[:key_up_raw, 1073741905, 0, 2, 131, 507]
+[:key_up_raw, 1073741903, 0, 2, 132, 548]
+[:key_down_raw, 1073741905, 0, 2, 133, 561]
+[:key_down_raw, 1073741905, 0, 2, 134, 576]
+[:key_down_raw, 1073741905, 0, 2, 135, 578]
+[:key_down_raw, 1073741905, 0, 2, 136, 580]
+[:key_down_raw, 1073741905, 0, 2, 137, 582]
+[:key_up_raw, 1073741905, 0, 2, 138, 584]
+[:key_down_raw, 96, 0, 2, 139, 648]
+[:key_up_raw, 96, 0, 2, 140, 653]
+[:mouse_move, 815, 98, 2, 141, 654]
+[:mouse_move, 816, 101, 2, 142, 655]
+[:mouse_move, 816, 104, 2, 143, 656]
+[:mouse_move, 816, 112, 2, 144, 657]
+[:mouse_move, 816, 117, 2, 145, 658]
+[:mouse_move, 810, 130, 2, 146, 659]
+[:mouse_move, 803, 137, 2, 147, 660]
+[:mouse_move, 782, 157, 2, 148, 661]
+[:mouse_move, 767, 168, 2, 149, 662]
+[:mouse_move, 734, 188, 2, 150, 663]
+[:mouse_move, 716, 197, 2, 151, 664]
+[:mouse_move, 682, 215, 2, 152, 665]
+[:mouse_move, 665, 223, 2, 153, 666]
+[:mouse_move, 645, 234, 2, 154, 667]
+[:mouse_move, 643, 235, 2, 155, 668]
+[:mouse_move, 643, 236, 2, 156, 669]
+[:mouse_move, 647, 237, 2, 157, 672]
+[:mouse_move, 670, 244, 2, 158, 673]
+[:mouse_move, 687, 245, 2, 159, 674]
+[:mouse_move, 720, 242, 2, 160, 675]
+[:mouse_move, 737, 237, 2, 161, 676]
+[:mouse_move, 764, 224, 2, 162, 677]
+[:mouse_move, 777, 216, 2, 163, 678]
+[:mouse_move, 796, 197, 2, 164, 679]
+[:mouse_move, 804, 187, 2, 165, 680]
+[:mouse_move, 815, 164, 2, 166, 681]
+[:mouse_move, 820, 152, 2, 167, 682]
+[:mouse_move, 825, 142, 2, 168, 683]
+[:mouse_move, 831, 128, 2, 169, 684]
+[:mouse_move, 832, 126, 2, 170, 685]
+[:mouse_move, 832, 125, 2, 171, 686]
+[:mouse_move, 833, 123, 2, 172, 688]
+[:mouse_move, 836, 120, 2, 173, 690]
+[:mouse_move, 837, 118, 2, 174, 691]
+[:mouse_move, 842, 113, 2, 175, 692]
+[:mouse_move, 844, 112, 2, 176, 693]
+[:mouse_move, 844, 111, 2, 177, 694]
+[:mouse_move, 844, 110, 2, 178, 696]
+[:mouse_move, 845, 110, 2, 179, 697]
+[:mouse_move, 845, 109, 2, 180, 699]
+[:key_down_raw, 13, 0, 2, 181, 741]
diff --git a/samples/07_advanced_rendering/08_z_targeting_camera/sprites/arena.png b/samples/07_advanced_rendering/09_z_targeting_camera/sprites/arena.png
index 5c92e91..5c92e91 100644
--- a/samples/07_advanced_rendering/08_z_targeting_camera/sprites/arena.png
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/sprites/arena.png
Binary files differ
diff --git a/samples/07_advanced_rendering/08_z_targeting_camera/sprites/player.png b/samples/07_advanced_rendering/09_z_targeting_camera/sprites/player.png
index 332a80b..332a80b 100644
--- a/samples/07_advanced_rendering/08_z_targeting_camera/sprites/player.png
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/sprites/player.png
Binary files differ
diff --git a/samples/07_advanced_rendering/08_z_targeting_camera/sprites/square/black.png b/samples/07_advanced_rendering/09_z_targeting_camera/sprites/square/black.png
index cea7bd7..cea7bd7 100644
--- a/samples/07_advanced_rendering/08_z_targeting_camera/sprites/square/black.png
+++ b/samples/07_advanced_rendering/09_z_targeting_camera/sprites/square/black.png
Binary files differ
diff --git a/samples/07_advanced_rendering/10_blend_modes/app/main.rb b/samples/07_advanced_rendering/10_blend_modes/app/main.rb
new file mode 100644
index 0000000..7e28ba8
--- /dev/null
+++ b/samples/07_advanced_rendering/10_blend_modes/app/main.rb
@@ -0,0 +1,49 @@
+$gtk.reset
+
+def draw_blendmode args, mode
+ w = 160
+ h = w
+ args.state.x += (1280-w) / (args.state.blendmodes.length + 1)
+ x = args.state.x
+ y = (720 - h) / 2
+ s = 'sprites/blue-feathered.png'
+ args.outputs.sprites << { blendmode_enum: mode.value, x: x, y: y, w: w, h: h, path: s }
+ args.outputs.labels << [x + (w/2), y, mode.name.to_s, 1, 1, 255, 255, 255]
+end
+
+def tick args
+
+ # Different blend modes do different things, depending on what they
+ # blend against (in this case, the pixels of the background color).
+ args.state.bg_element ||= 1
+ args.state.bg_color ||= 255
+ args.state.bg_color_direction ||= 1
+ bg_r = (args.state.bg_element == 1) ? args.state.bg_color : 0
+ bg_g = (args.state.bg_element == 2) ? args.state.bg_color : 0
+ bg_b = (args.state.bg_element == 3) ? args.state.bg_color : 0
+ args.state.bg_color += args.state.bg_color_direction
+ if (args.state.bg_color_direction > 0) && (args.state.bg_color >= 255)
+ args.state.bg_color_direction = -1
+ args.state.bg_color = 255
+ elsif (args.state.bg_color_direction < 0) && (args.state.bg_color <= 0)
+ args.state.bg_color_direction = 1
+ args.state.bg_color = 0
+ args.state.bg_element += 1
+ if args.state.bg_element >= 4
+ args.state.bg_element = 1
+ end
+ end
+
+ args.outputs.background_color = [ bg_r, bg_g, bg_b, 255 ]
+
+ args.state.blendmodes ||= [
+ { name: :none, value: 0 },
+ { name: :blend, value: 1 },
+ { name: :add, value: 2 },
+ { name: :mod, value: 3 },
+ { name: :mul, value: 4 }
+ ]
+
+ args.state.x = 0 # reset this, draw_blendmode will increment it.
+ args.state.blendmodes.each { |blendmode| draw_blendmode args, blendmode }
+end
diff --git a/samples/07_advanced_rendering/10_blend_modes/sprites/blue-feathered.png b/samples/07_advanced_rendering/10_blend_modes/sprites/blue-feathered.png
new file mode 100644
index 0000000..a8bf6b5
--- /dev/null
+++ b/samples/07_advanced_rendering/10_blend_modes/sprites/blue-feathered.png
Binary files differ