From 422a7828a537a0f79cb09ea879610235754f1917 Mon Sep 17 00:00:00 2001 From: Gwenhael Le Moine Date: Thu, 6 Jul 2023 15:09:29 +0200 Subject: [PATCH] First step towards an pseudo-LCD display Words: lcdon, lcdoff, pixon, pixoff --- bin/rpl | 11 +++++++++ lib/rpl.rb | 1 + lib/rpl/interpreter.rb | 13 ++++++++-- lib/rpl/words.rb | 1 + lib/rpl/words/graphics.rb | 52 +++++++++++++++++++++++++++++++++++++++ lib/rpl/words/repl.rb | 8 ++++++ 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 lib/rpl/words/graphics.rb diff --git a/bin/rpl b/bin/rpl index 32c183d..ed64a1e 100755 --- a/bin/rpl +++ b/bin/rpl @@ -60,6 +60,8 @@ class RplRepl end end + refresh_lcd if @interpreter.show_lcd + print_stack rescue Interrupt puts '^C' @@ -68,6 +70,15 @@ class RplRepl end end + def refresh_lcd + @interpreter.lcd_width.times do |x| + @interpreter.lcd_height.times do |y| + putc @interpreter.frame_buffer[ ( y * @interpreter.lcd_height ) + x ].zero? ? '_' : '.' + end + puts "\n" + end + end + def print_stack stack_size = @interpreter.stack.size diff --git a/lib/rpl.rb b/lib/rpl.rb index d0e8b97..a58e7b2 100644 --- a/lib/rpl.rb +++ b/lib/rpl.rb @@ -52,6 +52,7 @@ class Rpl < Interpreter prepend RplLang::Words::Display prepend RplLang::Words::FileSystem prepend RplLang::Words::General + prepend RplLang::Words::Graphics prepend RplLang::Words::List prepend RplLang::Words::Logarithm prepend RplLang::Words::Mode diff --git a/lib/rpl/interpreter.rb b/lib/rpl/interpreter.rb index 8d027de..2e99e59 100644 --- a/lib/rpl/interpreter.rb +++ b/lib/rpl/interpreter.rb @@ -32,9 +32,12 @@ class Interpreter attr_reader :stack, :frame_buffer, :dictionary, - :version + :version, + :lcd_width, + :lcd_height - attr_accessor :precision + attr_accessor :show_lcd, + :precision def initialize( stack: [], dictionary: Dictionary.new ) @dictionary = dictionary @@ -45,6 +48,12 @@ class Interpreter def initialize_frame_buffer @frame_buffer = BitArray.new + + # TODO: make this configurable from rpl? + @lcd_width = 131 + @lcd_height = 64 + + @show_lcd = false end def run!( input ) diff --git a/lib/rpl/words.rb b/lib/rpl/words.rb index ecc14eb..0bba39a 100644 --- a/lib/rpl/words.rb +++ b/lib/rpl/words.rb @@ -19,3 +19,4 @@ require 'rpl/words/trig' require 'rpl/words/logarithm' require 'rpl/words/filesystem' require 'rpl/words/list' +require 'rpl/words/graphics' diff --git a/lib/rpl/words/graphics.rb b/lib/rpl/words/graphics.rb new file mode 100644 index 0000000..9f02f50 --- /dev/null +++ b/lib/rpl/words/graphics.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module RplLang + module Words + module Graphics + include Types + + def populate_dictionary + super + + category = 'Graphics' + + @dictionary.add_word!( ['lcdon'], + category, + '( -- ) display lcd', + proc do + # Sets on a boolean that the REPL will survey and show the Gosu window when true + @show_lcd = true + end ) + + @dictionary.add_word!( ['lcdoff'], + category, + '( -- ) hide lcd', + proc do + # Sets on a boolean that the REPL will survey and hide the Gosu window when false + @show_lcd = false + end ) + + @dictionary.add_word!( ['pixon'], + category, + '( x y -- ) turn on pixel at x y coordinates', + proc do + args = stack_extract( [[RplNumeric], [RplNumeric]] ) + + puts "DEBUG: turn on pixel(x: #{args[1].value}, y: #{args[0].value})" + x = args[1].value.to_i + y = args[0].value.to_i + + @frame_buffer[ ( y * @lcd_height ) + x ] = 1 + end ) + @dictionary.add_word!( ['pixoff'], + category, + '( x y -- ) turn off pixel at x y coordinates', + proc do + args = stack_extract( [[RplNumeric], [RplNumeric]] ) + + puts "DEBUG: turn off pixel(x: #{args[1].value}, y: #{args[0].value})" + end ) + end + end + end +end diff --git a/lib/rpl/words/repl.rb b/lib/rpl/words/repl.rb index f15d62b..0de2004 100644 --- a/lib/rpl/words/repl.rb +++ b/lib/rpl/words/repl.rb @@ -79,6 +79,14 @@ module RplLang category, '() print internal state of local variables layers', proc { pp @dictionary.local_vars_layers } ) + + @dictionary.add_word!( ['.fb'], + category, + '() print internal state of framebuffer', + proc do + pp @show_lcd + pp @frame_buffer + end ) end end end