This program takes a string and transforms it into a colored, waved graphic.
In the final version it should also read information out of a *.txt file and
let it scroll right to left over the screen.
Obviously, it is far too slow with the grabsprite-solution (FPS on my computer: 10/30).
Can anyone think up a faster approach ?
TextWave.zip - 0.46MB (http://www.zshare.net/download/63807592dae82737/)
The bitmapfonts library on my homepage has some limited text-scrolling options if you want to see it. Full source included ofcourse :-)
The way to go would be to somehow use Polyvectors. Unfortunately, I wouldn't know how to start...
I love this effect, but the code really needs to be simplified.
Grabsprite is your speed issue....
I put in my own FPS function, and pumped the limitfps up.
By removing grabsprite from the routines, the FPS jumps up to 600+ fps.
TIP: turn this function into an isolated event, with a text input, and positioning.
ie FUNCTION fnFontWaver: text$, Xpos, Ypos, WaveHeight
Add a wave height too, for more dynamic control of the output.
Also try something like this:
1. get rid of the grabsprites in a loop.
2. grab the image of your string one time.(or each time the input is different into your function...use static to remember the input, to test if changed.) This is tricky adding to most programs, because you will need to clear your backbuffer at some point during the main loops...without interupt the program which is using this function. Use a hidden screen to swap the current backbuffer with a new one, then back again.
3. Make the output dynamic using drawanim.
// --------------------------------- //
// Project: TextWave
// --------------------------------- //
//_____________________________________________________________________________ DECLARATIONS
//............................................................................. "CONs"
// values for fnHC()
GLOBAL NumHC = 100; GLOBAL HCy = 178; GLOBAL HCyy = 64
//............................................................................... DIMs
// DIMs for fnHC()
DIM dHCl[NumHC][4]
DIM dHCr[NumHC][4]
// DIM for fnFontWaver()
DIM dWaver[640]
//............................................................................... VARs
// values for fnFontWaver()
GLOBAL Angle, Speed = 50, Dir
// counter
GLOBAL cnt
//______________________________________________________________________________________ INI
// limit frames per second
LIMITFPS -1
// set resolution / fullscreen true/false
// SETSCREEN 640, 480, 1 // GF: GAAAAAHHHHH, my eyes
// load fonts
SETTRANSPARENCY RGB(255,255,255)
LOADFONT "Font.png", 0
SETTRANSPARENCY RGB(255,0,128)
LOADFONT "smalfont.png", 1
// set font index
SETFONT 0
// initialize color-stream
FOR cnt = 0 TO NumHC-1
dHCl[cnt][0] = RND(639)
dHCl[cnt][1] = RND(HCyy) + HCy
dHCl[cnt][2] = RND(2) + 2
dHCl[cnt][3] = RND(2)
dHCr[cnt][0] = RND(810) - 171
dHCr[cnt][1] = RND(HCyy) + HCy
dHCr[cnt][2] = RND(2) + 2
dHCr[cnt][3] = RND(2)
NEXT
// initialize Wave
FOR cnt = 0 TO 639
IF Dir = 0
Speed = Speed + 0.1
IF Speed > 70; Speed = 70; Dir = 1; ENDIF
ELSE
Speed = Speed - 0.1
IF Speed < 30; Speed = 30; Dir = 0; ENDIF
ENDIF
INC Angle, 1
dWaver[cnt] = Speed * SIN(Angle) + 240
NEXT
//.................................................. LOAD GFX
LOADSPRITE "", 0 // for temporary GFX
LOADSPRITE "BG.png", 1 // background
LOADANIM "HypnoCircles.png", 2, 181, 61 // for color-stream
//________________________________________________________________________________ MAIN LOOP
WHILE TRUE
// this function draws a colored background
fnHC()
// print text over background
PRINT "FARTOOSLOW", 0, 208
// add transparent color
DRAWRECT 0,0,640, 208, RGB(255,0,128)
DRAWRECT 0,272,640,208, RGB(255,0,128)
// change y-coordinates of text portions
fnFontWaver()
// draw background
DRAWSPRITE 1, 0, 0
// draw text
ALPHAMODE 0.5; DRAWSPRITE 77, 0, 10; ALPHAMODE 0
DRAWSPRITE 77, 0, 0
// speedwatch
DEBUG_FPS_Time = GETTIMERALL()
DEBUG_FPS_Counter = DEBUG_FPS_Counter + 1
IF ( DEBUG_FPS_Time - DEBUG_FPS_temp ) >= 1000.0
DEBUG_FPS_temp = DEBUG_FPS_Time
DEBUG_s_FPS = DEBUG_FPS_Counter
DEBUG_FPS_Counter = 0
ENDIF
DEBUG_InfoFrames$ = "FPS: " + DEBUG_s_FPS + "/30"
SETFONT 1
PRINT DEBUG_InfoFrames$, 0, 0
SETFONT 0
// draw buffer on screen
SHOWSCREEN
WEND
//________________________________________________________________________________ FUNCTIONs
// ------------------------------------------------------------- //
// --- FNHC ---
// .............................................................
// draws colored background
// ------------------------------------------------------------- //
FUNCTION fnHC:
LOCAL lcnt
ALPHAMODE 0.32
FOR lcnt = 0 TO NumHC-1
IF dHCl[lcnt][0] < -170
dHCl[lcnt][0] = 639
dHCl[lcnt][1] = RND(HCyy) + HCy
dHCl[lcnt][2] = RND(2) + 2
dHCl[lcnt][3] = RND(2)
ELSE
DRAWANIM 2, dHCl[lcnt][3], dHCl[lcnt][0], dHCl[lcnt][1]
DEC dHCl[lcnt][0], dHCl[lcnt][2]
ENDIF
IF dHCr[lcnt][0] > 638
dHCr[lcnt][0] = -170
dHCr[lcnt][1] = RND(HCyy) + HCy
dHCr[lcnt][2] = RND(2) + 2
dHCr[lcnt][3] = RND(2)
ELSE
DRAWANIM 2, dHCr[lcnt][3], dHCr[lcnt][0], dHCr[lcnt][1]
INC dHCr[lcnt][0], dHCl[lcnt][2]
ENDIF
NEXT
ALPHAMODE 0
ENDFUNCTION // FNHC
// ------------------------------------------------------------- //
// --- FNFONTWAVER ---
// .............................................................
// repositions pixel columns
// ------------------------------------------------------------- //
FUNCTION fnFontWaver:
LOCAL lcnt
// delete first entry
DIMDEL dWaver[], 0
// add last entry
REDIM dWaver[640]
// compute last entry?s y-coordinate
IF Dir = 0
Speed = Speed + 0.1
IF Speed > 70; Speed = 70; Dir = 1; ENDIF
ELSE
Speed = Speed - 0.1
IF Speed < 30; Speed = 30; Dir = 0; ENDIF
ENDIF
INC Angle, 1
dWaver[639] = Speed * SIN(Angle) + 240
IF TRUE
// draw waved GFX
SMOOTHSHADING FALSE
GRABSPRITE 0, 0, 208, 640, 128
DRAWRECT 0, 208, 640, 64, RGB(255, 0, 128)
// top left to right
LOCAL block% = 8
FOR lcnt = 0 TO 639-block STEP block%
STARTPOLY 0
POLYVECTOR lcnt, dWaver[lcnt], lcnt, 0, 0xffffff
POLYVECTOR lcnt, 64+dWaver[lcnt], lcnt, 64, 0xffffff
POLYVECTOR lcnt+block, 64+dWaver[lcnt+block], lcnt+block, 64, 0xffffff
POLYVECTOR lcnt+block, dWaver[lcnt+block], lcnt+block, 0, 0xffffff
ENDPOLY
NEXT
ELSE
// draw waved GFX
FOR lcnt = 0 TO 639
GRABSPRITE 0, lcnt, 208, 1, 64
DRAWRECT lcnt, 208, 1, 64, RGB(255, 0, 128)
DRAWSPRITE 0, lcnt, dWaver[lcnt]
NEXT
ENDIF
// copy screen - GF: DONT! Use CREATESCREEN instead!
GRABSPRITE 77, 0, 32, 640, 448
ENDFUNCTION // FNFONTWAVER
FUNCTION poo:
// copy screen
GRABSPRITE 0, 0, 32, 640, 448
ENDFUNCTION
That's about 80 FPS on my machine now. Try this:
- Don't re-use the same sprite with GRABSPRITE if the dimensions between the calls change -> use 2 sprites for that
- Use CREATESCREEN instead of GRABSPRITE
- Use POLYVECTOR instead of 1 pixel slice GRABSPRITE.
If you use CREATESCREEN instead of GRABSPRITE (everywhere), you can easily get > 200 FPS.
Thanks for the help !