Page 1 of 1

Bitmap Sinusscroller with low FPS :( Please help ..

Posted: Sat Jul 14, 2007 9:48 pm
by DeXtr0
Hey guys,

I hope somebody can help me here.
I'm writing my own intro-fx library in PureBasic and I just finished the sinusscroller fully usable with an own sinustable ;).

Hereby a part of the code which works 100% but it's soo slow ??? , only 175FPS on my Intel Dual Core 3.5 with GForce4 8900GTS?

Code: Select all

;----------------------------------------------------------
; BITMAP SINUSSCROLL BY DEXTR0/DAWN - 2007
;----------------------------------------------------------

InitSprite()
InitSprite3D()
UsePNGImageDecoder()
InitKeyboard()

;----------------------------------------------------------
; VARIABLES SECTION
;----------------------------------------------------------
ScreenWidth = 800
ScreenHeight = 600

Enumeration
#buffer27 = 98200     ; Used for HScroller Temporary Bitmaptext
#buffer23 = 98220     ; Used for HSrcoller Temporary Screen
#buffer24 = 98240     ; Used for HScroller Final Screen
#buffer25 = 98260     ; Used for HScroller 3D Sprite
#buffer26 = 98300     ; Used for Reserve
#buffer28 = 98340     ; Used fro Mirror Font
#Screenbuffer = -1    ; Screenbuffer 
EndEnumeration

Structure HScroll 
  id.l
  FontID.l
  MirrorFont.l
  XPos.l
  YPos.l
  yPosMin.l
  yPosMax.l
  YSpeed.l
  YEffectNr.l
  YSpeedAngle.f
  YDirection.l
  NrCharsLine.l
  charwidth.l
  charheight.l
  Speed.l
  SpeedCounter.l
  actNrLines.l
  act_CharNr.l
  ScreenHeight.l
  ScreenWidth.l
  Text.s
  CharXPos.l
  CharYPos.l
  Effekt3D.l
  Rotate_Angle3D.l
  Rotate_Mode3D.l
  ZoomWidth3D.l
  ZoomHeight3D.l
  SinusBuffer.l [1024]
  SinusAngle.f
  SinusRadius.l
  SinusCounter.l
  SinusMaxCount.l
  EndStructure
  
Global Dim DX_HScroller.HScroll(10)

Structure Timer
  id.l
  started.b
  StartTime.l
  StopTime.l
  postiveFlank.b
EndStructure
  
Global Dim DX_Timer.Timer(100)    

;----------------------------------------------------------
; PROCEDURES SECTION
;----------------------------------------------------------
Procedure.f DXP_Sinus(Angle.f)                       
  ProcedureReturn Sin(Angle*(2*3.14159265/360))
EndProcedure   

Procedure DX_DrawText(x, y, Text.s, FrontColor.l = $FFFFFF, BackColor.l = $000000, FontID.l=0)
; -----------------------------------------------------------------------------         
; Name:         DX_DrawText
; Description   Will draw simple text on the screen 
;               In black background color & white text color
; Arguments:    X                    X Position of the text
;               Y                    Y Position of the text
;               Text.s               The text that needs to be displayed
;               FrontColor.l         The frontcolor, default WHITE
;               BackColor.l          The Backcolor, default BLACK
;               FontID               Which font to use
; -----------------------------------------------------------------------------  
  StartDrawing(ScreenOutput())
  
    FrontColor(FrontColor)
    BackColor(BackColor)
    
    If FontID<>0: DrawingFont(FontID) : EndIf
    
    DrawText(x, y, Text.s)
    
  StopDrawing()
   
EndProcedure

Procedure DX_Time(id.l,time.l)
  DX_Timer(id)\postiveFlank=#False
  If  DX_Timer(id)\started=#False 
    DX_Timer(id)\started=#True
    DX_Timer(id)\StartTime=ElapsedMilliseconds()
    DX_Timer(id)\StopTime=DX_Timer(id)\StartTime+time
  EndIf
  If ElapsedMilliseconds() >= DX_Timer(id)\StopTime:DX_Timer(id)\postiveFlank=#True:DX_Timer(id)\started=#False:EndIf
EndProcedure

Procedure DX_GetFPS(xpos.l=10,ypos.l=10)
  Global DX_FPSStart.l
  Global DX_FPSCounter.l
  Global DX_FPSOutput.l
  DX_FPSCounter+1
  If GetTickCount_()-DX_FPSStart>1000:DX_FPSStart=GetTickCount_():DX_FPSOutput=DX_FPSCounter:DX_FPSCounter=0:EndIf
  DX_DrawText(xpos,ypos,"FPS: "+Str(DX_FPSOutput))
EndProcedure

Procedure DX_InitHScroll (id.l,FontID.l,charwidth,charheight,XPos.l,YPos.l,NrCharsLine.l,Speed.l,Text.s,Effekt3D.l=0,MirrorFont.l=0)
  ; -----------------------------------------------------------------------------         
  ; Name:         DX_InitHScroll
  ; Description   Init of HScroller
  ; Arguments:    id                  id for HScroll
  ;               FontID              id for used Bitmapfont
  ;               CharWidth           CharWidth of Bitmapfont
  ;               XPos                XPos of HScroll
  ;               YPos                YPos of HScroll
  ;               Speed               Speed of HScroll         -> 0=fastest 1-x=Slower
  ;               ScrollTextPointer   Pointer to the Scrolltext -> for example: @Scrolltext()  if: DIM Scrolltext.s (100)
  ;                                   The Last String in Last array-Element MUST be a "@" - That means new Start of Scrolltext!
  ;               Effekt3D            Choose 3D Function (0-3)  -> 0=no 3D , 1=Zoom , 2 = Rotate , 3= Zoom AND Rotate  (Default=0 (no 3D))        
  ; ----------------------------------------------------------------------------- 
  
  DX_HScroller(id)\id=id
  DX_HScroller(id)\FontID=FontID
  DX_HScroller(id)\MirrorFont=MirrorFont
  DX_HScroller(id)\charwidth=charwidth
  DX_HScroller(id)\charheight=charheight
  DX_HScroller(id)\XPos=XPos
  DX_HScroller(id)\YPos=YPos
  DX_HScroller(id)\yPosMin=YPos
  DX_HScroller(id)\yPosMax.l=YPos
  DX_HScroller(id)\YSpeed.l=0
  DX_HScroller(id)\YEffectNr.l=0
  DX_HScroller(id)\YSpeedAngle.f=0
  DX_HScroller(id)\YDirection.l=0
  DX_HScroller(id)\NrCharsLine=NrCharsLine
  DX_HScroller(id)\Speed=Speed
  DX_HScroller(id)\SpeedCounter=10
  DX_HScroller(id)\actNrLines=0
  DX_HScroller(id)\act_CharNr=1
  DX_HScroller(id)\ScreenHeight=DX_HScroller(id)\charheight
  DX_HScroller(id)\ScreenWidth=(DX_HScroller(id)\charwidth*DX_HScroller(id)\NrCharsLine)
  DX_HScroller(id)\Text=Text.s
  DX_HScroller(id)\CharXPos=0
  DX_HScroller(id)\CharYPos=0
  DX_HScroller(id)\Effekt3D.l=Effekt3D
  DX_HScroller(id)\Rotate_Angle3D.l=0
  DX_HScroller(id)\Rotate_Mode3D.l=1
  DX_HScroller(id)\ZoomWidth3D.l=0
  DX_HScroller(id)\ZoomHeight3D.l=0
  DX_HScroller(id)\SinusAngle=0.0
  DX_HScroller(id)\SinusRadius=0
  For i.l=0 To 1023
    DX_HScroller(id)\SinusBuffer[i]=0
  Next
  DX_HScroller(id)\SinusCounter=0
  DX_HScroller(id)\SinusMaxCount=360
  
  
  ;Catch Font to Buffer
  CatchSprite(DX_HScroller(id)\id+#buffer25,FontID)
   ;Create Sprite for Temporary Bitmaptext 
  CreateSprite(DX_HScroller(id)\id+#buffer27,DX_HScroller(id)\ScreenWidth,DX_HScroller(id)\ScreenHeight)
  ;Create Sprite for Temporary Screen
  CreateSprite(DX_HScroller(id)\id+#buffer23,DX_HScroller(id)\ScreenWidth,DX_HScroller(id)\ScreenHeight)
   Sprite3DQuality(1)
  ;Create Sprite for Final Screen
  CreateSprite(DX_HScroller(id)\id+#buffer24,DX_HScroller(id)\ScreenWidth,DX_HScroller(id)\ScreenHeight,#PB_Sprite_Texture)
  
EndProcedure

Procedure DX_HScrollerRestoreSinusTable(id.l,SinusTable.l,MaxIndex.l)
  Restore SinusTable
  For i.l=0 To MaxIndex-1
    Read DX_HScroller(id)\SinusBuffer[i]
  Next
EndProcedure

Procedure DX_HScrollerSetSinusMaxCount(id.l,SinusMaxCount.l)
  DX_HScroller(id)\SinusMaxCount=SinusMaxCount-1
EndProcedure

Procedure.s DXP_GetHScrollerBitmapTextChar(id.l,act_CharNr.l)
  ; -----------------------------------------------------------------------------         
  ; Name:         DXP_GetHScrollerBitmapTextChar
  ; Description   Returns the actual Char out of a String
  ; Arguments:    id                  id for HScroll
  ;               act_CharNr          Charnumber from the Char which shall be extracted out of a String                
  ; ----------------------------------------------------------------------------- 
  ProcedureReturn Mid(DX_HScroller(id)\Text,act_CharNr,1)
EndProcedure

Procedure DXP_CalcHScrollerBitmapTextCharPosXY(id,Char.s)
  ; -----------------------------------------------------------------------------         
  ; Name:         DXP_CalcHScrollerBitmapTextCharPosXY
  ; Description   Calculation of the Char in a Bitmapfont
  ; Arguments:    id                  id for HScroll
  ;               Char                Char who shall be calculated               
  ; ----------------------------------------------------------------------------- 
  a.l=Asc(Char)-32
  If a/19 < 0
    DX_HScroller(id)\CharYPos=0
    DX_HScroller(id)\CharXPos=a%19
  Else
    DX_HScroller(id)\CharYPos=a/19
    DX_HScroller(id)\CharXPos=a%19
  EndIf
EndProcedure 

Procedure DXP_HScrollerGetBitmaptext(id)
  ; -----------------------------------------------------------------------------         
  ; Name:         DXP_HScrollerGetBitmaptext
  ; Description   makes a Bitmaptext out of a String 
  ; Arguments:    id                  id for HScroll 
  ; ----------------------------------------------------------------------------- 
  UseBuffer(DX_HScroller(id)\id+#buffer27)
   DXP_CalcHScrollerBitmapTextCharPosXY(id,DXP_GetHScrollerBitmapTextChar(DX_HScroller(id)\id,DX_HScroller(id)\act_CharNr))
    ClipSprite(DX_HScroller(id)\id+#buffer25,DX_HScroller(id)\CharXPos*DX_HScroller(id)\charwidth,DX_HScroller(id)\CharYPos*DX_HScroller(id)\charheight,DX_HScroller(id)\charwidth,DX_HScroller(id)\charheight)
    DisplaySprite(DX_HScroller(id)\id+#buffer25,0,0)
  UseBuffer(#Screenbuffer)
EndProcedure

Procedure DX_HScrollerRotateSinustable(id.l)
  If DXP_GetHScrollerBitmapTextChar(DX_HScroller(id)\id,DX_HScroller(id)\act_CharNr)="a"
    c.l=DX_HScroller(id)\SinusBuffer[0]
    For i.l=0 To DX_HScroller(id)\SinusMaxCount
      DX_HScroller(id)\SinusBuffer[i]=DX_HScroller(id)\SinusBuffer[i+1]
    Next
    DX_HScroller(id)\SinusBuffer[DX_HScroller(id)\SinusMaxCount]=c
  EndIf
EndProcedure

Procedure DX_DrawHScroller(id.l)
  ; -----------------------------------------------------------------------------         
  ; Name:         DX_DrawHScroller
  ; Description   Draws the HScroll to Screen 
  ; Arguments:    id                  id for HScroll 
  ; ----------------------------------------------------------------------------- 
  If DX_HScroller(id)\Speed < DX_HScroller(id)\SpeedCounter
    DX_HScroller(id)\SpeedCounter=DX_HScroller(id)\SpeedCounter-1
  Else
    DX_HScroller(id)\SpeedCounter=10
    UseBuffer(DX_HScroller(id)\id+#buffer23)
    ClipSprite(DX_HScroller(id)\id+#buffer23,1,0,DX_HScroller(id)\ScreenWidth-1,DX_HScroller(id)\ScreenHeight)
    DisplaySprite(DX_HScroller(id)\id+#buffer23,0,0)
    ClipSprite(DX_HScroller(id)\id+#buffer27,DX_HScroller(id)\actNrLines,0,1,DX_HScroller(id)\charheight)
    DisplaySprite(DX_HScroller(id)\id+#buffer27,DX_HScroller(id)\ScreenWidth-1,0) 
    DX_HScroller(id)\actNrLines=DX_HScroller(id)\actNrLines+1
    If DX_HScroller(id)\actNrLines > DX_HScroller(id)\charwidth
      If Not DXP_GetHScrollerBitmapTextChar(DX_HScroller(id)\id,DX_HScroller(id)\act_CharNr)="@"  
        DXP_HScrollerGetBitmaptext(id)
        DX_HScroller(id)\act_CharNr+1
      Else
        DX_HScroller(id)\act_CharNr=1
        DXP_HScrollerGetBitmaptext(id)
        DX_HScroller(id)\act_CharNr+1
      EndIf
      DX_HScroller(id)\actNrLines=0
    EndIf
  EndIf
  
  ;SPEED
  Select DXP_GetHScrollerBitmapTextChar(DX_HScroller(id)\id,DX_HScroller(id)\act_CharNr)
    Case "a":
      DX_HScroller(id)\SpeedCounter=10000
      DX_Time(DX_HScroller(id)\id+90,1000*(Asc(DXP_GetHScrollerBitmapTextChar(DX_HScroller(id)\id,DX_HScroller(id)\act_CharNr+1))-$30))
      If DX_Timer(DX_HScroller(id)\id+90)\postiveFlank:DX_HScroller(id)\SpeedCounter=10:DX_HScroller(id)\act_CharNr+2:EndIf
    Case "b":
      DX_HScroller(id)\Speed=1
    Case "c":
      DX_HScroller(id)\Speed=2
    Case "d":
      DX_HScroller(id)\Speed=3
    Case "e":
      DX_HScroller(id)\Speed=4
    Case "f":
      DX_HScroller(id)\Speed=5
    Case "g":
      DX_HScroller(id)\Speed=6
    Case "h":
      DX_HScroller(id)\Speed=7
    Case "i":
      DX_HScroller(id)\Speed=8
    Case "j":
      DX_HScroller(id)\Speed=9
    Case "k":
      DX_HScroller(id)\Speed=10
    Default: 
          ;DX_HScroller(id)\Speed=3
  EndSelect
   
  UseBuffer(DX_HScroller(id)\id+#buffer24)
  ClipSprite(DX_HScroller(id)\id+#buffer23,0,0,DX_HScroller(id)\ScreenWidth,DX_HScroller(id)\ScreenHeight)
  DisplaySprite(DX_HScroller(id)\id+#buffer23,0,0)
   
  UseBuffer(#Screenbuffer)
  ClipSprite(DX_HScroller(id)\id+#buffer24,0,0,DX_HScroller(id)\ScreenWidth,DX_HScroller(id)\ScreenHeight)
  
  Select DX_HScroller(id)\Effekt3D
    Case 5  
      DX_HScrollerRotateSinustable(id)
      DX_HScroller(id)\SinusCounter=0
      For i.l=0 To DX_HScroller(id)\ScreenWidth
        If DX_HScroller(id)\SinusCounter>=DX_HScroller(id)\SinusMaxCount:DX_HScroller(id)\SinusCounter=0:EndIf
        ClipSprite(DX_HScroller(id)\id+#buffer24,i+1,0,1,DX_HScroller(id)\ScreenHeight)  
        DisplayTransparentSprite(DX_HScroller(id)\id+#buffer24,DX_HScroller(id)\XPos+i,DX_HScroller(id)\YPos+DX_HScroller(id)\SinusBuffer[DX_HScroller(id)\SinusCounter])
        DX_HScroller(id)\SinusCounter+1
        Next
      
    Default
    
  EndSelect
  
EndProcedure

;----------------------------------------------------------
; MAIN PROGRAM
;----------------------------------------------------------

OpenScreen(ScreenWidth,ScreenHeight,32,"DX_SinusScroller")

DX_InitHScroll(1,?font1,32,32,0,50,50,10,"SINUSSCROLL BY DEXTRO OF DAWN.. BUT FPS IS WAY TO SLOW",5,0)

DX_HScrollerRestoreSinusTable(1,?SinusTable,800) 
DX_HScrollerSetSinusMaxCount(1,800)

Repeat 
   
  ClearScreen(0)
  
  DX_GetFPS()
  
  DX_DrawHScroller(1)
  
  FlipBuffers(0)

  ExamineKeyboard()
  
Until KeyboardPushed(#PB_Key_All)
End

;----------------------------------------------------------
; DATA SECTION
;----------------------------------------------------------

DataSection 
  font1:IncludeBinary "dAWN_030_32x32.PNG"
  
  SinusTable: 
  Data.L 100,97,95,93,91,88,86,84,82,80,78,75,73,71,69,67
  Data.L 65,63,61,59,58,56,54,52,50,49,47,45,44,42,41,39
  Data.L 38,36,35,33,32,31,30,29,27,26,25,24,24,23,22,21
  Data.L 21,20,19,19,18,18,18,17,17,17,17,17,17,17,17,17
  Data.L 17,17,18,18,19,19,20,20,21,22,22,23,24,25,26,27
  Data.L 28,30,31,32,33,35,36,38,39,41,43,44,46,48,50,52
  Data.L 54,56,58,60,62,64,66,69,71,73,75,78,80,83,85,88
  Data.L 90,93,96,98,101,104,106,109,112,115,117,120,123,126,129,132
  Data.L 134,137,140,143,146,149,152,155,158,161,164,167,169,172,175,178
  Data.L 181,184,187,190,192,195,198,201,204,206,209,212,215,217,220,222
  Data.L 225,227,230,232,235,237,240,242,244,247,249,251,253,255,257,259
  Data.L 261,263,265,267,269,271,272,274,276,277,279,280,282,283,284,286
  Data.L 287,288,289,290,291,292,293,294,295,295,296,297,297,298,298,299
  Data.L 299,300,300,300,300,300,300,300,300,300,300,300,300,299,299,299
  Data.L 298,298,297,297,296,296,295,294,293,293,292,291,290,289,288,287
  Data.L 286,285,284,283,281,280,279,278,276,275,274,272,271,270,268,267
  Data.L 265,264,262,261,259,258,256,255,253,252,250,248,247,245,244,242
  Data.L 241,239,238,236,234,233,231,230,228,227,225,224,223,221,220,218
  Data.L 217,216,214,213,212,211,209,208,207,206,205,204,203,202,201,200
  Data.L 199,198,197,196,196,195,194,194,193,193,192,192,191,191,190,190
  Data.L 190,190,190,190,189,189,190,190,190,190,190,190,191,191,192,192
  Data.L 193,193,194,194,195,196,197,197,198,199,200,201,202,203,205,206
  Data.L 207,208,210,211,212,214,215,217,218,220,222,223,225,227,229,230
  Data.L 232,234,236,238,240,242,244,246,248,250,252,254,256,258,260,263
  Data.L 265,267,269,271,274,276,278,280,283,285,287,289,292,294,296,298
  Data.L 301,303,305,307,310,312,314,316,318,320,322,325,327,329,331,333
  Data.L 335,337,339,341,342,344,346,348,350,351,353,355,356,358,359,361
  Data.L 362,364,365,366,367,369,370,371,372,373,374,375,376,377,377,378
  Data.L 379,379,380,380,381,381,382,382,382,382,382,382,382,382,382,382
  Data.L 382,381,381,381,380,380,379,378,378,377,376,375,374,373,372,371
  Data.L 370,369,368,366,365,363,362,360,359,357,356,354,352,350,348,346
  Data.L 344,342,340,338,336,334,332,329,327,325,322,320,317,315,312,310
  Data.L 307,305,302,299,297,294,291,289,286,283,280,277,275,272,269,266
  Data.L 263,260,257,254,251,249,246,243,240,237,234,231,228,225,222,219
  Data.L 216,214,211,208,205,202,199,197,194,191,189,186,183,181,178,175
  Data.L 173,170,168,165,163,160,158,156,153,151,149,147,145,143,141,139
  Data.L 137,135,133,131,129,127,126,124,123,121,120,118,117,115,114,113
  Data.L 112,110,109,108,107,106,106,105,104,103,103,102,101,101,100,100
  Data.L 100,99,99,99,99,99,99,99,99,99,99,99,99,100,100,100
  Data.L 101,101,102,102,103,104,104,105,106,107,108,109,110,110,112,113
  Data.L 114,115,116,117,118,119,121,122,123,125,126,127,129,130,132,133
  Data.L 134,136,137,139,140,142,144,145,147,148,150,151,153,154,156,158
  Data.L 159,161,162,164,165,167,168,170,171,173,174,176,177,179,180,181
  Data.L 183,184,185,187,188,189,190,191,193,194,195,196,197,198,199,200
  Data.L 201,201,202,203,204,204,205,206,206,207,207,208,208,208,209,209
  Data.L 209,209,209,209,210,210,209,209,209,209,209,208,208,208,207,207
  Data.L 206,206,205,204,204,203,202,201,200,199,198,197,196,195,194,193
  Data.L 191,190,189,187,186,184,183,181,180,178,176,175,173,171,170,168
  Data.L 166,164,162,160,158,156,154,152,150,148,146,144,142,140,137,135
  Data.L 133,131,129,126,124,122,120,118,115,113,111,109,106,104,102,100

EndDataSection
Here is the font which you will need to run it in purebasic

Image

Can anybody help me optimize it or give me hints how to get it faster.

When I add the sinusscroller to an own intro, the speed s*cks -[

1000x
DeXtr0