View Single Post
Old 04-01-2012, 03:56 PM   #48
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Arrow titty - tiny tty

UPDATE: v1.4 tested and works great on DX, DXG, K3, K4, and Touch!



titty

titty - tiny tty (display tiny text on eink display)

requirements: titty.png.

usage:
"titty" cat self
"
ls -al|titty -" cat STDIN (from "ls" in this example)
"
titty /etc/shadow" PWN!

hint: This runs at TTY speed.
PHP Code:
#!/bin/sh
#=============================
# titty - tiny tty (v1.4)
# display tiny text on eink
# requirements: titty.png.
# usage:
#   titty
#     cat self
#   titty [x y] [-k] [--] -|STRING|-f FILE
#     displays "STDIN", "echo STRING" or "cat FILE"
#       [x y]  initialize cursor at x y
#       [-k]   clear lines
#       [--]   treat as string
#   titty -s Y H S
#     move H-S lines S lines up, beginning with line Y+S
#   titty -mx|-my
#     return maximal x y coordinates
#   titty -v
#     return version
# hint: This runs at TTY speed.
#------------------------------
# Copyright (C) 2012 geekmaster
# 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.
#------------------------------
# Revision History (last change first):
# =ver= =date===== =author===== =description============================
# 1.4   2012-04-05 geekmaster   fix "end of page" bug
# 1.3   2012-04-05 kaminkatze   scrolling and options
# 1.2   2012-04-04 kaminkatze   k3 support and per line hexdump
# 1.1   2012-04-01 geekmaster   first release

# WARNING: If you don't stop using titty, you will go blind! :D

#===========================
# initvar - init global vars
#---------------------------
initvar() {
  
V=1.4 # version
  
eips -"$0.png" # char map image
  
DN=/dev/null DF=/dev/fb0 # devices
  
set $(eips -i|grep res:); FW=$2 FH=$# fb0 width, height
  
set $(eips -i|grep line); FS=$# fb0 stride
  
CW=$((4*FS/FW)) CH=6 LH=# char width, height, line height
  
LM=2 TM=$((CH*2)) # left, top margin px
  
MX=$((FW*FS/FW-CW)) MY=$((FH-LH)) # max X, Y
  
CX=$LM CY=$TM # cursor coords
  
DD="dd if=$DF of=$DF bs=1 count=$CW# ddblit
  
DL="dd if=$DF of=$DF bs=1 count=$((FS*CH)) skip=$((FS*CH))" # clear line
  
Q=false # quit flag
  
K=false # clear line flag
  
JFS=$IFS # normal field separator
}

#====================
# usage: scroll y h s
#--------------------
scroll() {
  
dd if=$DF of=$DF bs=1 count=$((FS*LH*($2-$3))) \
    
skip=$((FS*(LH*($1+$3)+TM))) seek=$((FS*(LH*$1+TM))) 2>$DN
  eips 
''
}

#=================
# titty - tiny tty
# displays STDIN
#------------------
titty() {
  
until $Q ;do IFS='\n'read L || Q=trueIFS=$JFS
    
for A in $(echo -"$Lhexdump -ve '/1 "%d\n"'); do
      if [[ 
$A -ne 32 ]]; then
        RO
=$(((A-32)*CW)) FO=$((CY*FS+CX))
        for 
y in $(seq 1 $CH);do
          
$DD skip=$RO seek=$FO 2>$DNRO=$((RO+FS)) FO=$((FO+FS))
        
done
      fi
CX=$((CX+CW)); [[ $((CX%64)) -eq $LM ]] && eips ''
      
if [[ $CX -gt $MX ]]; then CX=$LM CY=$((CY+LH))
        [[ 
$CY -gt $MY ]] && CY=$TM CX=$LM
        $K 
&& $DL seek=$((CY*FS)) 2>$DNfi
    done
eips ''
    
CX=$LM CY=$((CY+LH)); [[ $CY -gt $MY ]] && break
    
$K && $DL seek=$((CY*FS)) 2>$DN
  done
}

# Do stuff!  :-)
initvar
if [[ "$1" == "" ]]; then cat "$0"|titty
else while [[ "$1" ]]; do
  case 
"$1" in
    
-sscroll $$$4shift;shift;shift;shift;;
    -
mx) echo $((FS/CW-CW)); shift;;
    -
my) echo $MLshift;;
    -
fcat "$2"|tittyshift;shift;;
    -) 
tittyshift;;
    -
k) if [[ $CX -eq $LM ]]; then $DL seek=$((CY*FS)) 2>$DN
        
else for y in $(seq 0 $((CH-1))); do
          
dd if=$DF of=$DF bs=1 count=$((FS-CX)) \
            
skip=$((FS*CH)) seek=$(((CY+y)*FS+CX)) 2>$DN
        done
fiK=trueshift;;
    --) echo -
"$2"|tittyshift;shift;;
    -
v) echo $Vshift;;
    *) if [[ -
"$3" ]]
       
then CX=$((LM+$1*CW)) CY=$((TM+$2*LH)); shift;shift
       
else echo -"$1"|tittyshift
       fi
;;
  
esac
done
fi 
This script requires the "titty.png" file shown below, and included in the download file along with the script. This image contains a complete set of 128 ASCII characters, used to display text on the eink display. This is a VERY TINY font, just to show that we CAN do this. I also have a version with an 8 pt Courier font, which I will release later.

WARNING: As shown below, the text is REALLY TINY, and even near-sighted people may need magnifying reading glasses to see it clearly on a real eink display, where it is a LOT smaller than on a typical LCD panel where you may be viewing this. Reading text at that size is a difficult task for eyes. (But think of all the text you could cram onto a screensaver image using this script, such as crib notes for an exam, with no batteries needed .) And it is cool watching it too, ESPECIALLY considering that it is all being done with just some clever little /bin/sh kung fu mojo and a few built-in linux commands, IMHO...

titty.png:
(The tiny low-resolution characters shown above actually look a lot better on the smaller kindle eink display, or from a distance on a large LCD display, due to visual perception properties.)

Here are some screen captures
from a kindle touch eink display
showing "titty" in action:
Spoiler:
./titty

Spoiler:
./titty /etc/upstart/functions

Spoiler:
ls -al /etc/upstart|./titty -


....FAQ:
Spoiler:
Q1) Why is this called "titty"?
A1) "Titty" is short for "(ti)ny (TTY)". It is a tiny script, it displays tiny characters, and watching it is like watching a teletype (TTY). It is quite a bit faster than a *real* TTY though (I have an ASR-33).

Q2) Why is this in the "algorithmic art" thread?
A2) It displays a PNG file, and it uses algorithms, and using it is sort of an "artistic statement ". Do we really need a separate thread just for "titty"?

Q3) Does this work on the Kindle 3?
A3) It can with a few little adjustments. Either do it yourself (a great learning experience) or wait for somebody else to do it for you.

Q4) If you look at tiny titty on the eink display too much, can you go blind?
A4) Yes! Just like your mother warned you when you were a teenager and she caught you!

Enjoy, and learn!


Ongoing optimization
investigation updates:

Spoiler:
EDIT: I just had a simple idea how to make this faster. It is now calling "hexdump" for every single character on the input line, to convert it from a character to a number used to offset into the onscreen character image map. Instead, we could call "hexdump" once with the entire line and then process the numeric values on the lines of hex numbers that it returns. Unfortunately, after stripping this subset of my code base to its essential simplicity for publication, it would start growing again as we add optimizations and features.

EDIT: I realized that because "dd" can "blit" as many horizontal pixels as you want with a single call, and because text characters are tall and narrow, we could use "dd" much more efficiently by drawing characters with the longest dimension (vertical) in the fastest direction that "dd" can draw (horizontal). In other words, because we start with a blank screen, we can "pretend" that it is in landscape mode. This will make character blitting about 50-percent faster for the character set used here. So, for text blitting using "dd", landscape mode is the way to go, and we can display two pages of 100-character lines side-by-side. Progress is an evolutionary process.

EDIT: I thought of another possible speed improvement for portrait mode (normal) text. This exploits the fact that "dd" call overhead is such that it can copy an entire line in about the same amount of time it takes to copy a single character. I have worked a lot with custom data compression for high-speed in-memory data transfer. Due to multi-level memory cache heirarchy on modern CPUs, LZ decompression is many times faster than direct memory transfers of uncompressed data because typically 90% of the data is copied from earlier in the output buffer (which is in high speed memory cache), and only 10% does not match and gets copied literally from the input buffer (which may still be streaming in from much slower DRAM, or even slower mmc). What I realized is that the decompression algorithm that tells how far back in the output buffer to copy a run of duplicate data from, would also tell how far back to find the same run of already rendered text character images, and we could "ddblit" the entire run (split by right page margin) from the rendered page instead of individual characters from the character map image. With the typical 10x compression for normal text (like ascii ebooks), we should also see a 10x speedup on the "dd" calls (and 10x text rendering speed). This program could become sort of like an eink zcat instead of cat (but using simple and fast byte-mode LZ compression). Cool, huh?

EDIT: Of course, the GREATEST speed improvement will come from converting this to a compiled language such as C, which can directly access the pixels with no "dd" call overhead, and can do partial screen updates using ioctl system calls. For eink, partial screen updates make a HUGE difference for small changes such as individual characters like we are doing here. I still have a few more shell script code snippets I plan to use as teaching tools (and useful little script-only utilities), before I switch to C in these tutorials.


What, no feedback? Are you guys even READING this stuff? Please leave some feedback. Thanks.


Attached Files
File Type: gz titty-1.1.tar.gz (2.0 KB, 221 views)
File Type: gz titty-1.4.tar.gz (2.6 KB, 289 views)

Last edited by geekmaster; 04-11-2012 at 12:49 PM.
geekmaster is offline   Reply With Quote