mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 15:42:35 +00:00
Fixed some warnings, moved Subcommand into its own file, added support for subcommand and subcommand options autocomplete in Console, added texture ids to Model vertex buffer object
This commit is contained in:
@@ -23,13 +23,13 @@ when :OPENGL_PLATFORM_MACOSX
|
||||
when :OPENGL_PLATFORM_LINUX
|
||||
gl_library_path = nil
|
||||
|
||||
if File.exists?("/usr/lib/x86_64-linux-gnu/libGL.so") # Ubuntu (Debian)
|
||||
if File.exist?("/usr/lib/x86_64-linux-gnu/libGL.so") # Ubuntu (Debian)
|
||||
gl_library_path = "/usr/lib/x86_64-linux-gnu"
|
||||
|
||||
elsif File.exists?("/usr/lib/libGL.so") # Manjaro (ARCH)
|
||||
elsif File.exist?("/usr/lib/libGL.so") # Manjaro (ARCH)
|
||||
gl_library_path = "/usr/lib"
|
||||
|
||||
elsif File.exists?("/usr/lib/arm-linux-gnueabihf/libGL.so") # Raspbian (ARM/Raspberry Pi)
|
||||
elsif File.exist?("/usr/lib/arm-linux-gnueabihf/libGL.so") # Raspbian (ARM/Raspberry Pi)
|
||||
gl_library_path = "/usr/lib/arm-linux-gnueabihf"
|
||||
end
|
||||
|
||||
@@ -86,6 +86,7 @@ require_relative "lib/states/game_state"
|
||||
require_relative "lib/ui/menu"
|
||||
|
||||
require_relative "lib/ui/command"
|
||||
require_relative "lib/ui/subcommand"
|
||||
Dir.glob("#{IMICFPS::GAME_ROOT_PATH}/lib/ui/commands/*.rb").each do |cmd|
|
||||
require_relative cmd
|
||||
end
|
||||
|
||||
@@ -7,15 +7,13 @@ class IMICFPS
|
||||
|
||||
def window; $window; end
|
||||
|
||||
def delta_time
|
||||
(Gosu.milliseconds-@delta_time)/1000.0
|
||||
end
|
||||
def delta_time; (Gosu.milliseconds - @delta_time) / 1000.0; end
|
||||
def button_down?(id); window.button_down?(id); end
|
||||
|
||||
def mouse_x; window.mouse_x; end
|
||||
def mouse_y; window.mouse_y; end
|
||||
def mouse_x=int; window.mouse_x=int; end
|
||||
def mouse_y=int; window.mouse_y=int; end
|
||||
def mouse_x=(int); window.mouse_x = int; end
|
||||
def mouse_y=(int); window.mouse_y = int; end
|
||||
|
||||
def gl(&block)
|
||||
window.gl do
|
||||
@@ -31,6 +29,10 @@ class IMICFPS
|
||||
return string
|
||||
end
|
||||
|
||||
def control_down?; button_down?(Gosu::KbLeftControl) || button_down?(Gosu::KbRightControl); end
|
||||
def shift_down?; button_down?(Gosu::KbLeftShift) || button_down?(Gosu::KbRightShift); end
|
||||
def alt_down?; button_down?(Gosu::KbLeftAlt) || button_down?(Gosu::KbRightAlt); end
|
||||
|
||||
def draw_rect(*args)
|
||||
window.draw_rect(*args)
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ class IMICFPS
|
||||
query = @@keymap.dig(id_or_action)
|
||||
|
||||
if query.is_a?(Integer)
|
||||
id = query
|
||||
query
|
||||
elsif query.is_a?(Array)
|
||||
query.each do |key|
|
||||
@@keys[key] = true
|
||||
@@ -28,7 +28,7 @@ class IMICFPS
|
||||
query = @@keymap.dig(id_or_action)
|
||||
|
||||
if query.is_a?(Integer)
|
||||
id = query
|
||||
query
|
||||
elsif query.is_a?(Array)
|
||||
query.each do |key|
|
||||
@@keys[key] = false
|
||||
@@ -40,7 +40,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def self.get(action)
|
||||
key = @@keymap.dig(action)
|
||||
@@keymap.dig(action)
|
||||
end
|
||||
|
||||
def self.set(action, key)
|
||||
|
||||
@@ -9,7 +9,7 @@ class IMICFPS
|
||||
|
||||
attr_accessor :scale, :visible, :renderable, :backface_culling
|
||||
attr_accessor :position, :rotation, :velocity
|
||||
attr_reader :model, :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag
|
||||
attr_reader :name, :debug_color, :bounding_box, :collision, :physics, :mass, :drag
|
||||
|
||||
def initialize(x: 0, y: 0, z: 0, bound_model: nil, scale: MODEL_METER_SCALE, backface_culling: true, auto_manage: true, manifest_file: nil)
|
||||
@position = Vector.new(x, y, z)
|
||||
@@ -42,7 +42,7 @@ class IMICFPS
|
||||
@bound_model.model.objects.each { |o| o.scale = self.scale }
|
||||
@normalized_bounding_box = normalize_bounding_box_with_offset
|
||||
|
||||
box = normalize_bounding_box
|
||||
normalize_bounding_box
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
@@ -86,6 +86,41 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def autocomplete(console)
|
||||
split = console.text_input.text.split(" ")
|
||||
|
||||
if @subcommands.size > 0
|
||||
if !console.text_input.text.end_with?(" ") && split.size == 2
|
||||
list = console.abbrev_search(@subcommands.map { |cmd| cmd.command.to_s}, split.last)
|
||||
|
||||
if list.size == 1
|
||||
console.text_input.text = "#{split.first} #{list.first} "
|
||||
else
|
||||
return unless list.size > 0
|
||||
console.stdin("#{list.map { |cmd| Commands::Style.highlight(cmd)}.join(", ")}")
|
||||
end
|
||||
|
||||
# List available options on subcommand
|
||||
elsif (console.text_input.text.end_with?(" ") && split.size == 2) || !console.text_input.text.end_with?(" ") && split.size == 3
|
||||
subcommand = @subcommands.detect { |cmd| cmd.command.to_s == (split[1]) }
|
||||
|
||||
if subcommand
|
||||
if split.size == 2
|
||||
console.stdin("Available options: #{subcommand.values.map { |value| Commands::Style.highlight(value) }.join(",")}")
|
||||
else
|
||||
list = console.abbrev_search(subcommand.values, split.last)
|
||||
if list.size == 1
|
||||
console.text_input.text = "#{split.first} #{split[1]} #{list.first} "
|
||||
else
|
||||
console.stdin("Available options: #{list.map { |value| Commands::Style.highlight(value) }.join(",")}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# List available subcommands if command was entered and has only a space after it
|
||||
elsif console.text_input.text.end_with?(" ") && split.size == 1
|
||||
console.stdin("Available subcommands: #{@subcommands.map { |cmd| Commands::Style.highlight(cmd.command)}.join(", ")}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def handle_subcommand(arguments, console)
|
||||
@@ -107,91 +142,5 @@ class IMICFPS
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
|
||||
class SubCommand
|
||||
def initialize(parent, command, type)
|
||||
@parent = parent
|
||||
@command = command
|
||||
@type = type
|
||||
end
|
||||
|
||||
def command
|
||||
@command
|
||||
end
|
||||
|
||||
def handle(arguments, console)
|
||||
if arguments.size > 1
|
||||
console.stdin("to many arguments for #{Style.highlight("#{command}")}, got #{Style.error(arguments.size)} expected #{Style.notice(1)}.")
|
||||
return
|
||||
end
|
||||
|
||||
case @type
|
||||
when :boolean
|
||||
case arguments.last
|
||||
when "", nil
|
||||
var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : false
|
||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
||||
when "on"
|
||||
var = @parent.set(command.to_sym, true)
|
||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
||||
when "off"
|
||||
var = @parent.set(command.to_sym, false)
|
||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
||||
else
|
||||
console.stdin("Invalid argument for #{Style.highlight("#{command}")}, got #{Style.error(arguments.last)} expected #{Style.notice("on")}, or #{Style.notice("off")}.")
|
||||
end
|
||||
when :string
|
||||
case arguments.last
|
||||
when "", nil
|
||||
var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "\"\""
|
||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
||||
else
|
||||
var = @parent.set(command.to_sym, arguments.last)
|
||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
||||
end
|
||||
when :integer
|
||||
case arguments.last
|
||||
when "", nil
|
||||
var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "nil"
|
||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
||||
else
|
||||
begin
|
||||
var = @parent.set(command.to_sym, Integer(arguments.last))
|
||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
||||
rescue ArgumentError
|
||||
console.stdin("Error: #{Style.error("Expected an integer, got '#{arguments.last}'")}")
|
||||
end
|
||||
end
|
||||
when :decimal
|
||||
case arguments.last
|
||||
when "", nil
|
||||
var = @parent.get(command.to_sym) ? @parent.get(command.to_sym) : "nil"
|
||||
console.stdin("#{command}: #{Style.highlight(var)}")
|
||||
else
|
||||
begin
|
||||
var = @parent.set(command.to_sym, Float(arguments.last))
|
||||
console.stdin("#{command} => #{Style.highlight(var)}")
|
||||
rescue ArgumentError
|
||||
console.stdin("Error: #{Style.error("Expected a decimal or integer, got '#{arguments.last}'")}")
|
||||
end
|
||||
end
|
||||
else
|
||||
raise RuntimeError
|
||||
end
|
||||
end
|
||||
|
||||
def usage
|
||||
case @type
|
||||
when :boolean
|
||||
"#{Style.highlight(command)} #{Style.notice("[on|off]")}"
|
||||
when :string
|
||||
"#{Style.highlight(command)} #{Style.notice("[string]")}"
|
||||
when :integer
|
||||
"#{Style.highlight(command)} #{Style.notice("[0]")}"
|
||||
when :decimal
|
||||
"#{Style.highlight(command)} #{Style.notice("[0.0]")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -29,7 +29,7 @@ class IMICFPS
|
||||
end
|
||||
|
||||
def usage
|
||||
string = "debug\n #{@subcommands.map { |sub| sub.usage }.join("\n ")}"
|
||||
"debug\n #{@subcommands.map { |sub| sub.usage }.join("\n ")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@ class IMICFPS
|
||||
PADDING = 2
|
||||
include CommonMethods
|
||||
|
||||
attr_reader :text_input
|
||||
def initialize
|
||||
@text_input = Gosu::TextInput.new
|
||||
|
||||
@@ -12,11 +13,13 @@ class IMICFPS
|
||||
|
||||
@history_height = window.height / 4 * 3 - (PADDING * 2 + @input.textobject.height)
|
||||
@history = Text.new("=== #{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME}) ===\n\n", x: 4, y: @history_height, z: Console::Z + 1)
|
||||
update_history
|
||||
update_history_y
|
||||
|
||||
@command_history = []
|
||||
@command_history_index = 0
|
||||
|
||||
@memory = ""
|
||||
|
||||
@background_color = Gosu::Color.rgba(0, 0, 0, 200)
|
||||
@foreground_color = Gosu::Color.rgba(100, 100, 100, 100)
|
||||
@input_color = Gosu::Color.rgba(100, 100, 100, 200)
|
||||
@@ -28,6 +31,7 @@ class IMICFPS
|
||||
@caret_last_change = Gosu.milliseconds
|
||||
@caret_interval = 250
|
||||
@caret_color = Gosu::Color::WHITE
|
||||
@selection_color = Gosu::Color.new(0x5522ff22)
|
||||
|
||||
@width = window.width / 4 * 3
|
||||
@height = window.height / 4 * 3
|
||||
@@ -44,12 +48,36 @@ class IMICFPS
|
||||
@history.draw
|
||||
@input.draw
|
||||
# Caret
|
||||
draw_rect(@input.x + caret_pos, @input.y, Console::PADDING, @input.height, @caret_color, Console::Z + 2) if @show_caret
|
||||
draw_rect(@input.x + caret_from_left, @input.y, Console::PADDING, @input.height, @caret_color, Console::Z + 2) if @show_caret
|
||||
# Caret selection
|
||||
if caret_start != caret_end
|
||||
if caret_start < @text_input.selection_start
|
||||
draw_rect(@input.x + caret_from_left, @input.y, caret_selection_width, @input.height, @selection_color, Console::Z)
|
||||
else
|
||||
draw_rect((@input.x + caret_from_left) - caret_selection_width, @input.y, caret_selection_width, @input.height, @selection_color, Console::Z)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def caret_from_left
|
||||
return 0 if @text_input.caret_pos == 0
|
||||
@input.textobject.text_width(@text_input.text[0..@text_input.caret_pos-1])
|
||||
end
|
||||
|
||||
def caret_selection_width
|
||||
@input.textobject.text_width(@text_input.text[caret_start..(caret_end - 1)])
|
||||
end
|
||||
|
||||
def caret_pos
|
||||
return 0 if @text_input.caret_pos == 0
|
||||
@input.textobject.text_width(@text_input.text[0..@text_input.caret_pos-1])
|
||||
@text_input.caret_pos
|
||||
end
|
||||
|
||||
def caret_start
|
||||
@text_input.selection_start < @text_input.caret_pos ? @text_input.selection_start : @text_input.caret_pos
|
||||
end
|
||||
|
||||
def caret_end
|
||||
@text_input.selection_start > @text_input.caret_pos ? @text_input.selection_start : @text_input.caret_pos
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -68,7 +96,7 @@ class IMICFPS
|
||||
@history.text += "\n<c=999999>> #{@text_input.text}</c>"
|
||||
@command_history << @text_input.text
|
||||
@command_history_index = @command_history.size
|
||||
update_history
|
||||
update_history_y
|
||||
handle_command
|
||||
@text_input.text = ""
|
||||
|
||||
@@ -90,13 +118,12 @@ class IMICFPS
|
||||
split = @text_input.text.split(" ")
|
||||
|
||||
if !@text_input.text.end_with?(" ") && split.size == 1
|
||||
list = command_search(@text_input.text)
|
||||
list = abbrev_search(Commands::Command.list_commands.map { |cmd| cmd.command.to_s}, @text_input.text)
|
||||
|
||||
if list.size == 1
|
||||
@text_input.text = "#{list.first} "
|
||||
else
|
||||
@history.text += "\n#{list.map { |cmd| Commands::Style.highlight(cmd)}.join(", ")}"
|
||||
update_history
|
||||
stdin("\n#{list.map { |cmd| Commands::Style.highlight(cmd)}.join(", ")}")
|
||||
end
|
||||
else
|
||||
if split.size > 0 && cmd = Commands::Command.find(split.first)
|
||||
@@ -105,19 +132,64 @@ class IMICFPS
|
||||
end
|
||||
|
||||
when Gosu::KbBacktick
|
||||
# Removed backtick character from input
|
||||
# Remove backtick character from input
|
||||
if @text_input.text.size > 1
|
||||
@text_input.text = @text_input.text[0..@text_input.text.size - 2]
|
||||
else
|
||||
@text_input.text = ""
|
||||
end
|
||||
|
||||
# Copy
|
||||
when Gosu::KbC
|
||||
if control_down? && shift_down?
|
||||
@memory = @text_input.text[caret_start..caret_end - 1] if caret_start != caret_end
|
||||
p @memory
|
||||
elsif control_down?
|
||||
@text_input.text = ""
|
||||
end
|
||||
|
||||
# Paste
|
||||
when Gosu::KbV
|
||||
if control_down? && shift_down?
|
||||
string = @text_input.text.chars.insert(caret_pos, @memory).join
|
||||
_caret_pos = caret_pos
|
||||
@text_input.text = string
|
||||
@text_input.caret_pos = _caret_pos + @memory.length
|
||||
@text_input.selection_start = _caret_pos + @memory.length
|
||||
end
|
||||
|
||||
# Cut
|
||||
when Gosu::KbX
|
||||
if control_down? && shift_down?
|
||||
@memory = @text_input.text[caret_start..caret_end - 1] if caret_start != caret_end
|
||||
string = @text_input.text.chars
|
||||
Array(caret_start..caret_end - 1).each_with_index do |i, j|
|
||||
string.delete_at(i - j)
|
||||
end
|
||||
|
||||
@text_input.text = string.join
|
||||
end
|
||||
|
||||
# Delete word to left of caret
|
||||
when Gosu::KbW
|
||||
if control_down?
|
||||
split = @text_input.text.split(" ")
|
||||
split.delete(split.last)
|
||||
@text_input.text = split.join(" ")
|
||||
end
|
||||
|
||||
# Clear history
|
||||
when Gosu::KbL
|
||||
if control_down?
|
||||
@history.text = ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
end
|
||||
|
||||
def update_history
|
||||
def update_history_y
|
||||
@history.y = @history_height - (@history.text.lines.count * (@history.textobject.height))
|
||||
end
|
||||
|
||||
@@ -130,13 +202,11 @@ class IMICFPS
|
||||
IMICFPS::Commands::Command.use(command, arguments, self)
|
||||
end
|
||||
|
||||
def command_search(text)
|
||||
def abbrev_search(array, text)
|
||||
return [] unless text.length > 0
|
||||
|
||||
@command_search ||= Abbrev.abbrev(Commands::Command.list_commands.map { |cmd| cmd.command.to_s})
|
||||
|
||||
list = []
|
||||
@command_search.each do |abbrev, value|
|
||||
Abbrev.abbrev(array).each do |abbrev, value|
|
||||
next unless abbrev && abbrev.start_with?(text)
|
||||
|
||||
list << value
|
||||
@@ -147,7 +217,7 @@ class IMICFPS
|
||||
|
||||
def stdin(string)
|
||||
@history.text += "\n#{string}"
|
||||
update_history
|
||||
update_history_y
|
||||
end
|
||||
|
||||
def focus
|
||||
|
||||
@@ -3,7 +3,7 @@ class IMICFPS
|
||||
class Material
|
||||
include OpenGL
|
||||
attr_accessor :name, :ambient, :diffuse, :specular
|
||||
attr_reader :texture
|
||||
attr_reader :texture_id
|
||||
def initialize(name)
|
||||
@name = name
|
||||
@ambient = Color.new(1, 1, 1, 1)
|
||||
@@ -32,10 +32,6 @@ class IMICFPS
|
||||
|
||||
@texture = nil
|
||||
end
|
||||
|
||||
def texture_id
|
||||
@texture_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,8 +44,8 @@ class IMICFPS
|
||||
|
||||
puts "#{@file_path.split('/').last} took #{((Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)-start_time)/1000.0).round(2)} seconds to parse" if $debug.get(:stats)
|
||||
|
||||
# allocate_gl_objects
|
||||
# populate_buffers
|
||||
allocate_gl_objects
|
||||
populate_buffers
|
||||
# populate_arrays
|
||||
|
||||
@objects.each {|o| @vertex_count+=o.vertices.size}
|
||||
@@ -84,15 +84,17 @@ class IMICFPS
|
||||
@vertices_buffer_data = []
|
||||
|
||||
verts = []
|
||||
colors= []
|
||||
colors = []
|
||||
norms = []
|
||||
uvs = []
|
||||
tex_ids = []
|
||||
|
||||
@faces.each do |face|
|
||||
verts << face.vertices.map { |vert| [vert.x, vert.y, vert.z] }
|
||||
colors << face.colors.map { |vert| [vert.x, vert.y, vert.z] }
|
||||
norms << face.normals.map { |vert| [vert.x, vert.y, vert.z, vert.weight] }
|
||||
uvs << face.uvs.map { |vert| [vert.x, vert.y, vert.z] } if face.material.texture
|
||||
uvs << face.uvs.map { |vert| [vert.x, vert.y, vert.z] } if face.material.texture_id
|
||||
tex_ids << face.material.texture_id if face.material.texture_id
|
||||
end
|
||||
|
||||
verts.each_with_index do |vert, i|
|
||||
@@ -100,6 +102,7 @@ class IMICFPS
|
||||
@vertices_buffer_data << colors[i]
|
||||
@vertices_buffer_data << norms[i]
|
||||
@vertices_buffer_data << uvs[i] if uvs.size > 0
|
||||
@vertices_buffer_data << tex_ids[i] if tex_ids.size > 0
|
||||
end
|
||||
|
||||
data = @vertices_buffer_data.flatten.pack("f*")
|
||||
|
||||
Reference in New Issue
Block a user