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
|