Alive
News Team Current issue History Online Support Download Forum @Pouet

01 - 02 - SE - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14

Alive 12
SPOT LIGHT ON THE 520ST
                                                                                
       A small view into my little screen for the 20 years anniversary 
       demo.

       Well I guess most of the active gurus out there won't be able to 
       learn a lot from this one but for the beginners and apprentice 
       coders on ST out there it might be useful.

       In this short article I want to explain the interlace technique 
       as used in my screen.

       The screen consists of 3 parts, a small intro sequence, a plain 
       palette fade of the Paradize splashscreen. It was prepared with 
       my FADE CALCULATOR tool. Next comes the interlace and a text 
       sequence. The text sequence is very simple and lowtech. It is 
       just displaying the lines of text by waiting 3 VBLs per char. 
       This slows the blit down a bit and gives a standard effect.

       Now for the interlace effect which is supposed to give the 
       impression of a moving spot light on top of the wellknown 520ST. 
       The whole magic consists of 2 pictures which are displayed one 
       after another. The spot is moved on a second picture, fully 
       independant of the main 520ST picture.

       In pseudocode it looks like this:

       1. display 520ST pic with its colors

       2. move the spot on the invisible screen a bit

       3. display the spot pic with its colors and wait a bit

       4. repeat at step 1 until space bar is pressed or a certain 
          amount of frames have been drawn

       By doing a fast exchange of the two pictures, both pictures and 
       their specific colors are interlaced. This means for the human 
       eye there is no way to tell which screen is displayed. The 
       bright spot appears over darker pixels of the background pic and 
       retouching the whole thing into a mixed set of colors which 
       consist partly of the main picture and partly of the spot 
       picture. This flickers a bit but with a wise choice of colors 
       (note to self: mine ain't perfect!) it gives pretty nice results 
       with a "shine through" effect.

       The screen also forces 60Hz for the interlace effect as the 
       flicker is even uglier with 50Hz. No known emulator can cope 
       with interlace effects so use a real machine to view - and a 
       decent monitor or TV with the real thing!     

       For speed reasons I've coded two slightly different routines for 
       machines with and without Blitter chip. The versions have 
       slightly different curves for the spot and mainly different 
       sizes of the light spot.

       And now after reading the boring bits, you may take a look into 
       my crappy sourcecode for this screen. The whole screen is coded 
       in GFABASIC and it was compiled with the GFA compiler. The only 
       direct machine code in this one is the SNDH replay interface, in 
       this case the gwEm one from the Paradize homepage.

       Anyone who learned somehthing from this or who wants more 
       explanations, please contact me via email: Simon Sunnyboy / 
       Paradize <marndt@asmsoftware.de>

       Cheers, stay cool and stay Atari /|\ !
Simon Sunnyboy / Paradize for Alive,2005-12-12
 
Appendix A
Source Code of Spotlight on the 520ST

'
' SPOT LIGHT ON 520ST
' small demoscreen for the 20th years Atari ST anniversary compo
'
' code & main picture by Simon Sunnyboy / Paradize
' font by Minz / Paradize
' chip music by Marcer / Paradize
' splash screen by SH3 / Reservoir Gods
'
' Musik an/aus (fuer Test)
music!=TRUE
'
super%=0
fehler!=FALSE
ON ERROR GOSUB crash
ON BREAK CONT
RESERVE 200000
'
screens%=MALLOC(64256)
logbase%=AND(ADD(screens%,255),&HFFFFFF00)
physbase%=ADD(logbase%,32000)
'
DIM palette(16),r%(15)
DIM x%(359),y%(359)
'
INLINE sndhplay%,186
INLINE sndhtune%,18455
INLINE splashscreen%,32034
INLINE mainpic%,32034
INLINE mainfade%,512
INLINE splashfade%,512
INLINE light%,10274
INLINE font%,10914
'
@test_ste
@resol
@sauve_palette
'
init_blitter
'
initialisation_double_buffer    ! set on the double buffer
super%=GEMDOS(&H20,L:0)         ! go SUPER
syncmode|=BYTE{&HFFFF820A}      ! get old syncmode
keyclick|=BYTE{1156}
BYTE{1156}=0                    ! keyclick off
'
DO
LOOP UNTIL INKEY$=""
'
play_music
'
SETCOLOR 0,0,0,0
'
BMOVE splashfade%,&HFFFF8240,32
BMOVE splashscreen%+34,logbase%,32000
BMOVE splashscreen%+34,physbase%,32000
~XBIOS(5,L:logbase%,L:logbase%,L:-1)
paladdr%=splashfade%
' fade splash in
FOR i%=0 TO 15
  VSYNC
  VSYNC
  VSYNC
  BMOVE paladdr%,&HFFFF8240,32
  ADD paladdr%,32
NEXT i%
'
precalc
'
~XBIOS(5,L:physbase%,L:logbase%,L:-1)
IF blitter!=TRUE
' splash scrolls out on Blitter machines only
  FOR x%=2 TO 26
    y%=0
    FOR yy%=0 TO 24
      RC_COPY physbase%,x%,y%,320-x%,4 TO logbase%,0,y%
      RC_COPY physbase%,0,y%+4,318-x%,4 TO logbase%,x%,y%+4
      ADD y%,8
    NEXT yy%
    flip_screens
  NEXT x%
ELSE
  ~XBIOS(5,L:physbase%,L:physbase%,L:-1)
  CLS
  BMOVE physbase%,logbase%,32000
ENDIF
'
ef!=FALSE
oldw%=359
w%=0
blitter!=FALSE
DO
'
  a$=""
  BMOVE mainpic%+2,&HFFFF8240,32
  BMOVE mainpic%+34,logbase%,32000
  ~XBIOS(5,L:physbase%,L:logbase%,L:-1)
  count%=0
  BYTE{&HFFFF820A}=0      ! force 60Hz
  IF blitter!=TRUE
' BLITTER version
    DO
      ~XBIOS(5,L:logbase%,L:physbase%,L:-1)
'
      oldw%=w%
      INC w%
      IF w%>359
        w%=0
      ENDIF
      INC count%
      RC_COPY light%+34,64,0,lsize%,lsize% TO physbase%,x%(oldw%),y%(oldw%)
      BMOVE mainpic%+2,&HFFFF8240,32
      VSYNC
      a$=INKEY$
      EXIT IF a$>""
      ~XBIOS(5,L:physbase%,L:logbase%,L:-1)
      BMOVE light%+2,&HFFFF8240,32
      RC_COPY light%+34,lx%,0,lsize%,lsize% TO physbase%,x%(w%),y%(w%)
      VSYNC
'
      a$=INKEY$
      EXIT IF a$>""
    LOOP UNTIL count%>438
    IF a$>""
      ef!=TRUE
    ENDIF
  ELSE
' non-BLITTER code
    DO
      ~XBIOS(5,L:logbase%,L:physbase%,L:-1)
      BMOVE mainpic%+2,&HFFFF8240,32
      oldw%=w%
      INC w%
      IF w%>359
        w%=0
      ENDIF
      INC count%
      RC_COPY light%+34,64,0,lsize%,lsize% TO physbase%,x%(oldw%),y%(oldw%)
      VSYNC
      a$=INKEY$
      EXIT IF a$>""
      ~XBIOS(5,L:physbase%,L:logbase%,L:-1)
      BMOVE light%+2,&HFFFF8240,32
      RC_COPY light%+34,lx%,0,lsize%,lsize% TO physbase%,x%(w%),y%(w%)
      VSYNC
      a$=INKEY$
      EXIT IF a$>""
    LOOP UNTIL count%>438
    IF a$>""
      ef!=TRUE
    ENDIF
  ENDIF
  EXIT IF ef!=TRUE
'
  BYTE{&HFFFF820A}=syncmode|      ! restore syncmode
  textpart
'
LOOP
'
stop_music
BYTE{1156}=keyclick|
BYTE{&HFFFF820A}=syncmode|        ! restore syncmode
'
DO
LOOP UNTIL INKEY$=""
'
endit
'
PROCEDURE textpart
  ~XBIOS(5,L:physbase%,L:physbase%,L:-1)
  CLS
  BMOVE physbase%,logbase%,32000
'
  VSYNC
  ~XBIOS(5,L:logbase%,L:logbase%,L:-1)
  FOR i%=1 TO 3
    VSYNC
    BMOVE whitepal%,&HFFFF8240,32
    VSYNC
    VSYNC
    VSYNC
    BMOVE font%+2,&HFFFF8240,32
  NEXT i%
  RESTORE blupp
  FOR ty%=0 TO 10
    READ txt$
    tx%=160-INT(LEN(txt$)*6.5)
    FOR i%=1 TO LEN(txt$)
      VSYNC
      VSYNC
      VSYNC
      draw_char(tx%,ty%*17,MID$(txt$,i%,1))
      ADD tx%,13
    NEXT i%
  NEXT ty%
'
  PAUSE 250
'
  DO
  LOOP UNTIL INKEY$=""
'
RETURN
blupp:
DATA "SPOT LIGHT ON THE 520ST"
DATA "-----------------------"
DATA "A LAME DEMO SCREEN FOR"
DATA "THE 20 YEARS ANNIVERSARY"
DATA "COMPO IN 2005"
DATA " "
DATA "A PROD BY PARADIZE!"
DATA "CODE AND CRAPPY MAINPIC:"
DATA "SIMON SUNNYBOY"
DATA "CHIP MUSIC: MARCER"
DATA "NICE FONT: MINZ"
'
PROCEDURE precalc
  IF blitter!
' Blitter curve
' radius x: 256
' radius y: 136
    FOR w%=0 TO 359
      x%(w%)=(160-32)*COS(w%*PI/180)+(160-32)
      y%(w%)=(100-48)*SIN(w%*PI/180)+(108-32)
    NEXT w%
  ELSE
' non-Blitter curve
    FOR w%=0 TO 359
      x%(w%)=(160-16)*COS(w%*PI/180)+(160-16)
      y%(w%)=(66-24)*SIN(w%*PI/180)+(133-0)
    NEXT w%
  ENDIF
'
  wpal$=""
  FOR i%=0 TO 15
    wpal$=wpal$+MKI$(&HFFFF)
  NEXT i%
  whitepal%=V:wpal$
RETURN
'
PROCEDURE init_blitter
' init some vars for Blitter machines
' we use different blitting sizes and tiles for the light
  IF blitter!=TRUE
    lx%=0
    lsize%=64
  ELSE
    lx%=128
    lsize%=32
  ENDIF
RETURN
'
PROCEDURE endit
  @fin_double_buffer               ! double buffer end
'
  @restore_video_mode
  @restaure_palette
  ~MFREE(screens%)
  RESERVE
  IF fehler!=TRUE
    ~FORM_ALERT(1,fehler$)
  ENDIF
  IF super%<>0
    ~GEMDOS(&H20,L:super%)
  ENDIF
  fin
RETURN
PROCEDURE crash
  fehler!=TRUE
  fehler$=ERR$(ERR)
  endit
RETURN
'
PROCEDURE initialisation_double_buffer
  old_phy%=XBIOS(2)
  old_log%=XBIOS(3)
  VSYNC
  CLS
'
  BMOVE XBIOS(2),logbase%,32000
  BMOVE XBIOS(2),physbase%,32000
'
  ~XBIOS(5,L:physbase%,L:logbase%,W:-1)
RETURN
PROCEDURE fin_double_buffer
  CLS
  ~XBIOS(5,L:old_log%,L:old_phy%,W:-1) ! on remet les anciennes adresses
RETURN
PROCEDURE flip_screens
  ~XBIOS(5,L:physbase%,L:logbase%,L:-1)
  VSYNC
  SWAP physbase%,logbase%
RETURN
PROCEDURE new_video_mode(mode%)
  VOID XBIOS(5,L:-1,L:-1,W:3,W:mode%)
RETURN
PROCEDURE restore_video_mode
  IF falcon!=TRUE
    VOID XBIOS(5,L:-1,L:-1,W:3,old_video_mode%)
  ELSE
    VOID XBIOS(5,L:-1,L:-1,rez%)
  ENDIF
RETURN
FUNCTION cookie_find(id$)
  LOCAL c_ptr%,cname%,c_val%
  c_ptr%=LPEEK(&H5A0)             ! start of list (cookie-jar)
  IF OR(c_ptr%=0,ODD(c_ptr%))
    RETURN 0                      ! error: cookiejar does not exist
  ELSE
    REPEAT
      cname%=LPEEK(c_ptr%)
      c_val%=LPEEK(c_ptr%+4)
      EXIT IF cname%=0            ! end of list
      ADD c_ptr%,8
    UNTIL MKL$(cname%)=id$        ! cookie found
    IF cname%
      RETURN c_val%               ! return its value
    ENDIF
    RETURN -1                     ! jar exists; cookie not found
  ENDIF
ENDFUNC
PROCEDURE test_ste
  a|=PEEK(&HFF820D)
  SPOKE &HFF820D,15
  b|=PEEK(&HFF820D)
  SPOKE &HFF820D,a|
  IF a|<>b|
    blitter!=TRUE
    ste!=TRUE
    falcon!=FALSE
    stf!=FALSE
    IF @cookie_find("_SND")=31
      falcon!=TRUE
      ste!=FALSE
      stf!=FALSE
'      PRINT "falcon detected !"
    ELSE
'     PRINT "STE detected !"
    ENDIF
  ELSE
'  PRINT "STF detected !"
    stf!=TRUE
    falcon!=FALSE
    ste!=FALSE
    blitter!=FALSE
' TODO: Blitter detection
    IF (XBIOS(64,W:-1) AND &H2)>0
      ~XBIOS(64,W:1)
      blitter!=TRUE
    ENDIF
  ENDIF
RETURN
PROCEDURE resol
  rez%=XBIOS(4)
  IF falcon!=TRUE
    old_video_mode%=XBIOS(88,W:-1)                !save old video mode
    new_video_mode(434)                           !go STlow (temporary)
    nb_couleurs_a_sauver|=16
    @sauve_palette
  ELSE
    IF rez%=0
      nb_couleurs_a_sauver|=16
      @sauve_palette
    ENDIF
    IF rez%=1
      nb_couleurs_a_sauver|=4
      @sauve_palette
      VSYNC
      ~XBIOS(5,L:-1,L:-1,W:0)
    ENDIF
    IF XBIOS(4)=2
      @fin
    ENDIF
  ENDIF
RETURN
PROCEDURE sauve_palette
  LOCAL ctr%
  FOR ctr%=0 TO nb_couleurs_a_sauver|-1
    palette(ctr%)=XBIOS(7,W:ctr%,W:-1)
  NEXT ctr%
RETURN
PROCEDURE restaure_palette
  LOCAL ctr%
  FOR ctr%=0 TO nb_couleurs_a_sauver|-1
    SETCOLOR ctr%,palette(ctr%)
  NEXT ctr%
RETURN
PROCEDURE fin
  EDIT
RETURN
'
' SNDH Replayer for GFA
' Original by Swe/YesCrew
' Modified version by gwEm
'
PROCEDURE play_music
  IF music!=TRUE
' Address of the zik in A6
    r%(14)=sndhtune%
' R7: Frequency 200Hz (MusicMon tune here!)
    r%(7)=200
'
    RCALL sndhplay%+28,r%()
  ENDIF
RETURN
PROCEDURE stop_music
  IF music!=TRUE
    RCALL sndhplay%+28+4,r%()
  ENDIF
RETURN
'
' font display
PROCEDURE draw_char(x%,y%,c$)
  LOCAL c|,c1%,c2%,c3%,cx%,cy%
  c|=255
  c1%=ASC(c$)
  c2%=c1%-65
  c3%=c1%-48
  IF c2%>=0 AND c2%<=25
    c|=c2%
  ENDIF
  IF c3%>=0 AND c3%<=9
    c|=c3%+33
  ENDIF
  IF c1%=45
    c|=26
  ENDIF
  IF c1%=33
    c|=27
  ENDIF
  IF c1%=58
    c|=28
  ENDIF
'
  IF c|<255
    cx%=(c| MOD 11)*13
    cy%=INT(c|/11)*17
    RC_COPY font%+34,cx%,cy%,13,17 TO logbase%,x%,y%
  ENDIF
'
RETURN
Alive 12