35
\$\begingroup\$

Raffaele Cecco is a programmer who produced some of the best video games for the ZX Spectrum computer in the late eighties. Among others, he developed the highly acclaimed Cybernoid and Exolon.

Raffaele is turning 50 on May 10, 2017. This challenge is a small tribute to him, for the happy hours that many of us spent playing those terrific games, and for the motivation they brought.

The challenge

The purpose is to produce a rectangular marquee inspired by that seen in Cybernoid's main menu screen, but in ASCII art.

Specifically, the string "Happy birthday Raffaele Cecco " (note the final space) will be shown rotating along the edges of an 12×5 rectangle, with a constant pause time between snapshots.

For example, assuming the text is displayed clockwise and rotated counter-clockwise (see options below), here are three consecutive snapshots of the rectangular marquee:

Happy birthd
           a
o          y
c           
ceC eleaffaR

then

appy birthda
H          y

o          R
cceC eleaffa

then

ppy birthday
a           
H          R
           a
occeC eleaff

and so on.

Rules

No input will be taken. Output will be through STDOUT or equivalent, or in a graphical window.

The output should actually depict the text rotating; that is, each new snapshot should overwrite the previous one to give the impression of movement. This can be done by any means, for example, by writing the appropriate number of newlines to effectively clear the screen. It's acceptable if this is valid only for a given screen size; just specify it in the answer.

The following options are accepted:

  • Text can be displayed clockwise or counter-clockwise, and can be rotated clockwise or counter-clockwise (the example snapshots above assume clockwise displaying and counter-clockwise rotating).
  • Rotation should go on cyclically in an infinite loop (until the program is stopped), and can start at any phase.
  • Pause time between snapshots should be approximately constant, but can be freely chosen between 0.1 and 1 s. An initial pause before displaying the first snapshot is acceptable.
  • Letters can be upper-case, lower-case or mixed case (as in the example above).
  • Leading or trailing blank space is allowed.

Programs or functions are allowed, in any programming language. Standard loopholes are forbidden.

If possible, please provide a gif file showing the output, or a link to test the program.

Shortest code in bytes wins.

\$\endgroup\$
4
  • 4
    \$\begingroup\$ What if it´s impossible to overwrite? Can we use 99 red balloons er ... newlines? \$\endgroup\$
    – Titus
    Commented May 9, 2017 at 17:37
  • \$\begingroup\$ @Titus Only if that effectively clears the screen and gives the impression of moving text (gif please!) \$\endgroup\$
    – Luis Mendo
    Commented May 9, 2017 at 17:40
  • \$\begingroup\$ "This can be done by any means, for example, by writing the appropriate number of newlines to effectively clear the screen." - isn't this dependant on the console size? Is it acceptable to print one newline if it (along with the next rectangle) means the next iteration replaces the previous one (in my small console)? \$\endgroup\$ Commented May 9, 2017 at 18:44
  • 2
    \$\begingroup\$ @Jonathan Ok, just provide a gif with that console to see the effect \$\endgroup\$
    – Luis Mendo
    Commented May 9, 2017 at 18:56

14 Answers 14

17
\$\begingroup\$

HTML + ES6, 200 bytes

<pre id=o><script>setInterval(_=>o.innerHTML=(f=k=>k--?f(k)+(k<11?s[k]:k>47?s[74-k]:k%12?++k%12?' ':s[10+k/12]+`
`:s[30-k/12]):'')(60,s=s.slice(1)+s[0]),99,s="Happy birthday Raffaele Cecco ")</script>

\$\endgroup\$
3
  • \$\begingroup\$ It looks great! \$\endgroup\$
    – Luis Mendo
    Commented May 9, 2017 at 17:32
  • \$\begingroup\$ @LuisMendo That brings back memories, although I remember Cybernoid II better than the first one. I'm sure I've seen this effect in a couple of cracktros as well. ;-) \$\endgroup\$
    – Arnauld
    Commented May 9, 2017 at 17:38
  • \$\begingroup\$ Yes, I also preferred the second :-) \$\endgroup\$
    – Luis Mendo
    Commented May 9, 2017 at 17:41
11
\$\begingroup\$

ZX Spectrum BASIC, 187 bytes

Annoyed that Philip beat me to it by a couple of minutes :-) Numbers like \{15} are unprintable control codes - compile with zmakebas if you want to tinker. Note that the full rectangle isn't printed immediately, but it falls into place after the first few frames.

1 let a$=" Happy birthday Raffaele Cecco":dim b$(code"\{15}"):dim c$(pi*pi)
3 let b$=a$(sgn pi)+b$:let a$=a$(val"2" to)+a$(sgn pi):print "\{0x16}\{0}\{0}";a$(to code"\{12}")'b$(sgn pi);c$;a$(val"13")'b$(val"2");c$;a$(code"\{14}")'b$(pi);c$;a$(len b$)'b$(val"4" to):go to pi

Try it here (online JS-emulated version, press enter to start)... http://jsspeccy.zxdemo.org/cecco/

You can also save four bytes by clearing the screen between frames instead of doing a PRINT AT, but it's too flickery to be worth it...

1 let a$=" Happy birthday Raffaele Cecco":dim b$(code"\{15}"):dim c$(pi*pi)
3 let b$=a$(sgn pi)+b$:let a$=a$(val"2" to)+a$(sgn pi):cls:print a$(to code"\{12}")'b$(sgn pi);c$;a$(val"13")'b$(val"2");c$;a$(code"\{14}")'b$(pi);c$;a$(len b$)'b$(val"4" to):go to pi
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Ah, but you win by a lot of bytes :-) \$\endgroup\$ Commented May 10, 2017 at 19:03
  • 2
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ Commented May 10, 2017 at 19:15
  • 1
    \$\begingroup\$ Welcome to the game. ZX is always good to see. Nice answer. +1. \$\endgroup\$
    – ElPedro
    Commented May 10, 2017 at 21:44
10
\$\begingroup\$

Jelly, 74  65 bytes

“ÆÇÐÑ÷øœ‘Ṭœṗ⁸ṙ©-¤4421œ?U0¦;"⁷,⁶ẋ⁵¤¤ṁ9¤ȮœS.®ß
“9ɲcḟ#%⁴1t(ŀȷUCOw⁾»Ç

Windows version running in a 6 line high cp-65001 console.
There is a half a second (plus evaluation) pause between iterations:

gif of output

How?

“9ɲcḟ#%⁴1t(ŀȷUCOw⁾»Ç - Main link: no arguments
“9ɲcḟ#%⁴1t(ŀȷUCOw⁾»  - compression of [d( Happy)+d( birthday)+d( Raff)+s(aele)+d( Ce)+d(cc)+s(o)] - d=dictionaryLookup, s=stringEncode.
                     -              = " Happy birthday Raffaele Cecco"
                   Ç - call last link (1) as a monad

“ÆÇÐÑ÷øœ‘Ṭœṗ⁸ṙ©-¤4421œ?U0¦;"⁷,⁶ẋ⁵¤¤ṁ9¤ȮœS.®ß - Link 1, rotate, print, recurse: string s
                ¤                            - nilad followed by link(s) as a nilad:
            ⁸                                -   link's left argument (initially s)
               -                             -   literal -1
             ṙ                               -   rotate left -1 (e.g. "blah" -> "hbla")
              ©                              -   copy to register and yield
“ÆÇÐÑ÷øœ‘                                    - literal: [13,14,15,16,28,29,30]
         Ṭ                                   - untruth: [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1]
          œṗ                                 - partition right at truthy indexes of left
                                             -   chops up the rotated string into 8
                                             -   e.g. [" Happy birth",'d','a','y'," Raffaele Ce",'c','c','o'])
             4421œ?                          - get the 4421st permutation of those items
                                             -   e.g. [" Happy birth",'o','d','c','a','c','y'," Raffaele Ce"]
                         ¦                   - apply to indexes:
                        0                    -   0 (right most)
                       U                     -   upend  (e.g. " Raffaele Ce" -> "eC eleaffaR ")
                                     ¤       - nilad followed by link(s) as a nilad:
                                  ¤          -   nilad followed by link(s) as a nilad:
                                 ¤           -     nilad followed by link(s) as a nilad:
                              ⁶              -       literal space
                                ⁵            -       literal 10
                               ẋ             -       repeat: "          "
                            ⁷                -     literal new line
                             ,               -     pair: ['\n',"          "]
                                     9       -   literal 9
                                    ṁ        -   mould like: ['\n',"          ",'\n',"          ",'\n',"          ",'\n',"          ",'\n']
                           "                 - zip with:
                          ;                  -   concatenation
                                             -     e.g. [" Happy birth\n","o          ","d\n","c          ","a\n","c          ","y\n","eC eleaffaR           ","\n"])
                                      Ȯ      - print and yield
                                         .   - literal 0.5
                                       œS    - after sleeping right seconds yield left
                                          ®  - recall value from register (s rotated by 1)
                                           ß - call this link (1) with the same arity (as a monad)
\$\endgroup\$
0
10
\$\begingroup\$

V, 75 71 70 bytes

4 bytes saved thanks to @DJMcMayhem

iHappy birthd
±± a
o±° y
c±± 
ceC eleaffaR6ògÓÉ {dêjP2Ljjx1Lp5LxkpGd

Here is a TIO link, but note that this will not work on TIO because the program loops infinitely. Try it online!

Since this code contains unprintables, here is a hexdump.

00000000: 6948 6170 7079 2062 6972 7468 640a b1b1  iHappy birthd...
00000010: 2061 0a6f b1b0 2079 0a63 b1b1 200a 6365   a.o.. y.c.. .ce
00000020: 4320 656c 6561 6666 6152 1b36 f267 d3c9  C eleaffaR.6.g..
00000030: 207b 64ea 6a50 324c 166a 6a78 314c 7035   {d.jP2L.jjx1Lp5
00000040: 4c78 6b70 4764                           LxkpGd

The sleep time is 500 milliseconds.

giffy

\$\endgroup\$
5
  • \$\begingroup\$ Can you give a TIO link? \$\endgroup\$
    – Riker
    Commented May 9, 2017 at 19:21
  • \$\begingroup\$ Some tips (not all tested): H| --> {. <C-v>êx --> , and 5L --> } \$\endgroup\$
    – DJMcMayhem
    Commented May 9, 2017 at 20:37
  • \$\begingroup\$ Also, your repchar commands are all using 9 when you could use 10 or 11. For example: change the middle three lines to ±± a, o° y, and c±±<space> \$\endgroup\$
    – DJMcMayhem
    Commented May 9, 2017 at 20:41
  • \$\begingroup\$ @DJMcMayhem Everything works but 5L => }. \$\endgroup\$
    – user41805
    Commented May 10, 2017 at 6:44
  • \$\begingroup\$ @Riker Done, but note that the TIO link cannot show the animation \$\endgroup\$
    – user41805
    Commented May 10, 2017 at 6:45
9
\$\begingroup\$

SVG(HTML5), 267 bytes

<svg width=200 height=90><defs><path id=p d=M40,20h120v50h-120v-50h120v50h-120v-50></defs><text font-size="19" font-family="monospace"><textPath xlink:href=#p>Happy birthday Raffaele Cecco<animate attributeName=startOffset from=340 to=0 dur=5s repeatCount=indefinite>

Well, it is rectangular, and it is a marquee, and it is ASCII text...

\$\endgroup\$
1
  • 1
    \$\begingroup\$ ... and it runs smooooth :-) \$\endgroup\$
    – Luis Mendo
    Commented May 10, 2017 at 15:09
9
\$\begingroup\$

ZX Spectrum BASIC, 274 bytes

Well, someone had to do it. Pedants may wish to disqualify this for being too slow and not having a pause between animations, but I'm claiming a special case here :-)

10 LET m$=" Happy birthday Raffaele Cecco": LET o=0: LET l=LEN m$: LET f=4: LET t=12: LET a=t+f: LET b=27
20 FOR j=SGN PI TO l: LET i=j+o: IF i>l THEN LET i=i-l
40 LET x=(i-SGN PI AND i<=t)+(11 AND i>t AND i<=a)+(b-i AND i>a AND i<=b)
50 LET y=(i-t AND i>t AND i<=a)+(f AND i>a AND i<=b)+(b+f-i AND i>b): PRINT AT y,x;m$(j): NEXT j
80 LET o=o+SGN PI: IF o>=l THEN LET o=o-l
90 GO TO t

Not very golfed either. 274 bytes is the number of bytes saved by the Spectrum to tape when saving this program.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You went to all the trouble of using SGN PI for 1 (saves 5 bytes) but you forgot NOT PI for 0 and VAL for the other constants... \$\endgroup\$
    – Neil
    Commented May 10, 2017 at 19:46
  • 1
    \$\begingroup\$ NOT PI I just missed. Deliberately didn't do VAL as it was slow enough as it was, and VAL is horribly slow. \$\endgroup\$ Commented May 10, 2017 at 19:50
  • 1
    \$\begingroup\$ ZX Basic always gets an upvote from me. No pedantism here. I remember the good old days... Nice answer. \$\endgroup\$
    – ElPedro
    Commented May 10, 2017 at 20:29
7
\$\begingroup\$

PHP, 184 bytes

for($r=" ";++$i;sleep(print chunk_split(str_pad($r,96,"
",0),12)),$r=$k="0")for(;$c="ABCDEFGHIJKWco{zyxwvutsrqpdXL@"[$k];)$r[ord($c)-64]="Happy Birthday Raffaele Cecco "[($i+$k++)%30];

prints 39 newlines to clear the screen; run with -nr.
The actual pause is 1 second; but I sped up the gif.

HappyBirthday

ungolfed

$p = "ABCDEFGHIJKWco{zyxwvutsrqpdXL@";  # (positions for characters)+64 to ASCII
$t = "Happy Birthday Raffaele Cecco ";  # string to rotate
for($r=" ";                     # init result to string
    ++$i;                       # infinite loop
    $r=$k="0")                      # 6. reset $r and $k
{
    for(;$c=$p[$k];)                # 1. loop through positions
        $r[ord($c)-64]=                 # set position in result
        $t[($i+$k++)%30];               # to character in string
    sleep(                          # 5. wait 1 second
        print                       # 4. print
            chunk_split(
            str_pad($r,96,"\n",0)   # 2. pad to 96 chars (prepend 36 newlines)
            ,12)                    # 3. insert newline every 12 characters
        );
}
\$\endgroup\$
0
6
\$\begingroup\$

Python 2, 230 184 bytes

import time
s='Happy birthday Raffaele Cecco '*2
i=0
while[time.sleep(1)]:print'\n'*30+'\n'.join([s[i:i+12]]+[s[i-n]+' '*10+s[i+11+n]for n in 1,2,3]+[s[(i+15)%30:][11::-1]]);i+=1;i%=30

Try it at repl.it

enter image description here

\$\endgroup\$
5
\$\begingroup\$

Python 3, 160 bytes

import time;s="Happy_birthday_Raffaele_Cecco_"
while[time.sleep(1)]:print(s[:12]+'\n%s%%11s'*3%(*s[:-4:-1],)%(*s[12:15],)+'\n'+s[-4:14:-1]+'\n'*30);s=s[1:]+s[0]

Try it online! (No animation)

\$\endgroup\$
1
  • \$\begingroup\$ I kinda knew you would come in and beat me with Python. I was doing so well! At least mine makes use of "bugs" that you can't use with Python 3 :-). Nice answer as always. +1 \$\endgroup\$
    – ElPedro
    Commented May 10, 2017 at 21:27
5
\$\begingroup\$

Python 2, 218 200 190 181 176 bytes

import time;f='Happy birthday Raffaele Cecco '
while[time.sleep(1)]:v=f[::-1];print'\n'*90,f[:12],''.join('\n'+a+' '*10+b for a,b in zip(v[:3],f[12:16])),'\n',v[3:15];f=f[1:]+f[0]

-18 bytes by removing str formatting

-10 bytes, thanks to @Uriel and @ElPedro suggestions

-9 bytes by removing negative indexing

-5 bytes by storing reversed f as v and while condition

repl.it

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can cut the whitespace between while 1: and print and replace the next ; with an (actual) newline. Also f='H... Also f[:1] is actualy f[0]. \$\endgroup\$
    – Uriel
    Commented May 9, 2017 at 20:30
  • \$\begingroup\$ OP states that time can be anything between 0.1 and 1 seconds so why not time.sleep(1) to take it under 200? \$\endgroup\$
    – ElPedro
    Commented May 9, 2017 at 20:32
4
\$\begingroup\$

05AB1E, 43 bytes

[Ž-∊13в.•:=r}ƒyp$γ•™“ŽØ¢© ÿ“.ªN._Ž9¦S.Λ,т.W

What better time to answer a birthday related challenge than on your own birthday. ;)

Outputs and rotates in a similar matter as the challenge description; sleeps for 100 ms in between iterations (could alternatively sleep for 255 ms, 256 ms, or 1 second for the same byte-count by replacing the т with , , or respectively). Prints each iteration as a loose output (so without clearing the console and overwriting).

Try the first \$n\$ iterations online (without sleep).
Or as gif in my local console:
enter image description here

Explanation:

[                        # Loop indefinitely:
 Ž-∊                     #  Push compressed integer 27370
    13в                  #  Convert it to base-13 as list: [12,5,12,5]
 .•:=r}ƒyp$γ•            #  Push compressed string "raffaele cecco "
             ™           #  Titlecase the words: "Raffaele Cecco "
              “ŽØ¢© ÿ“   #  Push compressed string "happy birthday ÿ",
                         #  where `ÿ` is automatically filled with the top of the stack:
                         #   "happy birthday Raffaele Cecco "
                      .ª #  Sentence capitalize it, leaving existing caps intact:
                         #   "Happy birthday Raffaele Cecco "
  N._                    #  Rotate the characters in this string the 0-based loop-index
                         #  amount of times towards the left
 Ž9¦                     #  Push compressed integer 2460
    S                    #  Convert it to a list of digits: [2,4,6,0]
 .Λ                      #  Use the Canvas builtin with these three options
   ,                     #  Pop and print it with trailing newline
 т.W                     #  Sleep for 100 milliseconds

See this 05AB1E tip of mine to understand why “ŽØ¢© ÿ“ is "happy birthday ÿ"; .•:=r}ƒyp$γ• is "raffaele cecco "; Ž-∊ is 27370; Ž9¦ is 2460; and Ž-∊13в is [12,5,12,5].

As for the Canvas builtin: it takes three arguments to draw a shape:

  • Character/string to draw: the potentially rotated "Happy birthday Raffaele Cecco " in this case
  • Length of the lines we'll draw: the list [12,5,12,5]
  • The direction to draw in: [2,4,6,0]. The digits in the range [0,7] each represent a certain direction:
7   0   1
  ↖ ↑ ↗
6 ← X → 2
  ↙ ↓ ↘
5   4   3

So the [2,4,6,0] in this case translates to the directions \$[→,↓,←,↑]\$.

here a step-by-step explanation of the output for the initial state:

Step 1: Draw 12 characters ("Happy birthd") in direction 2→:

Happy birthd

Step 2: Draw 5-1 characters ("ay R") in direction 4↓:

Happy birthd
           a
           y
            
           R

Step 3: Draw 12-1 characters ("ceC eleaffa") in direction 6←:

Happy birthd
           a
           y
            
ceC eleaffaR

Step 4: Draw 5-1 characters ("co H") in direction 0↑:

Happy birthd
           a
o          y
c           
ceC eleaffaR

See this 05AB1E tip of mine for an in-depth explanation of the Canvas builtin.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Happy birthday! \$\endgroup\$
    – Razetime
    Commented Nov 12, 2020 at 13:16
  • 1
    \$\begingroup\$ @Kevin 🎂🍬🌟🎉😊 \$\endgroup\$
    – Luis Mendo
    Commented Nov 12, 2020 at 13:27
  • \$\begingroup\$ @Razetime Thank you. :) \$\endgroup\$ Commented Nov 12, 2020 at 13:31
  • 1
    \$\begingroup\$ @LuisMendo Thank you. :) \$\endgroup\$ Commented Nov 12, 2020 at 13:31
3
\$\begingroup\$

Ruby + GNU Core Utils, 136 bytes

s='Happy birthday Raffaele Cecco '
loop{puts`clear`+s[0,12],(0..2).map{|i|s[~i]+' '*10+s[12+i]},s[15,12].reverse
s=s[1,29]+s[0];sleep 1}
\$\endgroup\$
3
\$\begingroup\$

Python 2, 182 179 173 160 bytes

i="Happy birthday Raffaele Cecco "
while[s for s in i*18**4]:print'\n'*99,'\n'.join([i[:12]]+[i[-z]+' '*10+i[11+z]for z in 1,2,3]+[i[15:-3][::-1]]);i=i[1:]+i[0]

Try it at repl.it

Doesn't work on TIO so my first attempt at using repl.it

Edit Using a "time-wasting" loop to count to 1000000 gives a consistent delay of between 0.1 and 1s on my machine and on repl.it and saves importing time. I guess if you ran it on an old 286 computer with 64MB RAM it may go over the 1 second but I'm pretty sure that's not going to happen. If it does then simply reduce the 1000000 and save me a couple of bytes :-)

Edit 2 -6 for remembering that list comprehensions in Python 2 leak the last value of s so I can use it later and also remembering that pretty well anything other than 0 and "" is truthy. Bugs or features? Don't care. It's saved me 6 bytes :-)

Edit 3 Another 13 by revering the rotation and by using a list comprehension for the middle rows inside the join and changing 3000000 to 40**4. Thanks to @FelixDombek for the last one. Had to lose my list comprehension trick though.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Could you use scientific notation or a power expression for the big number? \$\endgroup\$ Commented May 9, 2017 at 22:04
  • 1
    \$\begingroup\$ Power expression yes, scientific notation no (because it becomes a float, which you can't multiply with strings). \$\endgroup\$
    – L3viathan
    Commented May 9, 2017 at 22:27
  • 3
    \$\begingroup\$ Obligatory 999999 instead of 1000000 for a byte :V \$\endgroup\$
    – Value Ink
    Commented May 10, 2017 at 0:11
  • \$\begingroup\$ Thanks @ValueInk but by using the leaky list comprehension "bug" I actually had to increase to 3000000 and still saved 3 bytes :-) \$\endgroup\$
    – ElPedro
    Commented May 10, 2017 at 20:49
  • \$\begingroup\$ Unfortunately no. @L3viathan is right on that one. \$\endgroup\$
    – ElPedro
    Commented May 10, 2017 at 21:02
2
\$\begingroup\$

ZX81 Z80 machine code, 158 130 bytes

OK so it has a lot of bytes until it is assembled but then it drops to 130 bytes. Not sure if that breaks any rules? Its my first post and only as a guest.

The program uses 'brute force' to display the message rather than clever function use as can be seen from the way it has separate code chunks for the top line, the right hand vertical, the bottom line and the left hand vertical. The animation is achieved by rotating the contents of the message and then just displaying it after a short delay which should be pretty much exactly 0.2 seconds as it waits for 10 frames out of a rate of 50 (for UK spec Zeddys anyway).

I have to credit kmurta for the concept of rotating the message to get the animation - that saved 28 bytes!!!

main    
  ld hl,happyBirthday           ;load the address of the message
  ld de,(D_FILE)                ;load the base of screen memory
  inc de                        ;increase it by one to bypass the $76
  ld bc,12                  ;ready for 12 loops
  ldir                      ;transfer HL to DE 12 times and increase both accordingly
  ex de,hl                  ;put HL into DE (HL was the message position)
  ld b,4                        ;prepare to loop 4 times
  dec hl                        ;decrease HL (screen location) by 1
rightVertical
  push de                       ;save the character position
  ld de,13                  ;load 13 (for the next line)
  add hl,de                 ;add to HL  
  pop de                        ;get the message position back
  ld a,(de)                 ;load the character into A
  ld (hl),a                 ;save it to HL
  inc de                        ;increase the character position
  djnz rightVertical            ;repeat until B = 0
  dec hl                        ;decrease HL (screen location) by 1 to step back from the $76 char
  ld b,11                       ;prepare for 11 loops
lastLine
  ld a,(de)                 ;load the current character into A
  ld (hl),a                 ;save to the screen
  dec hl                        ;decrease the screen position (as we are going backwards)
  inc de                        ;increase character position
  djnz lastLine             ;repeat until B = 0
  ld b,3                        ;get ready for the left vertical
  inc hl                        ;increase the screen position by 1 as we have gone 1 too far to the left and wrapped to the line above
leftVertical
  push de                       ;save the character position
  ld de,13                  ;load 13 (for the next line)
  sbc hl,de                 ;subtract it to move up a line in memory
  pop de                        ;get the character pos back
  ld a,(de)                 ;load the character
  ld (hl),a                 ;save it to the screen
  inc de                        ;next character
  djnz leftVertical         ;repeat until B = 0 
delayCode
  ld   hl,FRAMES                ;fetch timer                 
  ld   a,(hl)                 ;load into A                        
  sub  10                       ;wait 10 full frames (0.2 of a second)
delayLoop        
  cp  (hl)                  ;compare HL to 0
  jr   nz,delayLoop         ;if not 0 then repeat until it is   
shuffleMessage
  ld a, (happyBirthday)     ;load the first character of the message
  push af                       ;save the first character of the message
  ld hl, happyBirthday      ;load the address of the message
  inc hl                        ;increase by one to get the second char
  ld de, happyBirthday      ;load the start of the message
  ld bc, 29                 ;number of times to loop
  ldir                      ;load HL (char 2) into DE (char 1) and repeat
  pop af                        ;get char 1 back    
  ld (de),a                 ;out it at the end of the string
  jr main                       ;repeat
happyBirthday
    DEFB    _H,_A,_P,_P,_Y,__,_B,_I,_R,_T,_H,_D,_A,_Y,__,_R,_A,_F,_F,_A,_E,_L,_E,__,_C,_E,_C,_C,_O,__

Sorry I can't post a link to it running as it is a compiled program in the .P format for EightyOne (or other emulators) or an actual Zeddy if you have a ZXPand or similar to load it.

The .P can be downloaded at http://www.sinclairzxworld.com/viewtopic.php?f=11&t=2376&p=24988#p24988

\$\endgroup\$
3
  • \$\begingroup\$ Nice answer! I was missing one in Z80 machine code :-) And welcome to the site! \$\endgroup\$
    – Luis Mendo
    Commented May 14, 2017 at 22:24
  • \$\begingroup\$ Could you maybe provide a gif of the program running? \$\endgroup\$
    – Luis Mendo
    Commented May 15, 2017 at 1:22
  • \$\begingroup\$ Sorry - I don't have any gif creating software! \$\endgroup\$ Commented May 17, 2017 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.