experiment with drawille to display LCD + improving LCD

This commit is contained in:
Gwenhael Le Moine 2023-07-20 16:27:38 +02:00
parent c763c7bd4b
commit 002da6df44
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
5 changed files with 76 additions and 29 deletions

View file

@ -60,7 +60,7 @@ class RplRepl
end
end
print_display if @interpreter.show_display
print_lcd if @interpreter.show_lcd
print_stack
rescue Interrupt
@ -70,8 +70,8 @@ class RplRepl
end
end
def print_display
puts @interpreter.display_grob.to_text
def print_lcd
puts @interpreter.lcd_grob.to_braille
end
def print_stack

View file

@ -12,19 +12,19 @@ class Interpreter
include Types
attr_reader :stack,
:display_grob,
:lcd_grob,
:dictionary,
:version
attr_accessor :show_display
attr_accessor :show_lcd
def initialize( stack: [], dictionary: Dictionary.new )
@dictionary = dictionary
@stack = stack
@show_display = false
@show_lcd = false
@display_grob = RplGrOb.new( 'GROB:131:64:0' )
@lcd_grob = RplGrOb.new( 'GROB:131:64:0' )
end
def run!( input )

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true
require 'drawille'
require 'rpl/parser'
class BitArray
@ -82,8 +84,28 @@ module Types
.gsub( '1', '.' )
end
def to_braille
canvas = Drawille::Canvas.new
@height.times do |y|
@width.times do |x|
canvas[x, y] = @bits[ ( y * @height ) + x ] == 1
end
end
canvas.frame
end
def get_pixel( pos_x, pos_y )
@bits[ ( pos_y * @height ) + pos_x ]
end
def set_pixel( pos_x, pos_y, value )
@bits[ ( pos_y * @height ) + pos_x ] = value
@bits[ ( pos_y * @height ) + pos_x ] = value.to_i.zero? ? 0 : 1
end
def clear
@bits.from_i( 0 )
end
end
end

View file

@ -37,64 +37,64 @@ module RplLang
@stack << RplString.new( "\"#{args[0].bits.to_s(2).scan(/.{1,#{args[0].width}}/).join("\n")}\"" )
end )
category = 'Display management and manipulation'
category = 'Lcd management and manipulation'
@dictionary.add_word!( ['displayon'],
@dictionary.add_word!( ['lcdon'],
category,
'( -- ) display display',
'( -- ) display lcd',
proc do
@show_display = true
@show_lcd = true
end )
@dictionary.add_word!( ['displayoff'],
@dictionary.add_word!( ['lcdoff'],
category,
'( -- ) hide display',
'( -- ) hide lcd',
proc do
@show_display = false
@show_lcd = false
end )
@dictionary.add_word!( ['displaywidth'],
@dictionary.add_word!( ['lcdwidth'],
category,
'( -- i ) put framebuffer\'s width on stack',
proc do
@stack << RplNumeric.new( @display_grob.width )
@stack << RplNumeric.new( @lcd_grob.width )
end )
@dictionary.add_word!( ['displayheight'],
@dictionary.add_word!( ['lcdheight'],
category,
'( -- i ) put framebuffer\'s height on stack',
proc do
@stack << RplNumeric.new( @display_grob.height )
@stack << RplNumeric.new( @lcd_grob.height )
end )
@dictionary.add_word!( ['→displaywidth', '->displaywidth'],
@dictionary.add_word!( ['→lcdwidth', '->lcdwidth'],
category,
'( i -- ) set framebuffer\'s width',
proc do
args = stack_extract( [[RplNumeric]] )
@display_grob.width = args[0].value.to_i
@lcd_grob.width = args[0].value.to_i
end )
@dictionary.add_word!( ['→displayheight', '->displayheight'],
@dictionary.add_word!( ['→lcdheight', '->lcdheight'],
category,
'( i -- ) set framebuffer\'s height',
proc do
args = stack_extract( [[RplNumeric]] )
@display_grob.height = args[0].value.to_i
@lcd_grob.height = args[0].value.to_i
end )
@dictionary.add_word!( ['display→', 'display->'],
@dictionary.add_word!( ['lcd→', 'lcd->'],
category,
'( -- g ) export framebuffer to GrOb',
proc do
@stack << RplGrOb.new( @display_grob )
@stack << RplGrOb.new( @lcd_grob )
end )
@dictionary.add_word!( ['→display', '->display'],
@dictionary.add_word!( ['→lcd', '->lcd'],
category,
'( g -- ) import GrOb into framebuffer',
proc do
args = stack_extract( [[RplGrOb]] )
@display_grob = RplGrOb.new( args[0] )
@lcd_grob = RplGrOb.new( args[0] )
end )
@dictionary.add_word!( ['pixon'],
@ -106,7 +106,7 @@ module RplLang
x = args[1].value.to_i
y = args[0].value.to_i
@display_grob.set_pixel(x, y, 1)
@lcd_grob.set_pixel(x, y, 1)
end )
@dictionary.add_word!( ['pixoff'],
category,
@ -117,7 +117,30 @@ module RplLang
x = args[1].value.to_i
y = args[0].value.to_i
@display_grob.set_pixel(x, y, 0)
@lcd_grob.set_pixel(x, y, 0) # FIXME: toggle pixel instead of turning it off
end )
@dictionary.add_word!( ['pix?'],
category,
'( x y -- b ) return boolean state of pixel at x y coordinates',
proc do
args = stack_extract( [[RplNumeric], [RplNumeric]] )
x = args[1].value.to_i
y = args[0].value.to_i
@stack << RplBoolean.new( @lcd_grob.get_pixel(x, y) == 1 )
end )
@dictionary.add_word!( ['blank'],
category,
'( w h -- g ) create an empty GrOb',
proc do
args = stack_extract( [[RplNumeric], [RplNumeric]] )
w = args[1].value.to_i
h = args[0].value.to_i
@stack << RplGrOb.new( "GROB:#{w}:#{h}:0" )
end )
end
end

View file

@ -46,6 +46,8 @@ Gem::Specification.new do |s|
'lib/rpl/words/time-date.rb',
'lib/rpl/words/trig.rb']
s.add_dependency 'drawille'
s.executables << 'rpl'
s.required_ruby_version = '> 2.7'