www.sandromaffiodo.com
/homepage /list +nerd

Contact: yt tw fb in mail git


Tags: [all] obfuscated rubik arduino vgax terminal ebook epub esp8266 espvgax game javascript php scifi ioccc piano music book youtube curl

About me

Hello! Here you can find some stuff about me and somethings that i think can be interesting, made by me or not.

My name is Sandro Maffiodo. I was born in Italy in the year 1981 and i live in a small town near Torino. I studied Graphical Arts at ITIS G.B.Bodoni and Information Technology at University of Studies of Torino. From 2012 i am working for BETACOM S.R.L.. Mostly i am a software architect, software analyst, software developer, team leader, project manager. I love retrocomputing, electronics, computers, arts, music and wood crafting. I hope that here you may find something usefull or fun to read.

This website is LYNX/W3M friendly, so, if you are all alone in the dark, inside a remote SSH session, connected to a machine that does not have a graphical interface, you can open this website and read something. Or, if you own an old machine, like an Amiga 500, an old IBM 386 or an ancient Macintosh, you can use LYNX (or W3M) to open this page, without any problems ;-)

here you can download my curriculum vitae. Clicking here you can toggle the NERD MODE and see this webpage in a more NERDY WAY :-D

Here there are some of my projects:

IOCC 2015 not winning entries

Sometimes you win sometimes you NOT. One year after my 2014 Winning entries i have participated another times to the IOCCC contest without winning nothing. But here they are ALL of the programs that i have created for the nerdy contest!

SOUNDOFPI

pi

OVERVIEW

This is a song generator. The generated song is based on an obscure sequence of numbers. Who can understand what is this sequence?

BUILD

$(CC) prog.c -o prog

RUN

./prog 1000 > song.wav

FEATURES

This program generate a 44100Hz 16bit mono audio file. The length and duration of the file depends on the argument given to the program. You can try with these values:

./prog 200
./prog 1000
./prog 6000

The more the number is great, the more the length of the file will be big.

WAV EXAMPLE

DOCS
SOURCECODE

SIERPINSKI

sierpinski

OVERVIEW

This is a fractals generator. It generates a fractal like the Sierpinski Carpet but little different.

BUILD

$(CC) prog.c -o prog

RUN

echo 27 | ./prog > image.ppm

To view the generate image you can use GIMP or ImageMagick to convert the image

convert image.ppm image.jpg

FEATURES

This program reads a number N from stdin and generates a PPM image with resolution NxN

SIERPINSKI CARPET in 149 bytes

This is the standard Sierpinski Carpet fractal, if you don't want my fractal:

a,b,c,x,y;main(){scanf("%d",&a);printf("P5 %d %d 1 ",a,a);for(;b!=a*a;b++){x=b%a;y=b/a;c=1;while(c&&x||y){c&=!(x%3&1&&y%3&1);x/=3;y/=3;}putchar(c);}}

DOCS
SOURCECODE

PACMAN

pacman pacman-screenshot

OVERVIEW

This is not a pizza. Obviously this is a tribute to the famous PAC MAN game.

BUILD

$(CC) prog.c -lSDL -o prog

RUN

cat level-ioccc | ./prog && echo YOU WIN!

Or

cat level-classic | ./prog && echo YOU WIN!

The program return zero if you win, not-zero if you are a loser.

FEATURES

This simple program is a partial implementation of the original PAC MAN . The gameplay is a bit ' different : Ghosts , once eaten , never become two eyes and never return ghosts . This difference made ​​the game easier.

The program does not count the lives or points . Just wait until the player dies or wins ( by collecting all points / coins ) .

The program does not implement a traditional pathfinding algorithm , but use one that I wrote specifically for the event ( see chapter Pathfinding ) .

The description of the level is read from stdin so you can customize what you want . You can add ghosts , walls and dots .

The game sprites are contained in a single bitmap that you can change, if you like.

LEVEL DESCRIPTION

Each line must be 21 characters long.

These are the supported characters:

PATHFINDING

Instead of implementing one of the standard pathfinding algorithms i've decided to write a cooperative pathfinding algorithm that use a single weighted map for all ghosts. The code is small and seems to do the job.

The algorithm follow these three rules:

  1. every time the player moves, the global weighted table is computed using this formula:

    cell.weight = manhattan_distance(cell.pos, pacman.pos)

    If the cell is a wall its weight is infinitely great.

  2. each ghost moves to one of its nearest cells (up, down, left, right), choosing the one with the lowest weight
  3. when a ghost leaves a cell, the cell weight is multiplied by two

NOTES

The program will not terminate until the player win or dies. Press ESCAPE to quit.

DOCS
SOURCECODE

Two examples of levels build for this awesome and clearly clean program:

CHIP8

chip8 chip8_A chip8_B chip8_C chip8_D

OVERVIEW

As you can see , it is an emulator CHIP8. CHIP8 is an old virtual machine used in the 70s and 80s. It was used inside the VIP COSMAC , TELMAC 1800 and in some other microcomputer.

CHIP8 virtual machine has this features:

BUILD

$(CC) prog.c -lSDL -o prog

RUN

cat BRIX | ./prog

You can try one of these games (downloaded from here):

(DE)OBFUSCATION

The main obfuscation tricks is to encode the instruction set inside the V string:

*V="`__m__`__mm________`_____a_____b___`_c___`ad___a_e___`_f___"
    "`ag___aag__`aag__aaag__baag__caag__daag__eaag__faag__maah_"
    "__a_i_____j_____k___`_l___bbm_hmabm_i`abn__fabn__iabn_`dab"
    "n_`gabn_`mabn_ahabn_bbabn_ddabn_eda"

This string is a simple sequence encoded in base16. If you decodes it correctly you obtain this:

*V="100E00100EE000000001000002000003000104000125000206000107000"
    "12800022800122800222800322800422800522800622800722800E2290"
    "0020A00000B00000C00010D00033E09E23E0A123F00723F00A23F01523"
    "F01823F01E23F02923F03323F05523F0652"

Each subsequence of 6 characters contain these informations:

1 00E0 0
| |__| |
|    | +-- instruction parameters format (0=_NNN, 
|    |                                    1=_XNN, 
|    |                                    2=_XY_, 
|    |                                    3=_XYN)
|    |
|    +---- instruction opcode
|
+--------- instruction mask (0=1111000000000000, 
                             1=1111111111111111, 
                             2=1111000000001111, 
                             3=1111000011111111)

With these informations is pretty simple to recognize each one of the 35 instructions of the CHIP8, by searching a match inside the V string. This solution is obviously really slow but the resulting code is pretty fun. This is the main switch used to decode one instruction, rewritten using the _ macro:

#define _ ;}else if(((o=0),(c=*n++-95),\
            k(12),k(8),k(4),k(0),\
            (f=*n++-95),1)&&(q&r[c])==o){\
                s[f]();

void instruction_set_switch() {
    if (0) {
    _ _ _ _ _ 
    _ _ _ _ _ 
    _ _ _ _ _ 
    _ _ _ _ _ 
    _ _ _ _ _ 
    _ _ _ _ _ 
    }
}

From here you can de obfuscate the rest of the program. It's pretty simple to do... don't you think? :D

NOTES

You can slow down the emulator by increasing the parameter of

SDL_Delay(3);

You can change the zoom factor of the screen by editing this variable

I=4

DOCS
SOURCECODE

SUBLEQ

subleq-ob

Some INFO extracted from the official DOCS


OVERVIEW

This is a simple SUBLEQ emulator. It also embeds a SUBLEQ interpreter writen in SUBLEQ.

SUBLEQ is a simple OISC machine: A one instruction set computer (OISC), sometimes called an ultimate reduced instruction set computer (URISC), is an abstract machine that uses only one instruction [...] an OISC is capable of being a universal computer in the same manner as traditional computers that have multiple instructions.

SUBLEQ instruction is defined like this:

The subleq instruction ("SUbtract and Branch if Less than or EQual to zero") subtracts the contents at address A from the contents at address B, stores the result at address B, and then, if the result is not positive, transfers control to address C (if the result is positive, execution proceeds to the next instruction in sequence)

A SUBLEQ instruciton looks like this:

A B C 

This emulator execute its input until the program jump to the address -1 (C==-1).

This emulator can also read values from stdin, write to stdout and allocate some memory. To do that i've overloaded the original meaning of the SUBLEQ instruction by adding two special memory addresses: -1 and -2. These addresses must be used like that:

To terminate the sourcecode of your program you must use the magic number:

-65535

Your programs cannot be greater than 64 kilobytes of RAM.


SOURCECODE

IOCC 2014 not winning entries

In the year of the Lord (of the Ring) 2014 i won two times the IOCCC contest for my [Super Mario Bros Engine]() (aka MARIO) and [ASCII ART Generator]() (aka ART) programs.

These are others three programs that i have created and send to the 2014 contest but, unfortunately, was not winning entries.

THIRD

third third_A third_B third_C third_D

Some info extracted from the official DOCS:


OVERVIEW

This is not another Ray Tracer.

This is a classical 3D Software Rasterizer that supports:

The program reads an infinite list of frame descriptors from stdin and generate an infinite sequence of rendered frames to stdout.

HOW IT WORK

The program starts reading the output resolution from the command line arguments; then reads a raw BGRA texture image from stdin.

Texture format

The texture format is very simple:

Frame Descriptor

After that, the program continue to reading an infinite list of frame descriptor from stdin. Each frame descriptor is encoded in ASCII and contain a list of float values, comma separated:

The list of float values must terminate with the "E" character. For each 3 vertices the renderer will generate a single triangle.

Example

This is an example of a descriptor for one coloured triangle:

-1.81066, 0, 0, 0,
0, -2.414213, 0, 0,
0, 0, -1.083333, -1,
0, 0, -8.333333, 0,

1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, -10, 1,

10, 10, 1, 1, 

0, 0, 1, 1,     1, 0, 0,    0, 0,   -1, -1, 1, 1,
0, 0, 1, 1,     1, 0, 1,    1, 0,   1, -1,  1, 1,
0, 0, 1, 1,     1, 1, 1,    1, 1,   1,  1,  1, 1,

E

This command will generate the same triangle in the file frame.bgra, using a white 2x2 texture:

$ printf "\001\077\077\077\077\077\077\077\077\077\077\077\077\077\077\077\077 -1.81066, 0, 0, 0, 0, -2.414213, 0, 0, 0, 0, -1.083333, -1,0, 0, -8.333333, 0,1, 0, 0, 0,0, 1, 0, 0,0, 0, 1, 0,0, 0, -10, 1, 10, 10, 1, 1, 0, 0, 1, 1,1, 0, 0, 0, 0, -1, -1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, -1,  1, 1, 0, 0, 1, 1, 1, 1, 1,1, 1, 1,  1,  1, 1, E" | ./prog 320 200 > frame.bgra

To convert frame.bgra to JPG you can use this:

convert -size 320x200 -depth 8 frame.bgra frame.jpg

SOURCECODE

Some shell scripts used to generate the required input data:

Sourcecode (obfuscated, obviously) of the additional tools used to test and prepare the required input data:

ALIEN

alien alien-terminal

INFO extracted from the official DOCS


OVERVIEW

Obviously this is a SPACE INVADER game. It use NCURSES to get the terminal screen size and handle inputs/outputs.

The program return 0 if the user win or not-zero if the user is A LOSER.

RUN

To run the program type

./prog

You can move the ship to the LEFT using key A and to the RIGHT using any other key. Use SPACE to shoot a rocket.

The program return 0 if the user win so you can test it and make something usefull (or not), like that:

./prog && echo "you win"

Try the following alias! Every time you type ls you need to beat the aliens to list your files! :D

alias ls="'`pwd`/prog' && ls"

This is The mad SOURCECODE.

KUBRIK

kubrik

INFO extracted from the official DOCS


OVERVIEW

How small can be a Rubik's cube solver?

This is a Rubik's cube solver.

The program solves a 3x3 Rubik's cube using a modified version of the method "layer by layer" (explained here: http://solvethecube.com/).

This is not a bruteforce solver. One bruteforce solver takes too time to find a solution... This program will find its in the blink of an eye.

The program reads a scramble sequence from stdin and writes the solution to stdout. The program will not solve the cube by reversing the scramble sequence (this would be too simple!!). It uses the method "layer by layer", and is capable of solving any permutation of the cube (one of 43252003274489856000 permutations).

This program works with a cube with a standard color schema.

RUN

The program starts with a solved cube. You need to type a sequence of moves to scramble the cube.

You can get a scramble sequence from http://www.jaapsch.net/scramble_cube.htm or use one of these scramble:

L U B2 F' L' R B2 L' R2 F' R F2 D U' B D U' B U F'

B2 F' L U' F D' B D2 U2 R' U2 F' U F2 D' U2 B D2 U R'

L' R2 D2 U F2 D2 U2 L2 R2 B2 F D B2 U' L2 R2 D' B F' D

R U B2 L2 U2 F R'

The starts position of your cube MUST BE with the GREEN FACE on front and the WHITE FACE on top. The scramble sequence MUST NOT include the rotation moves: x, y, z.

You can type the scramble to the program using EOF (CTRL+D) to terminate the sequence, or use a pipe:

$ echo "R U B2 L2 U2 F R'" | ./prog

SOURCECODE

Smaffer 3D Cube Rubik solver

This is an old project that i've made a long time ago in a galaxy far far away.

3dcube

This project was mentioned inside my Arduino Rubik Server post.

This was a simple solver in Javascript that can solve the 3x3x3 cube by using the Layer by Layer method, starting from the RED CROSS. The project was developed using Javascript, HTML5, Canvas and WebGL

Here you can try to use the Smaffer 3D Cube.

SLAP LIKE NOW! ...wait, where is the LIKE button?

OI Ultimate reducted RISC machine

This is an old project that i've made in the past.. when a spider has bitten me and gave me the powers of the DORK NERD.

What is OI?

oi

OI is a small interpreter of an OISC machine.

Wikipedia define an OISC like this:

"A one instruction set computer (OISC), sometimes called an ultimate reduced instruction set computer (URISC), is an abstract machine that uses only one instruction [...] an OISC is capable of being a universal computer in the same manner as traditional computers that have multiple instructions."

OI is a SUBLEQ interpreter. SUBLEQ is an instruction defined like this:

"The subleq instruction ("SUbtract and Branch if Less than or EQual to zero") subtracts the contents at address A from the contents at address B, stores the result at address B, and then, if the result is not positive, transfers control to address C (if the result is positive, execution proceeds to the next instruction in sequence)"

The primarly nerdy part of this project WAS NOT to implement an OISC machine, but was to write an OISC interpreter using only the single instruction SUBLEQ. Really absurd huh? Yeeeah, like things that nerdy do.

Check out this simple and clean SUBLEQ interpreter writen in SUBLEQ:

-2 341 3 334 334 6 341 334 9 334 39 12 334 40 15 334 43 18 -1 330 21 330 -1 24 335 335 27 330 335 30 336 336 33 347 336 36 336 335 57 0 0 42 330 0 45 337 43 48 337 39 51 337 40 54 334 334 18 346 -2 60 346 -2 63 346 -2 66 334 334 69 341 334 72 334 102 75 334 105 78 334 108 81 337 105 84 337 108 87 337 108 90 343 343 93 331 331 96 332 332 99 333 333 102 0 331 105 0 332 108 0 333 111 334 334 114 338 334 117 331 334 159 334 334 123 337 334 126 331 334 159 334 334 132 335 335 135 341 334 138 334 335 141 331 335 144 237 237 147 334 334 150 335 334 153 334 237 156 334 334 168 340 343 162 237 237 165 331 237 168 334 334 171 338 334 174 332 334 222 334 334 180 337 334 183 332 334 222 334 334 189 335 335 192 341 334 195 334 335 198 332 335 201 238 238 204 246 246 207 334 334 210 335 334 213 334 238 216 334 246 219 334 334 237 238 238 225 246 246 228 332 238 231 332 246 234 340 343 237 0 0 240 337 343 267 334 334 246 0 334 249 335 335 252 334 335 267 339 102 258 339 105 261 339 108 264 334 334 90 334 334 270 333 334 327 334 334 276 335 335 279 341 334 282 334 335 285 333 335 288 342 342 291 334 334 294 335 342 297 102 102 300 105 105 303 108 108 306 342 102 309 342 105 312 342 108 315 337 105 318 337 108 321 337 108 324 334 334 90 334 334 -1 0 0 0 0 0 0 0 -1 -2 -3 1 0 0 0 33 35 10 65535 -65535

Here you can look at the assembler sourcecode that i've used to write the SUBLEQ interpreter in SUBLEQ. The assembler language used was created by me to simplify the writing process. Here you can see the assembler compiler i've writen for that purpose. OMG, what a nerdy thing!!

Read more on OI homepage.

This SUBLEQ interpreter was submitted on the IOCCC 2015 competion but unfortunately didn't win any awards. Check out this post about my SUBLEQ obfuscated IOCCC 2015 entry.

Have fun!

VGAXUA VGA library for Arduino UNO and MEGA

A new variant of VGAX library has born! VGAXUA is an alternative version of VGAX that can generate a VGA signal with a resolution of 192x80px with 2 colors. On Arduino MEGA resolution can be increased to 200x240px!

vgaxua-screen-1 vgaxua-screen-2

Check out the full documentation on my GitHub VGAXUA page

Two videos from YouTube: VGAXUA on Arduino UNO VGAXUA on Arduino MEGA

This library merge some ideas from ESPVGAX (my VGA library for ESP8266). In fact VGAXUA support extended colors toggling two PINS while generating horizontal lines. In theory is possible to control these PINS differently for each different horizontal lines but, for now, the code is limited to toggle these BITS one time for each frame.

These are the colors combinations that can be achived using VGAXUA:

vgaxua-colors

Now i am planning to work on a VGA signal generator that does not rely on a full framebuffer... it's a SPRITE based library!! Coming soon on The Internet :D

Happy hacking, Nerds!

VGAX Support for ATMega2560

I've added support for ATMega2560 to my library VGAX! Now the library can be configured to generate 120x90px (with squared pixels) or 120x240px (rectangular pixels).

atmega2560-video1

Video of VGAX on ATMega2560

The wiring is simple, like for ATMega328. You can wire up an Arduino MEGA board with some cheap components:

atmega2560-1

To enable 120x90px resolution you need to uncomment the constant ATMEGA2560_HIGHRES on VGAX.h header. To enable 120x240px uncomment ATMEGA2560_MAXRES.

The tricky part to add support for ATMega2560 has been adapting the interrupt dejitter code. I've found that the original code, writen by Charles CNLOHR assume to work on an AVR MCU with a 16bit Program Counter. ATMega2560, like others fat MCU, has a 22bit Program Counter! So, when Charles pop PC from stack, code must be modified to pop 3 bytes instead of 2 (22bit PC requires 3 bytes):

#define DEJITTER_OFFSET 1
#define DEJITTER_SYNC -2
asm volatile(
  "     lds r16, %[timer0]    \n\t" //
  #if defined(__AVR_ATmega2560__)
  "     add r16, %[toffset]   \n\t" //
  #endif
  "     subi r16, %[tsync]    \n\t" //
  "     andi r16, 7           \n\t" //
  "     call TL               \n\t" //
  "TL:                        \n\t" //
  #if defined(__AVR_ATmega2560__)
  "     pop r17               \n\t" //ATMEGA2560 has a 22bit PC!
  #endif
  "     pop r31               \n\t" //
  "     pop r30               \n\t" //
  "     adiw r30, (LW-TL-5)   \n\t" //
  "     add r30, r16          \n\t" //
  //"   adc r31, __zero_reg__ \n\t" //
  "     ijmp                  \n\t" //
  "LW:                        \n\t" //
  "     nop                   \n\t" //
  "     nop                   \n\t" //
  "     nop                   \n\t" //
  "     nop                   \n\t" //
  "     nop                   \n\t" //
  "     nop                   \n\t" //
  "     nop                   \n\t" //
  //"   nop                   \n\t" //
  "LBEND:                     \n\t" //
:
: [timer0] "i" (&TCNT0),
  [toffset] "i" ((uint8_t)DEJITTER_OFFSET),
  [tsync] "i" ((uint8_t)DEJITTER_SYNC)
: "r30", "r31", "r16", "r17");

MCU PORTD must be changed to PORTA becouse PORTD does not have 8 pins, so all the assumptions made in VGAX for ATMega328 cannot work with PORTD for ATMega2560. Colors pins must be moved from pin 6 and pin 7 to pin 30 and pin 31 (higher 2 bits of PORTA in ATMega2560).

TIMER0 setup must be also modified to work fine on both ATMega328 and ATMega2560.

That's all! :)

ATMega2560 has 8KB of SRAM, more space for framebuffer to increase vertical resolution from 60 to 90 or 240px. In theory with ATMega2560 a new library can be created to use 256 colors (with RRRGGGBB pixel format) or 16 colors (RGBH-RGBH double pixels in single byte format). I think to try to write, in the future, these variations of VGAX inside new differents libraries (VGAX256 and VGAX16 ?).

Have fun!

Read EPUB from Terminal

ebookalice

The REAL Nerd do not use an EBook Reader. Use Terminal Emulators ONLY! :-D

EPUB file are easy to read. Technically an EPUB file is a ZIP file with containing a bunch on HTML files. So, it is pretty simple to read an EPUB using LYNX or W3M (terminal based browsers).

Using LYNX

unzip -l -p MY_EPUB_FILENAME text/* | lynx --stdin

Using W3M

unzip -l -p MY_EPUB_FILENAME text/* | w3m -T text/html

BASH Functions

Save this functions inside your .bashrc or .bash_profile file and you will have a persistent terminal command function to be used to read your lovely loved ebooks:


#read ebook with lynx
function epubl {
    unzip -l -p "$1" text/* | lynx --stdin
}
#read ebook with w3m
function epubw {
    unzip -l -p "$1" text/* | w3m -T text/html
}

Have FUN!

Arduino ESPVGAX Library

This is a VGA Arduino library for ESP8266. It can display a 512x480 image with 1bit per pixel.

espvgax-0

Here you can download the Library code from GitHub. It's free and opensource.

Wiring

Like my VGAX Library, this Library require cheap components. You can generate a signal from an ESP8266 with less then 5$ :-)

ESPVGAX require a DSUB15 connector (aka VGA connector) and one 330Ohm resistor:

espvgax-2

Super simple!

Colors combinations

espvgax-1

You can wire the VGA connector in some different modes that allow you to choose your preferred white color. For example you can choose to wire it up to use black and green colors, or black and purple.

espvgax-3

You can find more informations about colors combinations here.

Additional colors

The Library also support two modes where colors can be increased from the standard 2 colors.

espvgax-1

The first additional mode allow you to hook up an hardware PIN to one of the VGA pins (different from the primary color that you have selected in the first wiring). Thi hardware PIN is always ON when VGA signal pixeldata is generated, so you can change the background color from black to another color. This change is permanent and you cannot turn ON/OFF this background color variation.

espvgax-3

The idea behind the second additional mode is this: ESP8266 HSPI can send data to VGA as a serial stream of bits, so it can only turn one VGA PIN ON/OFF at a time. But VGA timing has gaps between lines that can allow more code to be executed, before and after sending the stream of bits. So, before sending the data, the Library can turn ON/OFF some other bits and change the color combination used in each horizontal line (480 lines).

espvgax-3

The VGA signals can become unstable if your code uses Wifi, Serial, and other Arduino classes. You can find more informations here.

ESPVGAX on GitHub

Happy Hacking!

Arduino BITNINJA

This is my first game for VGAX the VGA library that i have developed for Arduino.

bitninja-1

TLDR: Video of BITNINJA first test

The game

This game is a small platform game, like Super Mario Bros, designed by me. After my nomination in the IOCCC 2014 Contest, i have ported some of the logic of the SMB Engine that i have developed for the Contest.

bitninja-2

BITNINJA implements these features:

RAM Optimizations

Becouse VGAX uses 1800 bytes of RAM and the Arduino UNO ATMEGA328 MCU has only 2048 bytes of RAM, the game is optimized to use only 41 bytes of global RAM. All the images, sprites, songs and level definitions are stored in the MCU FLASH ROM. Doing the math: 2048-1800-41=207 bytes are "free", used for the MCU STACK where local variables and parameters are stored.

The 41 bytes required for BITNINJA to run are subdivided like this:

Sourcecode

Here you can download the BITNINJA source code !

Hardware

bitninja-3 bitninja-4

The hardware required is pretty cheap:

The wiring and soldering is documented inside VGAX library documentation, except for the wiring of the standalone ATMEGA328 MCU but you can easily find online How to run ATMEGA328 standalone.

Here you can see a video of BITNINJA testing running on the Arduino UNO, before the standalone board creation. The level you see in the video is a test. The 5 levels inside the final version are different than the one in the video.

This is the final board, with a piece of plexi on the bottom:

bitninja-5 bitninja-6

I am planning to take a video of all 5 levels, running on the final standalone board. When i will do the video i will post it here!

Have FUN!

Arduino Robot UNO

This is my first Arduino Robot, created in 2011!

robotuno-IMG0

The idea

The reason i have build it is that i need to control my audio system volume knob without phisically stand up, walk and turn the knob. I am laaazy :-D

I have a TV Remote with volume controls (and mute button) and i want to use the TV Remote to rotate the volume knob.

TLDR: Making of Arduino ROBOT UNO on Youtube!

My audio system is a Creative INSPIRE Audio 4+1 Surround System that i has originally bought for my old PC. It has a volume knob to control its volume level by hand:

creative

Hardware and Software

I have started this project by creating a tape/cardboard prototype with an Arduino UNO board, using a servo motor and an infrared receiver. Then, after some tests, i have started to modify the code so it can run on an ATTINY85 MCU, smaller than the ATMEGA328 MCU used by Arduino UNO:

robotuno-IMG5

I have used the Arduino UNO board to program the ATTINY85 MCU, using an online tutorial like this. Note that ATTINY85, like ATMEGA328, has an internal oscillator that can generate the MCU clock at 8Mhz or 1Mhz, so you don't need an external oscillator (or quartz) to power the MCU. In my Arduino Robot UNO i have choose to run at 8Mhz.

robotuno-IMG4

After that i have build the minimal circuit for the "brain" of the robot. The servo motor will be installed as one of the robot hands.

robotuno-IMG1

CNC cutting

I own a small CNC router that can be controlled via GCODE. At this point i have designed some sheets of plastic parts to be cutted and glued together to become the outer aspect of the robot.

robotuno-CNC

.. then i cut everythings with the CNC router ..

robotuno-IMG2

.. and glued all pieces together!

robotuno-IMG3

Here you can see the Making of Arduino ROBOT UNO, step by step.

After some weeks of testings i have notice that the batteries life was too short (3 AAA for week), so i have modified the hardware to get the 5V power from a cellular power supply. Now ROBOT UNO has a cable that go out from its head and connect to a 5V microUSB connector to the power supply.. :-D

Here you can download the Arduino ROBOT UNO sourcecode.

Design note

The ROBOT UNO design is inspired from my childhood best robot film: Short Circuit!

jhonny5

Long live Jhonny Five! Inpuuuut, MORE INPUT

Arduino Rubik Server

rubik-1

This was my first Arduino project: A webserver inside a Rubik's cube (2x2x2 Pocket Cube version) able to solve a Rubik's Cube 3x3x3 with the Layer-by-Layer method. It is fast! Can solve any scramble in around 100msec, using only 2048 bytes of RAM (ATMEGA328 MCU)!

Coding

I am a Rubik's Cube fan. I learned how to solve the 3x3x3 standard Rubik's Cube by following this guide. But i does not follow all raccomandations and learned to solve it creating a first RED CROSS instead of WHITE CROSS.

As a programmer i have developed a simple solver in Javascript that can solve the 3x3x3 cube by using the Layer by Layer method, starting from the RED CROSS. The project was developed using Javascript, HTML5, Canvas and WebGL.

Here you can find the Smaffer 3D Cube project homepage.

After that, for the IOCCC Contest, i have ported the Javascript solver to C with some obfuscations to follow the rules of the contest.

As an Arduino fan i have also ported the obfuscated code to C++, optimizing it to use the lower amount of RAM possible, without rewriting all the code. The source code is not simple to understand.. its obfuscated.. but it works. Can solve a 3x3x3 using a standard scramble sequence.

Hardware time

The hardware required to create this project is this:

rubik-2

I have used the ENC28j60 breakout board to connect the Arduino ATMEGA328 MCU to Ethernet. The cube parts are from a broken 2x2x2 Pocket Cube given to me by EFFEOTTO (thanks!).

Running page

The Arduino WebServer hosted by the MCU has a simple NERDY style:

rubik-3

You can send the scramble sequence inside the HTTP URL. The returned page will contains the scrambled 3x3x3 cube and the list of moves to solve it.

Solving modes

The sourcecode can solve the cube in two modes: with cube rotations moves (X, Y, Z) or without rotations (in place solving). The second mode can be used, theoretically, to solve the cube phisically, using hardware motors, without full rotations of the cube (the cube stay always in the same original orientation).

Wiring mess

This was my first Arduino project and this fact can be seen in the internal hardware soldering and wiring. But the final cube works and i think that the idea is fun and so nerdy! :-P

rubik-6

rubik-5

rubik-4

Problems

The big problem with this project, after some tests, is the battery. The idea to power up the cube using a 9V battery is not happy. The power consumption of the Ethernet connection is very high and the cube, powered with a fully charged 9V battery, cannot stay ON more than a couple of hours :-/

Future and Download

In the future, i will do a porting of this project to ESP8266, powered by a microUSB connector.

That's IT!

Here you can download the Arduino Sketch sourcecode. It is a porting of an obfuscated program so it is not simple to understand at all.. :-/

Happy hacking

1981 The Game

1981

This is a SciFi text game, written by me. A text game is like the old "Libro Game" that i read in my childhood (80s). You can read the story and choose how the story must continue.

1981 is short, you can complete the story in 15 minutes but warning: there are more than one ending!! :-)

Here you can play 1981 The Game. NOTE: The game is written in italian! There is no translation in any other languages!

1981 was written in Javascript, PHP and CSS3!

I am planning to upgrade the 1981 website to be Responsive and Mobile Friendly but i don't know when i can do this.. in the future, sure.

Some years ago i have started to porting this game to an Arduino projects... but i never complete the project.. yet!

This game was originally published on the ASSEZETA.COM website, created by me and my old friend Marco Baudino.

Arduino VGAX Library

vgaxA0

When i have bought my first Arduino UNO i have started to test some libraries for video signal generation. One of the first interesting library was TVOut. A simple lib that allow you to generate a COMPOSITE video signal out of an ATMEGA328 MCU, using only some resistors and a COMPOSITE video connector.

VGAX Inspirations

The first inspiration for VGAX come from TVOut library: A simple VGA library for Arduino that can work with simple cheap components!

Online i have found some interesting articles about Arduino VGA video signal generation, written by Nick Gammon. These articles and his works was the starting point for the development of my VGAX Library.

vgaxA0

My writing of VGAX was also inspired by the work of Petri Häkkinen, creator of the game TORUM QUEST II (for ATMEGA328!!). Here a link to his Blog. Here a link to his post on the Arduino Forum.

torum-quest Youtube Video

VGAX Assembler core

The creation of VGAX was a little tricky. I've spent many nights around the interrupt jitter problem, trying to adjust some dejitter code founds online.. An Hell!

To write the Assembler core of VGAX i've studied the official ATMEL ATMEGA328 Instruction Set Manual (190 pages), searching for the best instructions to generate the PIXEL stream output without losing too many CPU cycles. The idea was to use these instructions, for each byte of the framebuffer, inside an unrolled loop

.rept 30             // output 4 pixels (unrolled loop)
    ld r16, Z+       
    out %[port], r16 // write pixel 1 
    mul r16, r20     // left shift 2
    out %[port], r0  // write pixel 2
    mul r0, r20      // left shift 2
    out %[port], r0  // write pixel 3
    mul r0, r20      // left shift 2
    out %[port], r0  // write pixel 4
.endr                

The first good thing is that LD and MUL instructions require both 2 CPU cycles, so the output of the four pixels, packed inside a single byte, is done with the same number of CPU cycles for each pixel (3 cycles, LD=2, MUL=2, OUT=1). This equal timing ensures that all generated pixels will be displayed with the same size (horizontal width).

The second tricky thing is that the two VGA PINs are written with a single OUT instruction that writes an 8bits hardware PORT... but bits cannot be rearranged without losing time.. so the idea was to (pre)arrange the 4 pixels in one byte keeping the order of the bits aligned to the output pins of the 8BIT PORT. First pixel is stored in the higher 2 bits of byte.

pixel-packing

The hardware PORT uses the PIN from 0 to 7 so i have wired the two VGA PINs to PIN6 and PIN7.

PORT-wiring

When a byte is read from the LD instruction, the first pixel bits are already on the 6th and 7th bits, ready to be written out from the OUT instruction. The next MUL will shift the second pixel bits to the right position (6th and 7th bits of the PORT) and written out. This is repeated for the remaining two pixels.

ld r16, Z+       
out %[port], r16 // pixel1 bits are aligned on PORT 6th and 7th bits
mul r16, r20     // shift 2 pixel up
out %[port], r0  // pixel2 bits are now aligned

Resolution limitations

Many people ask me if is possible to increase the horizontal resolution of the VGA signal (120px).

Arduino ATMEGA328 has only 2048 bytes of RAM! The VGAX framebuffer have a resolution of 120x60px with 2bpp, almost all the MCU RAM is used (1800 bytes). This is the first limitation that cannot allow an increase of the horizontal resolution without losing color depth (2bpp). But there is another important reason that does not allow a greater horizontal resolution: the CPU speed!

ATMEGA328, inside Arduino, runs at 16Mhz. VGA signal require a 25Mhz PIXEL output speed. If you calculate the number of CPU cycles used to send PIXEL out you obtain this formula:

25Mhz : 640px = (16Mhz / 3clocks) : RES
RES = (640 * 5.3) / 25
RES = 136px~

So, the maximum resolution possible, at 16Mhz, using 3 CPU cycles for each pixel, is 136px! VGAX for ATMEGA328, with the dejitter code and the audio signal generation, reach a resolution of 120px for each horizontal line, near the maximum resolution possible.

Sharing

Here is hosted my VGAX Library, on GitHub. Here my post on the Arduino Forum.

This library was used from some people around the world. I thanks everybody for have spent some time using VGAX! Many thanks to Rob Cai that has recreated some classic games like Tetris, Pong and Breakout, using VGAX!

ct make

VGAX was reviewed in an article of the C'T MAKE newspaper, number of 03/2017. When i read this article i am always happy! :-)

MINICHIP The Game

A little platform game programmed in Javascript. This was the origin for the development of my future IOCCC Super Mario Bros Platform Engine. All the graphics (in pixelart) and sounds are created by me. This game has also a simple Level Editor i have used to design all levels of the game.

minichip0

This game was originally hosted on ASSEZETA.COM, years ago.

Here you can open the MINICHIP Homepage.

Following are some of the sprites used inside the game:

player

enemy-1

power-ups

robots

Have FUN!

IOCCC 2014 Winning entries

Long time ago (2014), in a galaxy far far away, i have won two nominations at the Internatonal Obfuscated Code Contest. I remember when I discovered the IOCCC, back in 2003, thanks to EFFEOTTO ... I would have never thought to participate and win something .. but in a single year i have won two times! Incredible :-)

Homage to a classic game

This is the source code of the first winning entry:

obfuscated-program

The program is not only a Super Mario Bros partial implementation but also a generic Engine for Platform Games. It can be used to create games like Super Mario Bros. The contest entry was released with two example games level: one level of Super Mario Bros and one level of Giana the Sister (an SMB-like game for Amiga).

These are two screenshots of the two playable levels:

super-mario-bros

giana-the-sister

The Engine implements all the needed stuff:

These are the IOCCC Selected Judges Remarks about this program:

"A classic for a particular generation. Like all good programs, being data driven means you can do fun things in small spaces."

Here you can download the obfuscated sourcecode. If you open the file with and see some ugly alignment, set the TAB WIDTH of your text editor equal to 4. :-)

Here you can download the not obfuscated sourcecode. The code is already unreadable due to the shrink in sizes and due to the multiple rewrite steps (needed to simplify all the internal logic of the Engine).

Here you can read the official IOCCC winning entry description.

Most tweetable entry

The second winning entry is very little. This is the program full sourcecode:

d=80,e,j;g(){j+=getchar();}main(a,b)char**b;{for(;;){j=0;g();if(j<0)break;g(g());putchar(b[1][j/3*strlen(b[1])>>8]);if(!(++e%d))puts("");}}

There is also a shortest version of the same program, with a simplified logic:

d=80,e,j;g(){j+=getchar();}main(){for(;;){j=0;g();if(j<0)break;g(g());putchar(" .:#@"[j/3*5>>8]);if(!(++e%d))puts("");}}

What the hell do the program do?

monna-lisa

The program convert the image given in input to an ASCII ART!

These are the IOCCC Selected Judges Remarks about this program:

"On the face of it :-) given what this program one might wonder what makes this winner special. But when you realize the source is small enough to tweet on twitter you understand.

Who will be the first to tweet this source? How many re-tweets will such tweet get? And how many people will really understand the tweet?"

Here you can read the official IOCCC winning entry description.

...

Now... Really... How much is insanely NERD all of this?

Piano from Terminal

I'm learning to play Piano but my terminal call me.. What about a simple piano visualizer in the terminal?

I need a simple visualizer that highlights piano keys.. I don't need it, really, but its fun to make everythings in the terminal (or not?). This visualizer looks like this:

Piano Screenshot

Coding

I have tried to write this tool with a "simple" bash script but i know C and i am more "productive" with C. So this is the main structure of the program:

/*p[Y][NOTE]
    where p[0] is the top line of the piano
          p[1] is the middle line of the piano
          p[2] is the bottom line of the piano
    foreach p[COLUMN] there are 14 keys for each OCTAVE
        [0] is the C key
        [1] is the C# key
        [2] is the D key
        [3] is the D# key
        [4] is the E key
        [5] is a dummy key for a not existent semitone
        [6] is the F key
        ...
        [12] is the A# key
        [13] is a dummy key for a not existent semitone 
        */
char p[3][14*N_OCT]={0};

//[...]
int main(int argc, char *argv[]) {
    //check argv for arguments

    //for each note in arguments hightlight p[0..2][NOTE]

    //draw all piano keys
}

The trick of using 14 keys instead of the standard 12 is used to calculate a key index, trought octaves, in a simpler way, assuming that each tone has a semitone. This is not true for E-F and B-C intervals but the program will intercept this exceptions and skip the [5] and the [13] dummy keys (not existent semitones).

This is how this trick work:

1) Notes are translated to numbers:

Notes: CDEFGAB
NOTE_INDEX: C=0 D=2 E=4 F=6 G=8 A=10 B=12

2) This formula is used to find the index of a key for a note without alterations:

KEY_INDEX = NOTE_INDEX(NOTE)*2 + (14 * OCTAVE)

3) (optional) code to add a semitone to a KEY_INDEX:

ALTERATED_KEY_INDEX: KEY_INDEX +1
IF (ALTERATED_KEY_INDEX==5 OR 13)
    ALTERATED_KEY_INDEX = ALTERATED_KEY_INDEX +1;

4) (optional) code to add two semitones (##):

two time the first algorithm

5) (optional) code to subtract a semitone (b):

one time the first algorithm with -1 instead of +1

6) (optional) code to subtract two semitones (bb):

two time the subtract of a single semitone

By using The trick of 14 keys, instead of 12, the program is pretty simple. For each note (ex: A2#) passed as an argument, the program will highlight the key using Terminal colors. After highlights of all keys the program draw all 12 keys (skipping the 5 and the 13 dummy keys).

Sourcecode

The full source of this program is here. The program use ANSI ESCAPE CODE to colorize the terminal output, so will run fine on a Linux machine, on Mac OS X or with MinGW on Windows.

Compile

To compile this program you do not need any fancy arguments:

gcc piano.c -o piano

Usage

This program accept a list of notes where each note syntax is

NOTE[OCTAVE][ALTERATION][ALTERATION]

For example if you want to highlight a C# you write C# (or B), if you want a C# on the second octave you write C2# (or B2), if you want a C with two semitones alteration you write C## (or B#).

By default the program will display 3 octaves but you can change that by using the -o (or --octaves) parameters.

The maximum number of octaves supported by the program is 10. You can extend this values by modifing the sourcecode, changing the value of the N_OCT macro.

Ok, this tool is useless... but exists :-D

THEY'RE MADE OUT OF MEAT

I always love to read this short story about "Humans":

"They're made out of meat."

"Meat?"

"Meat. They're made out of meat."

"Meat?"

"There's no doubt about it. We picked up several from different parts of the planet, took them aboard our recon vessels, and probed them all the way through. They're completely meat."

"That's impossible. What about the radio signals? The messages to the stars?"

"They use the radio waves to talk, but the signals don't come from them. The signals come from machines."

"So who made the machines? That's who we want to contact."

"They made the machines. That's what I'm trying to tell you. Meat made the machines."

"That's ridiculous. How can meat make a machine? You're asking me to believe in sentient meat."

"I'm not asking you, I'm telling you. These creatures are the only sentient race in that sector and they're made out of meat."

... continue here.

Author: Terry_Bisson

YouTube from Terminal (Part 2)

This is the second part of the Nerd guide to play Youtube videos from your terminal.

In the first part these bash function has been added to my .bashrc (or .bash_profile on Mac OS X):

function yt {
    mpv --ontop --geometry=320x200+0+0 $(youtube-dl -g -f 18 $1)    
}
#download Youtube video using youtube-dl
function dyt {
    curl $(youtube-dl -g -f 18 $1) -o video.mp4
}

Now, the missing part is to search something and play all results. The follow solution will play all results in sequence. Youtube results are paginated on multiple HTML pages. In this case this script will play only the first page of results (who care.. these NERD scripts are insane):

#search Youtube and play all results
function yts {
    curl "https://www.youtube.com/results?search_query=$(echo $* | sed -E 's/ /%20/g')" -L | grep -o '/watch?[^\"]*' | uniq | grep -v "list=" | while read -r line; do yt "https://www.youtube.com$line"; done;
}

To use this function you only need only to type

yts MY LONG SEARCH STRING

To skip a video that you do not like you need to close mpv window. To terminate the script (looping throught all results) you need to send CTRL-C to the terminal running yts.

If you want to download all files, instead of playing them, you can use dyt instead of yt.

Let's break this function in pieces:

$(echo '$*' | sed -E 's/ /%20/g')

Grab all parameters passed to yts function ($*) and replace all whitespaces with %20 (the space character encoded for HTML URL)

curl "https://www.youtube.com/results?search_query=$(echo '$*' | sed -E 's/ /%20/g')" -L

Download youtube search results, following HTTP redirection (-L)

grep -o '/watch?[^\"]*' | uniq

Extract all /watch?* video URL. Some URL are duplicated so with uniq the output of the command is a list of unique URLs without duplicates

grep -v "list="

Exclude all lines that contains "list="; these lines are for Youtube playlists

while read -r line; do yt "https://www.youtube.com$line"; done;

Loop throught each line. For each line execute yt function to view the video (or dyt if you want to download videos).

Full code for play and search

#play Youtube video using youtube-dl
function yt {
    mpv --ontop --geometry=320x200+0+0 $(youtube-dl -g -f 18 $1)    
}
#download Youtube video using youtube-dl
function dyt {
    curl $(youtube-dl -g -f 18 $1) -o video.mp4
}
#search Youtube and play all results
function yts {
    curl "https://www.youtube.com/results?search_query=$(echo '$*' | sed -E 's/ /%20/g')" -L | grep -o '/watch?[^\"]*' | uniq | grep -v "list=" | while read -r line; do dyt "https://www.youtube.com$line"; done;
}

YouTube from Terminal (Part 1)

Sometimes a NERD watch Youtube without a browser opened. NERDS use text browsers like LYNX or W3M :-D

In the past years i've tryed mps-youtube and youtube-viewer, both are terminal apps that allow you to search, view and download videos from Youtube, but this time i want something more customizable, also based on youtube-dl.

Solution 1: play video from URL

You need only these two tools: youtube-dl and mpv. I think that these are the same tools used by mps-youtube. This solution is quick and dirty.

Installation on Mac (via brew) is easy:

brew install youtube-dl mpv

On Linux, Debian based distros, you can use apt:

apt-get install youtube-dl mpv

After that you can open your video with this command (replace VIDEO_URL with your Youtube video URL):

mpv $(youtube-dl -g -f 18 VIDEO_URL)

The magic number 18 is to select MP4 360p videos. If you want to select others format you can choose from one of these:

MAGIC NUMBER FORMAT RESOLUTION CODECS
171 webm audio only vorbis
140 m4a audio only mp4a
133 mp4 426x240 avc1 video only
134 mp4 640x360 avc1 video only
135 mp4 854x480 avc1 video only
247 webm 1280x720 vp9 video only
136 mp4 1280x720 avc1 video only
248 webm 1920x1080 vp9 video only
137 mp4 1920x1080 avc1 video only
43 webm 640x360 vp8 + vorbis
18 mp4 640x360 avc1 + mp4a
22 mp4 1280x720 avc1 + mp4a

If you want to be lazy in typing commands (like a real NERD needs to be), you can add this function to your .bashrc (or .bash_profile if you use Mac OS X) and use have this solution ready anytime you need to watch videos from terminal:

function yt {
    mpv $(youtube-dl -g -f 18 $1)   
} 

To use this function you only need only to type

yt VIDEO_URL

Download videos

If you want to download videos, instead of playing them, you only need to replace mpv with curl:

function dyt {
    curl $(youtube-dl -g -f 18 $1) -o video.mp4
} 

Picture in Picture alike

When i work on my computer i like to have the video that i am watching on one corner of the screen, possibly on top of the others windows (this mode is normally called PIP: picture in picture). With mpv you can use two parameters to configure the position of the window and the stay-on-top mode:

mpv --ontop --geometry=WIDTHxHEIGHT+X+Y

Add these parameters to your scripts to have mpv play like a PIP!

Experiment without youtube-dl (little more complex)

You don't like to use existent tools. You are a NERD and you like to do everything with a bunch of curl, grep and sed commands. Supposing that you do not wont to rewrite curl or mpv (you dont?), you can use curl to extract the required video URL and play that with mpv:

function ytc {
    mpv $(echo -ne $(curl $1 | grep -o 'https[^\"]*' | grep videoplayback | grep itag%3D18 | sed -E "s/%/\\\\x/g"))
}

This is it. HTML scraping: the worst thing you should do, EVER. Let's break each command apart:

curl $1 | grep -o 'https[^\"]*'

curl youtube page and extract all HTTPS links contained in the page. If you look at the HTML page returned from Youtube, you will see that inside HTML there is a big JSON string that contains all HTTPS URLs for the final video playback. These links contains the videoplayback substring. see screenshot-1

grep videoplayback

select only lines that contains videoplayback substring

grep itag%3D18

select only lines with itag=18 (my preferred format is 18, you can choose others format from the table above). %3D is the character = escaped inside the HTTP URL

sed -E "s/%/\\\\x/g"

convert each HTTP encoded characters from %NN to \xNN. This is the standard C/bash escape for characters expressed as hexadecimal two digit number

echo -ne

echo results converting all \xNN sequences to its ASCII equivalents. After that you obtain the final URL. Something like this: r11---sn-hpa7zn7r.googlevideo.com/videoplayback?initcwndbps=472500&sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cnh%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cupn%2Cexpire&ip=87.8.231.48&key=yt6&mn=sn-hpa7zn7r&signature=23D980F8415F6F313EF422E95BA85AA55FCD22BA.96645A049DC436870F36DD48BFE64DE20283F787&mm=31&ms=au&id=o-AP4my72PmmcNCaYptxcQ92Q3knmzotCfM9FaAHfHAW5E&ei=PAw6WP2GE4HXcPy_haAF&mv=m&mt=1480198892&dur=590.483&lmt=1428034888381069&source=youtube&upn=vncEZvHsRZc&itag=18&requiressl=yes&clen=40049035&nh=IgpwcjA0Lm1pbDAxKgw3Mi4xNC4yMDQuNzM&ipbits=0&ratebypass=yes&pl=19&expire=1480220828&gir=yes&mime=video%2Fmp4

mpv

run mpv, finally

PLEASE NOTE that this solution do not work for all Youtube videos. Use youtube-dl instead, it works better and it is less insane.

Full code

#play Youtube video using youtube-dl
function yt {
    mpv --ontop --geometry=320x200+0+0 $(youtube-dl -g -f 18 $1)    
}
#download Youtube video using youtube-dl
function dyt {
    curl $(youtube-dl -g -f 18 $1) -o video.mp4
}
#play Youtube video without youtube-dl (do not work for all videos) 
function ytc {
    mpv $(echo -ne $(curl $1 | grep -o 'https[^\"]*' | grep videoplayback | grep itag%3D18 | sed -E "s/%/\\\\x/g"))
}
#download Youtube video without youtube-dl (do not work for all videos) 
function ytc {
    curl $(echo -ne $(curl $1 | grep -o 'https[^\"]*' | grep videoplayback | grep itag%3D18 | sed -E "s/%/\\\\x/g")) -o video.mp4
}

Have FUN (or use a normal, more easy, soft clickable, quite adorable WebBrowser like everyone do)