Crashes on Shared, but not as a local variable

General FreeBASIC programming questions.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Crashes on Shared, but not as a local variable

Postby rolliebollocks » Aug 12, 2010 16:33

#1. Firstly, when you run this, what kind of FPS are you getting?
#2. If I try to dim myscreen (screenobject UDT) as a global using shared fb immediately crashes.

Any thoughts?

Code: Select all

#include once "fbgfx.bi"

#define screen_x 800
#define screen_x2 799
#define screen_y 600
#define screen_y2 599
#define center_x 400
#define center_y 300
#define RND_UBYTE Int(Rnd * 256)
#define RNDRGB rgb(RND_UBYTE, RND_UBYTE, RND_UBYTE)
#define RNDRGBA rgba( RND_UBYTE, RND_UBYTE, RND_UBYTE, RND_UBYTE )
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
type ScreenObject
    as fb.image ptr     screenbuffer
    as ubyte ptr        pixdata
   
    declare Constructor ()
   
    declare sub ppSet ( byval x as integer, byval y as integer, clr as uinteger )
    declare sub Display ()
    declare sub Clearscreen()
end type

Constructor ScreenObject()
    screenbuffer = imagecreate(screen_x,screen_y)
    pixdata      = Cast( Ubyte Ptr, screenbuffer ) + Sizeof( FB.IMAGE )
end Constructor

sub ScreenObject.ppSet ( byval x as integer, byval y as integer, clr as uinteger )
    if x < 0 then exit sub
    if x > screen_x2 then exit sub
    if y < 0 then exit sub
    if y > screen_y2 then exit sub
    Cast (Uinteger Ptr, pixdata + ( y * screenbuffer->Pitch ))[ x ] = clr
end sub

sub ScreenObject.Display ()
    Put (0,0), screenbuffer, trans
end sub

sub ScreenObject.ClearScreen ()
    for ix as integer = 0 to screen_x-1
        for iy as integer = 0 to screen_y-1
            Cast (Uinteger Ptr, pixdata + ( iy * screenbuffer->Pitch ))[ ix ] = 0
        next
    next
end sub

screen 19,32

dim as screenobject myscreen
dim as integer mx, my, mw, mb, fps, frames, oldwheel
dim as double tNow, tLast

do
    myscreen.Clearscreen()
    for ix as integer = 0 to screen_x2
        for iy as integer = 0 to screen_y2
            myscreen.ppSet (ix,iy, &hffffff)
        next
    next
    myscreen.Display()
    sleep 2
      frames+=1
   If frames=100 Then
     tNow = Timer()
     fps = frames/(tNow-tLast)
     windowtitle "fps = " & fps
     Sleep 1
     tLast=Timer():frames=0
   End If
loop until len(inkey)
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Postby rolliebollocks » Aug 12, 2010 16:40

Oops!

I forgot. Shared variables are processed prior to compilation and thus the pointer was pointing to nothing. I guess I have to call screen in the constructor if I want to use shared variables.

Are you guys getting around 80 FPS? That's what I'm getting.
rvdm
Posts: 3
Joined: Mar 20, 2008 14:43
Location: netherlands

framerate program rolliebollocks

Postby rvdm » Aug 12, 2010 19:13

I'm getting 64 fps on a i5 650 3.2 gigaherz with a processor time of 2 a 3%. rvdm
Richard
Posts: 2928
Joined: Jan 15, 2007 20:44
Location: Australia

Postby Richard » Aug 12, 2010 19:47

There is much to be gained by using the compiler commands “-exx” and “-w pedantic” while developing code. It does slow the running code down, but it certainly speeds up development.
My frame rate is 64 fps without -exx. It is16 fps with -exx , but it does find the null pointer.
badidea
Posts: 1358
Joined: May 24, 2007 22:10
Location: The Netherlands

Postby badidea » Aug 12, 2010 21:47

On a windows system, you won't get more then 64 fps, since you have a short sleep in your code (which is a good thing).
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Postby rolliebollocks » Aug 12, 2010 23:38

Thanks guys.

This should be faster:

Code: Select all

#include once "fbgfx.bi"

#define screen_x 800
#define screen_x2 799
#define screen_y 600
#define screen_y2 599
#define center_x 400
#define center_y 300
#define RND_UBYTE Int(Rnd * 256)
#define RNDRGB rgb(RND_UBYTE, RND_UBYTE, RND_UBYTE)
#define RNDRGBA rgba( RND_UBYTE, RND_UBYTE, RND_UBYTE, RND_UBYTE )
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Type point3d
  As single x,y,z
  declare Constructor ()
  declare Constructor ( rhs as point3d )
  declare Operator Let ( rhs as point3d )
End Type

Constructor point3d ()
    this.x = 0
    this.y = 0
    this.z = 0
end Constructor
   
Constructor point3d ( rhs as point3d )
    this.x = rhs.x
    this.y = rhs.y
    this.z = rhs.z
end Constructor

Operator point3d.Let ( rhs as point3d )
    this.x = rhs.x
    this.y = rhs.y
    this.z = rhs.z
end Operator


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
type ScreenObject
    as fb.image ptr     screenbuffer
    as integer          pitch
    as ubyte ptr        pixdata
   
    declare Constructor ()
   
    declare sub ppSet ( byref p3d as point3d, byval clr as uinteger )
    declare sub ppSet ( byval x as integer, byval y as integer, clr as uinteger )
    declare sub Display ()
    declare sub Clearscreen()
end type

Constructor ScreenObject()
    screen 19,32,,fb.GFX_ALPHA_PRIMITIVES
    screenbuffer = imagecreate(screen_x,screen_y)
    pixdata      = Cast( Ubyte Ptr, screenbuffer ) + Sizeof( FB.IMAGE )
    pitch = screenbuffer->pitch
end Constructor

sub ScreenObject.ppSet ( byval x as integer, byval y as integer, clr as uinteger )
    if x < 0 then exit sub
    if x > screen_x2 then exit sub
    if y < 0 then exit sub
    if y > screen_y2 then exit sub
    Cast (Uinteger Ptr, pixdata + ( y * pitch ))[ x ] = clr
end sub

sub ScreenObject.ppSet ( byref p3d as point3d, byval clr as uinteger )
   Dim As Integer xscreen = 0, yscreen = 0
   xscreen = (p3d.x*512)/(p3d.z+1000) + 400
      If xscreen > 0 Then
        If xscreen < screen_x2 Then
          yscreen = (p3d.y*512)/(p3d.z+1000) + 300
          If yscreen > 0 Then
            If yscreen < screen_y-1 Then
                Cast (Uinteger Ptr, pixdata + ( yscreen * pitch ))[ xscreen ] = clr
            endif
          endif
        endif
    endif     
end sub

sub ScreenObject.Display ()
    Put (0,0), screenbuffer, trans
end sub

sub ScreenObject.ClearScreen ()
    line screenbuffer, (0,0)-(screen_x2,screen_y2),RGBA(0,0,0,15),bf
end sub

dim shared as screenobject myscreen
dim as integer mx, my, mw, mb, fps, frames, oldwheel
dim as double tNow, tLast

do
    myscreen.ClearScreen()
    for ix as integer = 0 to screen_x2
        for iy as integer = 0 to screen_y2
            myscreen.ppset(ix,iy,RGB(ix,iy,99))
        next
    next
    myscreen.Display()
    sleep 1
      frames+=1
   If frames=100 Then
     tNow = Timer()
     fps = frames/(tNow-tLast)
     windowtitle "fps = " & fps
     Sleep 1
     tLast=Timer():frames=0
   End If
loop until len(inkey)
dodicat
Posts: 5758
Joined: Jan 10, 2006 20:30
Location: Scotland

Postby dodicat » Aug 13, 2010 0:42

Hi Rollie~
Nice background.
I get 14 fps for code 1
and 16 fps for code 2
Twin Pentium 3 @ 933 M.Hz.

I miss the old circles topic for posting silly code.
My latest silly code is a photo-shoot of a tapeworm.
I found out the cure for a tapeworm last Sunday in Church, the minister held up a glass of whisky and Yelled DEVIL'S BREW
Then he shook it around and yelled THIS STUFF KILLS

Code: Select all



''TAPE WORM

#include "fbgfx.bi"
Dim As Integer xres,yres
screeninfo xres,yres
'xres=600
'yres=600


Dim border As Integer=20
screenres xres-border,yres-border,32,1,fb.GFX_NO_FRAME Or fb.GFX_ALWAYS_ON_TOP or fb.GFX_HIGH_PRIORITY
'''screenres xres-border,yres-border,32,1,fb.GFX_ALWAYS_ON_TOP or fb.GFX_HIGH_PRIORITY


Dim As Double pi=4*Atn(1)
Dim Shared As Double xc,yc
Type PLANE     'points to define a plane (screen edges in this case)
    As Double x,y,z
End Type
type _POINT  ' points for a point
    As Double x,y,z
End Type
Declare Function planedistance(v() As PLANE,p As _POINT) As Double

xc=xres/2
yc=yres/2
Function r(first As Double, last As Double) As Double
    Function = Rnd * (last - first) + first
End Function
Dim As plane top(1 To 3),rhs(1 To 3),lhs(1 To 3),bottom(1 To 3)

top(1).x=0:top(1).y=0:top(1).z=0
top(2).x=xres:top(2).y=0:top(2).z=0
top(3).x=xres/2:top(3).y=0:top(3).z=100

bottom(1).x=0:bottom(1).y=yres:bottom(1).z=0
bottom(2).x=xres:bottom(2).y=yres:bottom(2).z=0
bottom(3).x=xres/2:bottom(3).y=yres:bottom(3).z=100


lhs(1).x=0:lhs(1).y=0:lhs(1).z=0
lhs(2).x=0:lhs(2).y=yres:lhs(2).z=0
lhs(3).x=0:lhs(3).y=yres/2:lhs(3).z=100

rhs(1).x=xres:rhs(1).y=0:rhs(1).z=0
rhs(2).x=xres:rhs(2).y=yres:rhs(2).z=0
rhs(3).x=xres:rhs(3).y=yres/2:rhs(3).z=100
#macro edges(q)
If Abs(planedistance(top(),position))<20+border Then
 ky=-ky
 Endif
 If Abs(planedistance(bottom(),position))<20+border Then
 ky=-ky
 Endif
 If Abs(planedistance(lhs(),position))<20+border Then
 kx=-kx
 Endif
 If Abs(planedistance(rhs(),position))<20+border Then
 kx=-kx
 Endif
#endmacro

    Dim As Double x,y,dr=1
 #macro slug(theta,R)
 Dim As Double tot=tot+dr*theta
   x= xc+R*Cos(tot)
   y=yc+R*Sin(tot)
   If tot>2*pi Then tot=0
   #endmacro

Dim As Double dx,dy
dx=1:dy=1
Dim As Double diffx,diffy,length,total_length,rad
Dim As _point position
Dim As Integer kx=1,ky=1,intlen,maxlen
Dim As Uinteger c
dim count as integer
Do
    count=count+1
Randomize
position.x=xc
position.y=yc
total_length=0
maxlen=r(500,2000)
rad=r(2,15)

Do
   
    Paint(0,0),rgb(200,200,255)
    draw string (20,20),"SPACE TO CHANGE, ESC TO QUIT",rgb(0,0,200)
    slug(r(.01,.01),r(19000,19000))
    diffx=x-position.x:diffy=y-position.y
    length=Sqr(diffx^2+diffy^2)
    dx=diffx/length
    dy=diffy/length
    edges(0)
    total_length=total_length+Sqr(dx^2+dy^2)
    position.x=position.x+kx*dx
    position.y=position.y+ky*dy
    intlen=Int(total_length)
    c=255*intlen/maxlen
    if count mod 2 =0 then
    circle(position.x,position.y),rad*c/255,rgb(intlen mod int(r(255,255)),255-intlen mod int(r(100,255)),200-intlen mod int(r(100,255))),,,,f
    else
    Circle (position.x,position.y),rad*c/255,rgb(c,c,c),,,,f
    end if
   If intlen Mod 200 =0 Then dr=-dr
Loop Until total_length>maxlen
Sleep
Cls
Loop Until Inkey=Chr(27)

Function planedistance(v() As PLANE,p As _POINT) As Double
    Type FUNCTION_VECTOR 'internal type
    As Double x,y,z
    End Type

    Dim vct(1 To 2) As function_vector 'to vector multiply
    Dim As Double wx,wy,wz,nw,dist 'for the macros
 Dim As Double px,py,pz
       px=p.x-v(1).x  'get vector (components) from p to a point on v()
       py=p.y-v(1).y
       pz=p.z-v(1).z
    #macro unitcross(product)
    wx= vct(1).y*vct(2).z-vct(1).z*vct(2).y
    wy= -(vct(1).x*vct(2).z-vct(2).x*vct(1).z)
    wz=vct(1).x*vct(2).y-vct(2).x*vct(1).y
    nw=Sqr(wx^2+wy^2+wz^2) 'normalizer(length)
    wx=wx/nw   'unit cross product components
    wy=wy/nw
    wz=wz/nw
    #endmacro
   
    #macro dot(product)
    dist=wx*px+wy*py+wz*pz 
    #endmacro
    vct(1).x=v(1).x-v(2).x:vct(2).x=v(2).x-v(3).x 'get 2 vectors on plane
    vct(1).y=v(1).y-v(2).y:vct(2).y=v(2).y-v(3).y
    vct(1).z=v(1).z-v(2).z:vct(2).z=v(2).z-v(3).z
       unitcross(0)  'get unit normal to plane
       dot(0) 'scalar multiply by px,py and pz above
    Return dist
End Function

 
Richard
Posts: 2928
Joined: Jan 15, 2007 20:44
Location: Australia

Postby Richard » Aug 13, 2010 2:39

rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Postby rolliebollocks » Aug 13, 2010 12:33

@Dodicat

16 FPS!?! Pentium 3???

I'm surprised it's still running. That was right about the time they started making computers real cheap, disposable, so that they would die in 3 years. My 8088 outlasted my first Pentium (which I think was right before Pentium 3).
voyager2-DX
Posts: 4
Joined: Jan 16, 2012 8:40

Re: Crashes on Shared, but not as a local variable

Postby voyager2-DX » Jan 19, 2012 6:28

rolliebollocks wrote:@Dodicat



16 FPS!?! Pentium 3???



I'm surprised it's still running. That was right about the time they started making computers real cheap, disposable, so that they would die in 3 years. My 8088 outlasted my first Pentium (which I think was right before Pentium 3).


I have a Pentium 3 @ 690MHz and it still works fine , and up till a year ago it was still my main computer :p (not kidding!!)
I also have an AMD Duron @ 850MHz that still works :p
Both run Windows XP multiboot Ubuntu

My current computer is Pentium 4 @ 3.2 GHz :p
The P4 with WinXP says = 34 FPS
But all I get is a White screen

I can test the P3 and D850 later.
fxm
Posts: 8962
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Crashes on Shared, but not as a local variable

Postby fxm » Jan 19, 2012 9:30

rolliebollocks wrote:#2. If I try to dim myscreen (screenobject UDT) as a global using shared fb immediately crashes.

rolliebollocks wrote:I forgot. Shared variables are processed prior to compilation and thus the pointer was pointing to nothing. I guess I have to call screen in the constructor if I want to use shared variables.

Yes, putting 'Shared' in the 'myscreen' declaration, we obtain the run-time error (compiling with option -exx):
Aborting due to runtime error 7 (null pointer access) at line 44 of ...
(line#44: Cast (Uinteger Ptr, pixdata + ( iy * screenbuffer->Pitch ))[ ix ] = 0)

In fact, it is a very 'classic' error due to the using of 'Shared':
- Entity declared using the Shared specifier is implicitly static.
- Static variable, object and array lifetimes begin at program creation and end with program termination.
=> The declaration and the construction of the instance 'myscreen' (with integrated constructor) is done before the instruction:
screen 19,32
(we can verify that 'imagecreate(screen_x,screen_y)' returns 0 before the run-time error)

If we want to keep 'imagecreate' in the constructor (and not put 'screen' at the beginning of the constructor), there is only one solution:
separate the 'Shared' declaration and the construction of 'myscreen' in two distinct instructions.
=> use of a pointer:
screen 19,32
dim shared as screenobject Ptr myscreen
myscreen = new screenobject

Consequently, the declaration and the memory reservation of the pointer 'myscreen' is executed at the beginning of the program, but the instance memory allocation and especially the construction is always executed after the graphic screen definition.
('dim shared as screenobject Ptr myscreen' can also be in beginning of the program, but 'myscreen = new screenobject' must be after 'screen 19,32')

The program so modified:

Code: Select all

#include once "fbgfx.bi"

#define screen_x 800
#define screen_x2 799
#define screen_y 600
#define screen_y2 599
#define center_x 400
#define center_y 300
#define RND_UBYTE Int(Rnd * 256)
#define RNDRGB rgb(RND_UBYTE, RND_UBYTE, RND_UBYTE)
#define RNDRGBA rgba( RND_UBYTE, RND_UBYTE, RND_UBYTE, RND_UBYTE )
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
type ScreenObject
    as fb.image ptr     screenbuffer
    as ubyte ptr        pixdata
   
    declare Constructor ()
   
    declare sub ppSet ( byval x as integer, byval y as integer, clr as uinteger )
    declare sub Display ()
    declare sub Clearscreen()
end type

Constructor ScreenObject()
    screenbuffer = imagecreate(screen_x,screen_y)
    pixdata      = Cast( Ubyte Ptr, screenbuffer ) + Sizeof( FB.IMAGE )
end Constructor

sub ScreenObject.ppSet ( byval x as integer, byval y as integer, clr as uinteger )
    if x < 0 then exit sub
    if x > screen_x2 then exit sub
    if y < 0 then exit sub
    if y > screen_y2 then exit sub
    Cast (Uinteger Ptr, pixdata + ( y * screenbuffer->Pitch ))[ x ] = clr
end sub

sub ScreenObject.Display ()
    Put (0,0), screenbuffer, trans
end sub

sub ScreenObject.ClearScreen ()
    for ix as integer = 0 to screen_x-1
        for iy as integer = 0 to screen_y-1
            Cast (Uinteger Ptr, pixdata + ( iy * screenbuffer->Pitch ))[ ix ] = 0
        next
    next
end sub

screen 19,32

dim shared as screenobject Ptr myscreen
myscreen = new screenobject
dim as integer mx, my, mw, mb, fps, frames, oldwheel
dim as double tNow, tLast

do
    myscreen->Clearscreen()
    for ix as integer = 0 to screen_x2
        for iy as integer = 0 to screen_y2
            myscreen->ppSet (ix,iy, &hffffff)
        next
    next
    myscreen->Display()
    sleep 2
      frames+=1
   If frames=100 Then
     tNow = Timer()
     fps = frames/(tNow-tLast)
     windowtitle "fps = " & fps
     Sleep 1
     tLast=Timer():frames=0
   End If
loop until len(inkey)
nota: fps = 25/26 on my portable PC


[Edit]:
- In fact, I just realize that it is an old solved bug dating a year and a half, but I think that this little reminder can be useful to all.
-
voyager2-DX wrote:But all I get is a White screen
There is nothing else to see.

Return to “General”

Who is online

Users browsing this forum: No registered users and 1 guest