thank you for your help! SelectBrush() enlightend me this one works even on an Amiga (with PiStorm, I admit) fine.
I use Cls() because I did a star field moving in background. Is it really better to clear only the "old" pixels even from starfield instead of using Cls()?
yet another sinus scroller question
Re: yet another sinus scroller question
It might depend how full of stars it is, but most likely it's better to avoid Cls() still. You'll see the definite answer when you measure time spend on drawing a frame or certain amount of frames with both methods. Use StartTimer() and print GetTimer() to see how many milliseconds it takes to render frame(s). Try to get time spent per frame as low as possible, even small improvements matter when you push tens of frames per second in the final product.
Re: yet another sinus scroller question
I changed the code along your tips, so I don't have to use Cls() anymore. It is faster, that's true. But still too demanding for a real machine. Even in high speed emulation the demo is far to slow....
Code: Select all
; starfield
;@REQUIRE planarama.hwb
@DISPLAY {Width = 640, Height = 500, Mode = "FullScreen"}
@MUSIC 1, "blaizer.mod"
@BRUSH 2,"amigalogo.jpg", {x= 0, y = 0, ScaleWidth = 284, Scaleheight = 120}
@BRUSH 1,"80sfont.png" ; font
CreateFont(1,1,"ABCDEFGHIJKLMNOPQRSTUVWXYZ*%: 0123456789!'()?-/.,",32,34,10)
UseFont(1)
Const #SIZE = 32
Const #HEIGHT = 34
t$ = " * Hi everybody! * : " ..
"This is a first try of coding a demo with HOLLYWOOD-MAL "..
" and it looks quite nice, doesn't it? "
t$ = UpperStr(t$)
tlen = StrLen(t$)
ytable = {}
chars_on_screen = Int(GetAttribute(#DISPLAY, 1, #ATTRWIDTH) / #SIZE) ; no float numbers for tables ;-)
char = {}
text_pos = 0
char_brush = {}
; Render all separate characters in the text as brushes
For Local i = 0 To tlen - 1
Local char$ = MidStr(t$, i, 1)
If Not RawGet(char_brush, char$)
; Just render a brush if it wasn't done earlier
char_brush[char$] = CreateBrush(Nil, #SIZE, #HEIGHT, #BLACK)
SelectBrush(char_brush[char$])
TextOut(0, 0, char$)
EndSelect
EndIf
Next
; table with sinus values for scrolltext
ytable={
50,49,48,47,46,45,44,43,43,42,41,40,39,38,37,37,
36,35,34,33,32,32,31,30,29,28,28,27,26,25,24,24,
23,22,21,21,20,19,19,18,17,17,16,15,15,14,13,13,
12,12,11,11,10,9,9,8,8,7,7,7,6,6,5,5,
4,4,4,3,3,3,2,2,2,2,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,
3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,10,
10,11,11,12,13,13,14,14,15,16,16,17,18,18,19,20,
20,21,22,23,23,24,25,26,26,27,28,29,30,30,31,32,
33,34,34,35,36,37,38,39,40,40,41,42,43,44,45,46,
46,47,48,49,50,51,52,53,53,54,55,56,57,58,59,59,
60,61,62,63,64,65,65,66,67,68,69,69,70,71,72,73,
73,74,75,76,76,77,78,79,79,80,81,81,82,83,83,84,
85,85,86,86,87,88,88,89,89,90,90,91,91,92,92,93,
93,94,94,94,95,95,95,96,96,96,97,97,97,97,98,98,
98,98,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,99,98,98,98,98,98,97,97,
97,97,96,96,96,95,95,95,94,94,93,93,92,92,92,91,
91,90,90,89,88,88,87,87,86,86,85,84,84,83,82,82,
81,80,80,79,78,78,77,76,75,75,74,73,72,71,71,70,
69,68,67,67,66,65,64,63,62,62,61,60,59,58,57,56,
56,55,54,53,52,51,50,50
}
; Create a table item per visible character.
; Store a corresponding brush and location.
For Local i = 0 To chars_on_screen
char[i] = {
brush = char_brush[MidStr(t$, i, 1)],
x = GetAttribute(#DISPLAY, 1, #ATTRWIDTH) + i * #SIZE,
y = 0
}
Next
text_pos = chars_on_screen + 1
star_max_y = GetAttribute(#DISPLAY, 1, #ATTRHEIGHT) + GetAttribute(#DISPLAY, 1, #ATTRWIDTH)/2
star_num = 199
; start values for color bars
bar_y=142
bar_one_y = 10
bar_two_y = 145
bar_max = 145
bar_min = 10
bar_one_dir = 2
bar_two_dir = -2
one_fore=False ; which bar is in front
star_dir = 1 ; direction of star movement
star_dir_x = 1
star_min=-(GetAttribute(#DISPLAY, 1, #ATTRWIDTH)/2)
; the color bars will cycle through these colors
cols = {$F70000, $F72000, $F74100, $F76100, $F78200, $F7A200, $F7C300, $F7E300, $F7F300, $E7F300,
$C6F300, $A5F300, $84F300, $63F300, $42F300, $21F300, $00F300, $00F321, $00F342, $00F363,
$00F384, $00F3A5, $00F3A5, $00F3C6, $00F3E7, $00F3F7, $00E3F7, $00C3F7, $00A2F7, $0082F7,
$0061F7, $0041F7, $0020F7, $0000F7, $2100F7, $4200F7, $6300F7, $8400F7, $A500F7, $C600F7,
$E700F7, $F700F7, $F700E7, $F700C6}
collength = ListItems(cols)
start2 = collength - 1
scroll_col = 0
; prepare starfield
Function p_InitStars()
stars = {}
For Local i = star_min To star_num ;+ (star_min*-1)
stars[i] = {
x = Rnd(GetAttribute(#DISPLAY, 1, #ATTRWIDTH)+star_min*-1),
y = Rnd(star_max_y) + star_max_y,
speed = Rnd(4) + 1,
color = (Rnd(11) + 4) * 0x111111}
Next
EndFunction
Function bar_one()
i = start1
; Box(0,bar_one_y-1,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_one_y+5,#BLACK)
For k = 0 To collength - 2
Line(k * 16, bar_one_y, k * 16 + 15, bar_one_y, cols[i],{Thickness=5})
i = i + 1
If i = collength Then i = 0
Next
Line(k * 16, bar_one_y, GetAttribute(#DISPLAY, 1, #ATTRWIDTH), bar_one_y, cols[i],{Thickness=5})
start1 = start1 + 1
If start1 = collength Then start1 = 0
EndFunction
Function bar_two()
; display lower color bar (reverse direction!)
i = start2
; Box(0,bar_two_y-1,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_two_y+5,#BLACK)
For k = collength * 2 To 1 Step -1
Line(k * 16 + 15, bar_two_y, k * 16,bar_two_y, cols[i],{Thickness=5})
i = i - 1
If i = -1 Then i = collength - 1
Next
Line(18, bar_two_y, 0, bar_two_y, cols[i],{Thickness=5})
start2 = start2 - 1
If start2 = -1 Then start2 = collength - 1
EndFunction
Function sine_scroll()
; DisableLineHook()
SetFillStyle(#FILLCOLOR)
For i = 0 To chars_on_screen
Local x = char[i].x
Local y = char[i].y
; Clear the previous character graphics
Box(x, y, #SIZE, #HEIGHT, #BLACK)
; Calculate new position
x = x - 4
y = ytable[Wrap(Int(x/2), 1, 360)]+(GetAttribute(#DISPLAY, 1, #ATTRHEIGHT)-300)
; Display a character in new position
DisplayBrush(char[i].brush, x, y)
; If a character is out of the screen, position it back to right
; and assign the next character (brush) on it
If x < - #SIZE
x = GetAttribute(#DISPLAY, 1, #ATTRWIDTH)
char[i].brush = char_brush[MidStr(t$, text_pos, 1)]
text_pos = text_pos + 1
; If we're out of text, start over from the beginning
If text_pos = tlen Then text_pos = 0
EndIf
char[i].x = x
char[i].y = y
Next
; Flip
; EnableLineHook()
EndFunction
Function draw_starfield()
; Local bar_front = 2
; DisableLineHook()
; Cls
Box(0,bar_one_y-4,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_one_y+5,#BLACK)
Box(0,bar_two_y-4,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_two_y+5,#BLACK)
sine_scroll()
vy = vy + dir
If vy=range Then dir = -1
If vy=-range Then dir = 1
For i = star_min To star_num
Plot(stars[i].x,stars[i].y,#BLACK)
If stars[i].y >= star_max_y Then stars[i].y = stars[i].y - star_max_y
If stars[i].x <= star_min Then stars[i].x = stars[i].x + GetAttribute(#DISPLAY, 1, #ATTRWIDTH)
stars[i].x = (stars[i].x - (stars[i].speed) * star_dir_x)
stars[i].y = stars[i].y + star_dir * star_dir_x
Plot(stars[i].x, stars[i].y, stars[i].color)
Next
If one_fore= True Then bar_two() Else bar_one()
DisplayBrush(2,#CENTER,20) ; show picture
If one_fore= True Then bar_one() Else bar_two()
bar_one_y = bar_one_y + bar_one_dir
bar_two_y = bar_two_y + bar_two_dir
If bar_one_y >= bar_max
bar_one_dir = -2
bar_two_dir = 2
one_fore = True
EndIf
If bar_one_y <= bar_min
bar_one_dir = 2
bar_two_dir = -2
one_fore = False
EndIf
Flip
Local e = TimerElapsed(1)
Local f = TimerElapsed(2)
If e = True Then star_dir = star_dir * -1
If f = True Then star_dir_x = star_dir_x * -1
If x<=-width Then x=GetAttribute(#DISPLAY, 1, #ATTRWIDTH)
; EnableLineHook()
EndFunction
p_InitStars()
;SetFillStyle(#FILLNONE)
EscapeQuit(True)
PlayMusic(1)
SetInterval(1, draw_starfield, 1000/50) ; run function draw_starfiel() @ 50fps
StartTimer(1,3000)
StartTimer(2,5000)
HidePointer()
DisableLineHook()
BeginDoubleBuffer
Repeat
WaitEvent
Forever
Re: yet another sinus scroller question
a little update for speed winning. Now the starfield is only drawn when visible on screen. gives a little speedup, but still too demanding for an Amiga 1200 with Pistorm...
No use of Cls(), every pixel (at least I hope so ) only drawn when on screen.
No use of Cls(), every pixel (at least I hope so ) only drawn when on screen.
Code: Select all
; starfield
;@REQUIRE planarama.hwb
@DISPLAY {Width = 640, Height = 500, Mode = "FullScreen"}
@MUSIC 1, "blaizer.mod"
@BRUSH 2,"amigalogo.jpg", {x= 0, y = 0, ScaleWidth = 284, Scaleheight = 120}
@BRUSH 1,"80sfont.png" ; font
CreateFont(1,1,"ABCDEFGHIJKLMNOPQRSTUVWXYZ*%: 0123456789!'()?-/.,",32,34,10)
UseFont(1)
Const #SIZE = 32
Const #HEIGHT = 34
t$ = " * Hi everybody! * : " ..
"This is a first try of coding a demo with HOLLYWOOD-MAL "..
" and it looks quite nice, doesn't it? "
t$ = UpperStr(t$)
tlen = StrLen(t$)
ytable = {}
chars_on_screen = Int(GetAttribute(#DISPLAY, 1, #ATTRWIDTH) / #SIZE) ; no float numbers for tables ;-)
char = {}
text_pos = 0
char_brush = {}
; Render all separate characters in the text as brushes
For Local i = 0 To tlen - 1
Local char$ = MidStr(t$, i, 1)
If Not RawGet(char_brush, char$)
; Just render a brush if it wasn't done earlier
char_brush[char$] = CreateBrush(Nil, #SIZE, #HEIGHT, #BLACK)
SelectBrush(char_brush[char$])
TextOut(0, 0, char$)
EndSelect
EndIf
Next
; table with sinus values for scrolltext
ytable={
50,49,48,47,46,45,44,43,43,42,41,40,39,38,37,37,
36,35,34,33,32,32,31,30,29,28,28,27,26,25,24,24,
23,22,21,21,20,19,19,18,17,17,16,15,15,14,13,13,
12,12,11,11,10,9,9,8,8,7,7,7,6,6,5,5,
4,4,4,3,3,3,2,2,2,2,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,
3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,10,
10,11,11,12,13,13,14,14,15,16,16,17,18,18,19,20,
20,21,22,23,23,24,25,26,26,27,28,29,30,30,31,32,
33,34,34,35,36,37,38,39,40,40,41,42,43,44,45,46,
46,47,48,49,50,51,52,53,53,54,55,56,57,58,59,59,
60,61,62,63,64,65,65,66,67,68,69,69,70,71,72,73,
73,74,75,76,76,77,78,79,79,80,81,81,82,83,83,84,
85,85,86,86,87,88,88,89,89,90,90,91,91,92,92,93,
93,94,94,94,95,95,95,96,96,96,97,97,97,97,98,98,
98,98,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,99,98,98,98,98,98,97,97,
97,97,96,96,96,95,95,95,94,94,93,93,92,92,92,91,
91,90,90,89,88,88,87,87,86,86,85,84,84,83,82,82,
81,80,80,79,78,78,77,76,75,75,74,73,72,71,71,70,
69,68,67,67,66,65,64,63,62,62,61,60,59,58,57,56,
56,55,54,53,52,51,50,50
}
; Create a table item per visible character.
; Store a corresponding brush and location.
For Local i = 0 To chars_on_screen
char[i] = {
brush = char_brush[MidStr(t$, i, 1)],
x = GetAttribute(#DISPLAY, 1, #ATTRWIDTH) + i * #SIZE,
y = 0
}
Next
text_pos = chars_on_screen + 1
star_max_y = GetAttribute(#DISPLAY, 1, #ATTRHEIGHT) + GetAttribute(#DISPLAY, 1, #ATTRWIDTH)/2
star_num = 199
; start values for color bars
bar_y=142
bar_one_y = 10
bar_two_y = 145
bar_max = 145
bar_min = 10
bar_one_dir = 2
bar_two_dir = -2
one_fore=False ; which bar is in front
star_dir = 1 ; direction of star movement
star_dir_x = 1
star_min=(GetAttribute(#DISPLAY, 1, #ATTRWIDTH)/2)*-1
; the color bars will cycle through these colors
cols = {$F70000, $F72000, $F74100, $F76100, $F78200, $F7A200, $F7C300, $F7E300, $F7F300, $E7F300,
$C6F300, $A5F300, $84F300, $63F300, $42F300, $21F300, $00F300, $00F321, $00F342, $00F363,
$00F384, $00F3A5, $00F3A5, $00F3C6, $00F3E7, $00F3F7, $00E3F7, $00C3F7, $00A2F7, $0082F7,
$0061F7, $0041F7, $0020F7, $0000F7, $2100F7, $4200F7, $6300F7, $8400F7, $A500F7, $C600F7,
$E700F7, $F700F7, $F700E7, $F700C6}
collength = ListItems(cols)
start2 = collength - 1
scroll_col = 0
; prepare starfield
Function p_InitStars()
stars = {}
For Local i = star_min To star_num ;+ (star_min*-1)
stars[i] = {
x = Rnd(GetAttribute(#DISPLAY, 1, #ATTRWIDTH)+star_min*-1),
y = Rnd(star_max_y) + star_max_y,
speed = Rnd(4) + 1,
color = (Rnd(11) + 4) * 0x111111}
Next
EndFunction
Function bar_one()
i = start1
; Box(0,bar_one_y-1,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_one_y+5,#BLACK)
For k = 0 To collength - 2
Line(k * 16, bar_one_y, k * 16 + 15, bar_one_y, cols[i],{Thickness=5})
i = i + 1
If i = collength Then i = 0
Next
Line(k * 16, bar_one_y, GetAttribute(#DISPLAY, 1, #ATTRWIDTH), bar_one_y, cols[i],{Thickness=5})
start1 = start1 + 1
If start1 = collength Then start1 = 0
EndFunction
Function bar_two()
; display lower color bar (reverse direction!)
i = start2
; Box(0,bar_two_y-1,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_two_y+5,#BLACK)
For k = collength * 2 To 1 Step -1
Line(k * 16 + 15, bar_two_y, k * 16,bar_two_y, cols[i],{Thickness=5})
i = i - 1
If i = -1 Then i = collength - 1
Next
Line(18, bar_two_y, 0, bar_two_y, cols[i],{Thickness=5})
start2 = start2 - 1
If start2 = -1 Then start2 = collength - 1
EndFunction
Function sine_scroll()
; DisableLineHook()
SetFillStyle(#FILLCOLOR)
For i = 0 To chars_on_screen
Local x = char[i].x
Local y = char[i].y
; Clear the previous character graphics
Box(x, y, #SIZE, #HEIGHT, #BLACK)
; Calculate new position
x = x - 4
y = ytable[Wrap(Int(x/2), 1, 360)]+(GetAttribute(#DISPLAY, 1, #ATTRHEIGHT)-300)
; Display a character in new position
DisplayBrush(char[i].brush, x, y)
; If a character is out of the screen, position it back to right
; and assign the next character (brush) on it
If x < - #SIZE
x = GetAttribute(#DISPLAY, 1, #ATTRWIDTH)
char[i].brush = char_brush[MidStr(t$, text_pos, 1)]
text_pos = text_pos + 1
; If we're out of text, start over from the beginning
If text_pos = tlen Then text_pos = 0
EndIf
char[i].x = x
char[i].y = y
Next
; Flip
; EnableLineHook()
EndFunction
Function draw_starfield()
; Local bar_front = 2
; DisableLineHook()
; Cls
Box(0,bar_one_y-4,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_one_y+5,#BLACK)
Box(0,bar_two_y-4,GetAttribute(#DISPLAY, 1, #ATTRWIDTH),bar_two_y+5,#BLACK)
vy = vy + dir
If vy=range Then dir = -1
If vy=-range Then dir = 1
For i = star_min To star_num
Plot(stars[i].x,stars[i].y,#BLACK)
If stars[i].y >= star_max_y Then stars[i].y = stars[i].y - star_max_y
If stars[i].x <= star_min Then stars[i].x = stars[i].x + GetAttribute(#DISPLAY, 1, #ATTRWIDTH)
stars[i].x = (stars[i].x - (stars[i].speed) * star_dir_x)
stars[i].y = stars[i].y + star_dir * star_dir_x
If stars[i].x>=0 And stars[i].x<=GetAttribute(#DISPLAY, 1, #ATTRWIDTH) And stars[i].y>=0 And stars[i].y<=GetAttribute(#DISPLAY, 1, #ATTRHEIGHT)
Plot(stars[i].x, stars[i].y, stars[i].color)
EndIf
Next
sine_scroll()
If one_fore= True Then bar_two() Else bar_one()
DisplayBrush(2,#CENTER,20) ; show picture
If one_fore= True Then bar_one() Else bar_two()
bar_one_y = bar_one_y + bar_one_dir
bar_two_y = bar_two_y + bar_two_dir
If bar_one_y >= bar_max
bar_one_dir = -2
bar_two_dir = 2
one_fore = True
EndIf
If bar_one_y <= bar_min
bar_one_dir = 2
bar_two_dir = -2
one_fore = False
EndIf
Flip
Local e = TimerElapsed(1)
Local f = TimerElapsed(2)
If e = True Then star_dir = star_dir * -1
If f = True Then star_dir_x = star_dir_x * -1
If x<=-width Then x=GetAttribute(#DISPLAY, 1, #ATTRWIDTH)
; EnableLineHook()
EndFunction
p_InitStars()
;SetFillStyle(#FILLNONE)
EscapeQuit(True)
PlayMusic(1)
SetInterval(1, draw_starfield, 1000/50) ; run function draw_starfiel() @ 50fps
StartTimer(1,3000)
StartTimer(2,5000)
HidePointer()
DisableLineHook()
BeginDoubleBuffer
Repeat
WaitEvent
Forever