Here is the code for the "wicked" scroller
'================================================================= ' By: Scott Shaver '================================================================= Strict Framework BRL.GlMax2D Import BRL.System Import BRL.Basic Import BRL.Retro Import BRL.Max2D Import BRL.pngloader Graphics 640,480,32',60 '================================================================= Incbin "mom_child.png" Global mom:TImage = LoadImage("incbin::mom_child.png") Global momImage:LineImage = LineImage.Create(mom)',0,255,255,255) momImage.SetColorFunction(SetMomDrawColor) ' use this function to set the color when drawing Incbin "hansolo_crisp.png" Global font:TImage = LoadAnimImage("incbin::hansolo_crisp.png",32,32,0,128,FILTEREDIMAGE|MASKEDIMAGE|DYNAMICIMAGE) Global lif:LineImageFont = LineImageFont.Create(font,0,0,0,90,-1) lif.SetColorFunction(SetFontDrawColor) ' use this function to set the color when drawing 'lif.SetCoordFunction(SetFontCoordOffset) ' use this function to modify the draw coords Incbin "hbar.png" Global hbar:TImage = LoadImage("incbin::hbar.png") MidHandleImage(hbar) Global ang:Double=0 Global ang2:Double=0 Global tilt:Float=0'.5 Global tiltOff:Float=.01 Global scrollerx:Float=GraphicsWidth() SetClsColor(100,100,200) 'lif.rotate(0,75,0) '================================================================= While Not KeyHit(KEY_ESCAPE) Cls SetScale(1,1) 'lif.DrawFont(tilt,False,0,0) lif.rotate(4,0,0) SetScale(1,1) 'momImage.Draw(320+Cos(ang2)*220,240+Sin(ang2)*140,tilt,False) 'momImage.rotate(0,0,1) ang:+4 ang2:+1 'tilt:+tiltOff 'If tiltOff>0 And tilt>1 Then tiltOff=-.01 'If tiltOff<0 And tilt<-1 Then tiltOff=.01 Local msg:String = " WICKED SCROLLER! BROUGHT TO YOU BY ZPARTICLE! I HAVE ONLY EVER SEEN THIS IN ONE DEMO AND I THOUGHT IT WAS TOTALLY COOL! " lif.DrawString(scrollerx,GraphicsHeight()/2,msg,0,0,0) If scrollerx<=-Len(msg)*32 Then scrollerx=GraphicsWidth() scrollerx:-1 Flip Wend End '================================================================= Function SetMomDrawColor(x:Int,y:Int,z:Int) SetColor(Abs(255*Cos(x+ang2)),Abs(255*Sin(y+ang2)),Abs(255*Cos(y+ang2))) End Function '================================================================= Function SetFontDrawColor(x:Int,y:Int,z:Int) 'SetColor(Abs(255*Cos(y+ang)),Abs(255*Sin(y+ang)),Abs(255*Cos(y+ang))) SetColor(175+(5*z),175+(5*z),50+(5*z)) End Function '================================================================= Function SetFontCoordOffset(x:Double Var,y:Double Var) x :+ Sin(y/.25+ang)*4 End Function '================================================================= ' this type holds the coordinates for a line segment '================================================================= Type Line Field x1:Double,y1:Double,x2:Double,y2:Double,z1:Double=15,z2:Double=15 Field SetDrawColor(x:Int,y:Int,z:Int) = Null Field SetCoordOffset(x:Double Var,y:Double Var) = Null Method compare:Int(o:Object) Local s:Line = Line(o) If Not s Then Return 1 Return z1 - s.z1 End Method Method SetColorFunction(SetDrawColor(x:Int,y:Int,z:Int)) self.SetDrawColor = SetDrawColor End Method Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var)) self.SetCoordOffset = SetCoordOffset End Method Function Create:Line(x1:Double,y1:Double,x2:Double,y2:Double) Local rval:Line = New Line rval.x1=x1 rval.y1=y1 rval.x2=x2 rval.y2=y2 Return rval End Function '-------------------------------------------------------- ' rotate a point around the origin, we rotate in the following order x,y,z ' xa,ya,za - The angle To rotate the point from its current position, in degrees Method rotate(xa:Double,ya:Double,za:Double) Local xx:Double = Cos(ya) * Cos(za) Local xy:Double = (Sin(xa) * Sin(ya) *Cos(za)) - (Cos(xa) * Sin(za)) Local xz:Double = (Cos(xa) * Sin(ya) *Cos(za)) + (Sin(xa) * Sin(za)) Local yx:Double = Cos(ya) * Sin(za) Local yy:Double = (Cos(xa) * Cos(za)) + (Sin(xa) * Sin(ya) * Sin(za)) Local yz:Double = (-Sin(xa) * Cos(za)) + (Cos(xa) * Sin(ya) * Sin(za)) Local zx:Double = -Sin(ya) Local zy:Double = Sin(xa) * Cos(ya) Local zz:Double = Cos(xa) * Cos(ya) Local nx:Double = (x1*xx)+(y1*xy)+(z1*xz) Local ny:Double = (x1*yx)+(y1*yy)+(z1*yz) Local nz:Double = (x1*zx)+(y1*zy)+(z1*zz) x1=nx y1=ny z1=nz nx = (x2*xx)+(y2*xy)+(z2*xz) ny = (x2*yx)+(y2*yy)+(z2*yz) nz = (x2*zx)+(y2*zy)+(z2*zz) x2=nx y2=ny z2=nz End Method '-------------------------------------------------------- ' rotate a point around the origin, we rotate in the following order x,y,z ' xa,ya,za - The angle To rotate the point from its current position, in degrees Method TempRotate(xa:Double,ya:Double,za:Double,x1:Double Var,y1:Double Var,z1:Double Var,x2:Double Var,y2:Double Var,z2:Double Var) Local xx:Double = Cos(ya) * Cos(za) Local xy:Double = (Sin(xa) * Sin(ya) *Cos(za)) - (Cos(xa) * Sin(za)) Local xz:Double = (Cos(xa) * Sin(ya) *Cos(za)) + (Sin(xa) * Sin(za)) Local yx:Double = Cos(ya) * Sin(za) Local yy:Double = (Cos(xa) * Cos(za)) + (Sin(xa) * Sin(ya) * Sin(za)) Local yz:Double = (-Sin(xa) * Cos(za)) + (Cos(xa) * Sin(ya) * Sin(za)) Local zx:Double = -Sin(ya) Local zy:Double = Sin(xa) * Cos(ya) Local zz:Double = Cos(xa) * Cos(ya) Local nx:Double = (x1*xx)+(y1*xy)+(z1*xz) Local ny:Double = (x1*yx)+(y1*yy)+(z1*yz) Local nz:Double = (x1*zx)+(y1*zy)+(z1*zz) x1=nx y1=ny z1=nz nx = (x2*xx)+(y2*xy)+(z2*xz) ny = (x2*yx)+(y2*yy)+(z2*yz) nz = (x2*zx)+(y2*zy)+(z2*zz) x2=nx y2=ny z2=nz End Method Method Draw(x:Double,y:Double,tilt:Float, angle:Double=0) Global lasty:Double=-1 Local x1:Double = self.x1 Local y1:Double = self.y1 Local z1:Double = self.z1 Local x2:Double = self.x2 Local y2:Double = self.y2 Local z2:Double = self.z2 If angle<>0 Then TempRotate(angle,0,0,x1,y1,z1,x2,y2,z2) If SetDrawColor<>Null Then SetDrawColor(x1+x,y1+y,z1) EndIf Local dx:Double = x1+x+(tilt*y1) Local dy:Double = y1+y If Abs(lasty-dy)>1 Then 'fill gaps between lines when wrapped around origin If SetCoordOffset<>Null Then SetCoordOffset(dx,dy) ScaleDrawRect(dx,dy-1,x2-x1,1) EndIf If SetCoordOffset<>Null Then SetCoordOffset(dx,dy) ScaleDrawRect(dx,dy,x2-x1,1) End Method Function ScaleDrawRect(x:Double,y:Double,w:Double,h:Double) Local sx:Float,sy:Float GetScale(sx,sy) If sx*x>GraphicsWidth() Or sy*y>GraphicsHeight() Then Return DrawRect(sx*x,sy*y,w,h) End Function Method DrawByPixel(x:Double,y:Double,tilt:Double) Local deltax:Double= Abs(x2 - x1) ' The difference between the x's Local deltay:Double= Abs(y2 - y1) ' The difference between the y's Local lx:Double= x1 ' Start x off at the first pixel Local ly:Double= y1 ' Start y off at the first pixel Local xinc1:Double= 0 Local yinc1:Double= 0 Local xinc2:Double= 0 Local yinc2:Double= 0 Local numadd:Double= 0 Local numpixels:Double= 0 Local den:Double= 0 Local num:Double= 0 If x2 >= x1 Then ' The x-values are increasing xinc1 = 1 xinc2 = 1 Else ' The x-values are decreasing xinc1 = -1 xinc2 = -1 EndIf If y2 >= y1 Then ' The y-values are increasing yinc1 = 1 yinc2 = 1 Else ' The y-values are decreasing yinc1 = -1 yinc2 = -1 EndIf If deltax >= deltay Then ' There is at least one x-value For every y-value xinc1 = 0 ' Don't change the x when numerator >= denominator yinc2 = 0 ' Don't change the y for every iteration den = deltax num = deltax / 2 numadd = deltay numpixels = deltax ' There are more x-values than y-values Else ' There is at least one y-value For every x-value xinc2 = 0 ' Don't change the x for every iteration yinc1 = 0 ' Don't change the y when numerator >= denominator den = deltay num = deltay / 2 numadd = deltax numpixels = deltay ' There are more y-values than x-values EndIf For Local curpixel:Int = 0 To numpixels If SetDrawColor<>Null Then SetDrawColor(x1+x,y1+y,z1) EndIf Local dx:Double = lx+x-(y1*tilt) Local dy:Double = ly+y If SetCoordOffset<>Null Then SetCoordOffset(dx,dy) ScaleDrawRect(dx,dy,1,1) ' draw the current pixel num :+ numadd ' Increase the numerator by the top of the fraction If num >= den Then ' Check If numerator >= denominator num :- den ' Calculate the New numerator value lx :+ xinc1 ' Change the x as appropriate ly :+ yinc1 ' Change the y as appropriate EndIf lx :+ xinc2 ' Change the x as appropriate ly :+ yinc2 ' Change the y as appropriate Next End Method End Type '================================================================= ' an image made of line segments '================================================================= Type LineImage Field lines:Line[] = New Line[0] Field width:Int = 0 Field height:Int = 0 Field lineCount:Int = 0 Field bar:Byte=False Method SetColorFunction(SetDrawColor(x:Int,y:Int,z1:Int)) For Local l:Int = 0 Until lineCount lines[l].SetColorFunction(SetDrawColor) Next End Method Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var)) For Local l:Int = 0 Until lineCount lines[l].SetCoordFunction(SetCoordOffset) Next End Method Method Draw(x:Double,y:Double,tilt:Double,pixel:Byte=True,angle:Double=0,inc:Double=0) lines.sort() If pixel=True Then For Local l:Int = 0 Until lineCount lines[l].DrawByPixel(x,y,tilt) Next Else Local drawBar:Byte=True For Local l:Int = 0 Until lineCount If bar=True And lines[l].z1>0 And drawBar=True Then Local sx:Float,sy:Float GetScale(sx,sy) drawBar=False SetColor(50,50,255) DrawImageRect(hbar,sx*x,sy*y,sx*width,sy*ImageHeight(hbar)) EndIf lines[l].Draw(x,y,tilt,angle+(inc*l)) Next If bar=True And drawBar=True Then Local sx:Float,sy:Float GetScale(sx,sy) drawBar=False SetColor(50,50,255) DrawImageRect(hbar,sx*x,sy*y,sx*width,sy*ImageHeight(hbar)) EndIf EndIf End Method '-------------------------------------------------------- ' rotate a point around the origin, we rotate in the following order x,y,z ' xa,ya,za - The angle To rotate the point from its current position, in degrees Method rotate(xa:Double,ya:Double,za:Double) For Local l:Int = 0 Until lineCount lines[l].rotate(xa,ya,za) Next End Method Function Create:LineImage(image:TImage,frame:Int=0,r:Int=0,g:Int=0,b:Int=0,angle:Double=0,inc:Double=0) Local rval:LineImage = New LineImage Local pm:TPixmap = LockImage( image,frame) rval.width = PixmapWidth(pm) rval.height = PixmapHeight(pm) Local started:Byte=False Local sx:Int=-1 Local ex:Int=-1 For Local y:Int = 0 Until rval.height started=False sx=-1 ex=-1 For Local x:Int = 0 Until rval.width Local pix:Int = pm.ReadPixel(x,y) If started=False And (pix & $FF000000)<>0 And (pix & $00FFFFFF) | (r Shl 16|g Shl 8|b) <> 0 Then ' found SOL started=True sx = x Else If started=True And ((pix & $FF000000)=0 Or (pix & $00FFFFFF) | (r Shl 16|g Shl 8|b) = 0) Then ' found EOL ex = x-1 EndIf If started=True And ex<>-1 Then Local l:Line = Line.Create(sx-(rval.width/2),y-(rval.height/2),ex-(rval.width/2),y-(rval.height/2)) If angle<>0 Or inc<>0 Then l.rotate(angle+(inc*y),0,0) rval.lines = rval.lines[..(rval.lineCount+1)] rval.lines[rval.lineCount]=l rval.lineCount:+1 started=False sx=-1 ex=-1 EndIf Next If started=True And ex=-1 Then ex=rval.width-1 Local l:Line = Line.Create(sx-(rval.width/2),y-(rval.height/2),ex-(rval.width/2),y-(rval.height/2)) If angle<>0 Or inc<>0 Then l.rotate(angle+(inc*y),0,0) rval.lines = rval.lines[..(rval.lineCount+1)] rval.lines[rval.lineCount]=l rval.lineCount:+1 EndIf Next UnlockImage(image,frame) Return rval End Function End Type '================================================================= ' a font made of LineImage objects '================================================================= Type LineImageFont Field chars:LineImage[] = New LineImage[256] Method SetColorFunction(SetDrawColor(x:Int,y:Int,z:Int)) For Local c:Int = 0 To 127 chars[c].SetColorFunction(SetDrawColor) Next End Method Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var)) For Local l:Int = 0 To 127 chars[l].SetCoordFunction(SetCoordOffset) Next End Method '-------------------------------------------------------- ' rotate a point around the origin, we rotate in the following order x,y,z ' xa,ya,za - The angle To rotate the point from its current position, in degrees Method rotate(xa:Double,ya:Double,za:Double) For Local l:Int = 0 To 127 chars[l].rotate(xa,ya,za) Next End Method Function Create:LineImageFont(image:TImage,r:Int=0,g:Int=0,b:Int=0,angle:Double,inc:Double) Local rval:LineImageFont = New LineImageFont For Local c:Int = 0 To 127 rval.chars[c] = LineImage.Create(image,c,r,g,b,angle,inc) rval.chars[c].bar=True Next Return rval End Function Method DrawFont(tilt:Float=0,pixel:Byte=True,angle:Double=0,inc:Double=0) For Local y:Int=0 To 15 For Local x:Int = 0 To 15 If chars[(y*16)+x]<>Null Then chars[(y*16)+x].Draw((x+1)*chars[0].width,(y+1)*(chars[0].height+20),tilt,pixel,angle,inc) EndIf Next Next End Method Method DrawString(x:Int,y:Int,msg:String,tilt:Float=0,angle:Double=0,inc:Double=0) Local spacing = chars[0].width Local msglen:Int = Len(msg) Local curx:Int = x ' draw each character For Local i:Int = 1 To msglen ' get the letter Local letter:String = Mid$(msg,i,1) ' get the ascii code Local ccode:Int = Asc(letter$) chars[ccode].Draw(curx,y,.2,False,angle,inc) ' move To the Next character position curx = curx + spacing 'angle:+5 ' this gives a spiral effect Next End Method End Type