This is getting to be a nightmare, this is the 5th Old School demonstration made in Monkey X. Probably the last in the series. I must have be bitten by a nostalgia bug.
In this version the lightning effect affects the font too — see the better quality video with new music:
Below is the source code:
Import mojo2 Import brl.databuffer Function Main() New MyApp End Class MyApp Extends App Const FONT_HEIGHT:Int = 219 Const SCROLLTEXT:String = " Old School V - A weird sine wave scroller... Now the lightning effect affects the font too... " Global canvas:Canvas Global fontDat:DataBuffer Global gfxFont:Image Global gfxBG:Image Global chrStartOffset:Int Global firstChrWidth:Int Global chrEndOffset:Int Global angleAdd:Int Global coefficient:Float Global lightAngle:Float, lightX:Float Global x:Float Method OnCreate() canvas = New Canvas gfxBG = Image.Load("bg.png",.0,.0) gfxFont = Image.Load("font.png") fontDat = New DataBuffer(95*4*2) ' 95 characters, for each character two 4 byte integers fontDat = DataBuffer.Load("monkey://data/font.dat") canvas.SetAmbientLight .2,.3,.7 x = 0 chrStartOffset = 0 firstChrWidth = charWidth(0) chrEndOffset = getTextEndOffset() angleAdd = 0 lightX = Cos(lightAngle) * 150 + 640 / 2 SetUpdateRate(60) End Method OnUpdate() lightX = Cos(lightAngle) * 150 + 640 / 2 lightAngle = lightAngle + 2 ' If the amount of scrolling is at least the width of the first ' character to be drawn, increase the starting index where the next ' character will be drawn by one and handle the end of the string If x < -firstChrWidth Then x = firstChrWidth + x chrStartOffset = chrStartOffset + 1 If chrStartOffset > SCROLLTEXT.Length - 1 Then chrStartOffset = 0 firstChrWidth = charWidth(chrStartOffset) chrEndOffset = getTextEndOffset() If chrEndOffset > SCROLLTEXT.Length - 1 Then chrEndOffset = 0 Endif x = x - 2 ' scrolling speed End Method OnRender() canvas.PushMatrix() canvas.Scale(DeviceWidth()/640.0,DeviceHeight()/480.0) canvas.Clear canvas.SetLightType 0,1 canvas.SetLightColor 0,.7,.7,.9 canvas.SetLightPosition 0,lightX, (480 - 128) / 2,-100 canvas.SetLightRange 0,200 For Local sx:=0 Until DeviceWidth Step 128 For Local sy:=0 Until DeviceHeight Step 128 canvas.DrawImage gfxBG,sx,sy Next Next canvas.SetBlendMode(BlendMode.Additive) ' draw string to position x drawString(x) canvas.Flush() canvas.PopMatrix() End ' This function draws text with sine wave from indexes ' chrStartOffset to chrEndOffset of the scrolltext string Function drawString(x:Int) Local angle:Int Local index:Int Local len = SCROLLTEXT.Length() Local i:Int = 0, xx:Int Local coefficient:Float Local chrs:Int[] chrs = SCROLLTEXT.ToChars() xx = x For i = chrStartOffset To chrEndOffset For Local ii = 0 To fontDat.PeekInt((chrs[i]-32)*4*2 + 4) - 1 canvas.DrawRect(xx, Sin(angle) * 50 + (480 - FONT_HEIGHT) / 2, 1, FONT_HEIGHT, gfxFont, fontDat.PeekInt((chrs[i]-32)*4*2)+ii, 0, 1, FONT_HEIGHT) angle = (xx + angleAdd) * 0.5625 * coefficient xx = xx + 1 coefficient = Sin(xx) Next angleAdd = 1 Next End ' get character's width in pixels Function charWidth:Int(offset:Int) Local chrs:Int[] chrs = SCROLLTEXT.ToChars() Return fontDat.PeekInt((chrs[offset]-32)*4*2 + 4) End Function getTextEndOffset:Int() Local chrs:Int[] Local c:Int = chrStartOffset Local textWidth:Int = 0 chrs = SCROLLTEXT.ToChars() ' Find the end offset for a character to build a string ' that's width in pixels is at least 640 + first character's width While textWidth < 640 + firstChrWidth textWidth = textWidth + charWidth(c) c = c + 1 If c > SCROLLTEXT.Length - 1 Then c = 0 Wend Return c End End Class
The strange variable coefficient causes the weird sine wave effect.
In order to get the lightning effect working for the font, one must create in addition to font.png file files font_n.png and font_s.png. The Mojo2 renderer does the job from that on.
File font.png is light blue as color, font_n.png is graphically the same but white. Font_s.png is darkened version of font_n.png.
As mentioned in the first Old School post, n stands for normal, s stands for specular.
I hope you get the same nostalgic feeling from the video as I get… As always, feel free to use the source.