luz_performer.rb
#
# LuzPerformer connects a basic SDLApplication with the Luz $engine and $gui
#
# (This is the only file that should need to change when switching SDL to an alternative.)
#
class LuzPerformer < SDLApplication
SDL_TO_LUZ_BUTTON_NAMES = {'`' => 'Grave', '\\' => 'Backslash', '[' => 'Left Bracket', ']' => 'Right Bracket', ';' => 'Semicolon', "'" => 'Apostrophe', '/' => 'Slash', '.' => 'Period', ',' => 'Comma', '-' => 'Minus', '=' => 'Equal', 'Left Ctrl' => 'Left Control', 'Right Ctrl' => 'Right Control'}
SHIFT_LOOKUP = {'/' => '?', "'" => '"', ';' => ':', ',' => '<', '.' => '>', '=' => '+', '-' => '_', '1' => '!', '2' => '@', '3' => '#', '4' => '$', '5' => '%', '6' => '^', '7' => '&', '8' => '*', '9' => '(', '0' => ')', '[' => '{', ']' => '}'}
# (hacks for reduced garbage / better performance)
MOUSE_1_X = "Mouse 01 / X"
MOUSE_1_Y = "Mouse 01 / Y"
MOUSE_BUTTON_FORMAT = "Mouse %02d / Button %02d"
MOUSE_1_BUTTON_FORMATTER = Hash.new { |hash, key| hash[key] = sprintf(MOUSE_BUTTON_FORMAT, 1, key) }
def reload_code!
change_count = $engine.reload
$gui.reload_notify
if change_count > 0
$gui.positive_message "Reloaded #{change_count.plural('file', 'files')}."
else
$gui.positive_message "No modified source files found."
end
end
def open_project(project_path)
@switch_to_project_path = project_path
end
# public API is in baseclass
def parse_command_line_options
command_line_options.parse!
end
private
def command_line_options
OptionParser.new do |opts|
opts.banner = "Usage: luz.rb [options] [project.luz]"
opts.on("--width <width>", Integer, "Resolution width (eg. 800)") do |w|
self.width = w
end
opts.on("--height <height>", Integer, "Resolution height (eg. 600)") do |h|
self.height = h
end
opts.on("--bits-per-pixel <bpp>", Integer, "Bits per pixel (8, 16, 24, 32)") do |bpp|
self.bits_per_pixel = bpp
end
opts.on("--frames-per-second <fps>", Integer, "Target FPS") do |fps|
self.frames_per_second = fps.to_i
end
opts.on("--fullscreen", "Fullscreen") do
self.fullscreen = true
end
opts.on("--window", "Window") do
self.fullscreen = false
end
opts.on("--system-mouse", "System Mouse") do
self.system_mouse = true
end
opts.on("--sprite-mouse", "Sprite Mouse") do
self.system_mouse = false
end
opts.on("--output-window", "Output Window on 2nd Display") do
self.use_output_window = true
end
opts.on("--borderless", "Borderless") do
self.border = false
end
end
end
def do_frame(time)
$engine.do_frame(time)
$engine.load_from_path(@switch_to_project_path) if @switch_to_project_path
@switch_to_project_path = nil
end
def handle_sdl_event(event)
case event
# Mouse input
when SDL2::Event::MouseMotion
$engine.on_slider_change(MOUSE_1_X, (event.x / (@width - 1).to_f))
$engine.on_slider_change(MOUSE_1_Y, (1.0 - (event.y / (@height - 1).to_f)))
when SDL2::Event::MouseButtonDown
$engine.on_button_down(MOUSE_1_BUTTON_FORMATTER[event.button], frame_offset=1)
when SDL2::Event::MouseButtonUp
$engine.on_button_up(MOUSE_1_BUTTON_FORMATTER[event.button], frame_offset=1)
when SDL2::Event::MouseWheel
if event.y == 1
$engine.on_button_down(sprintf("Mouse %02d / Button 04", event.which + 1), 1) # last 1 is frame_offset: use it on the coming frame
elsif event.y == -1
$engine.on_button_down(sprintf("Mouse %02d / Button 05", event.which + 1), 1) # last 1 is frame_offset: use it on the coming frame
else
puts "unhandled mouse wheel event: #{event}"
end
# Keyboard input
when SDL2::Event::KeyDown
key_name = SDL2::Key.name_of(event.sym)
button_name = sdl_to_luz_button_name(key_name)
$engine.on_button_down(button_name, 1) # 1 is frame_offset: use it on the coming frame
$gui.raw_key_down(sdl_to_gui_key(key_name, event))
when SDL2::Event::KeyUp
key_name = SDL2::Key.name_of(event.sym)
button_name = sdl_to_luz_button_name(key_name)
$engine.on_button_up(button_name, 1) # 1 is frame_offset: use it on the coming frame
$gui.raw_key_up(sdl_to_gui_key(key_name, event))
when SDL2::Event::Quit
finished!
end
end
def sdl_to_luz_button_name(name)
@sdl_to_luz_button_names ||= Hash.new { |hash, key| hash[key] = sprintf('Keyboard / %s', SDL_TO_LUZ_BUTTON_NAMES[key] || key.humanize) }
@sdl_to_luz_button_names[name]
end
def sdl_to_gui_key(key_name, sdl_event) # actually decorates the existing String ;P
key_name.downcase!
key_name.shift = ((sdl_event.mod & SDL2::Key::Mod::SHIFT) > 0)
key_name.control = ((sdl_event.mod & SDL2::Key::Mod::CTRL) > 0)
key_name.alt = ((sdl_event.mod & SDL2::Key::Mod::ALT) > 0)
key_name.shifted = shift_key(key_name) if key_name.shift?
key_name
end
def shift_key(key_name)
SHIFT_LOOKUP[key_name] || key_name.upcase
end
def after_run(seconds)
puts sprintf('%d frames in %0.1f seconds = %dfps (~%dfps render loop)', $env[:frame_number], seconds, $env[:frame_number] / seconds, 1.0 / $engine.average_frame_time)
end
end