IntroductionThe little tutorial will complete the 1.0 series of tuts and get us ready for the 2.0 series. Since our screen object is expected to grow in size as we add more features to it, it is time to get our development project files in order and this is what we'll talk about in this tutorial.
Test File and Include FileIn other object oriented programming languages the convention is to place a class object in its own file and we are going to follow that procedure with the screen object. There are good reasons to do this. First, it makes managing the object code easier since it is all contained within a single file. Second, because the development parallels what a user would be doing, we can see how the object behaves in a more realistic setting. Since most editors today allow project files, splitting up a project into multiple files only makes sense.
How it WorksAttached to this post is a zip file, fbscrobj.zip that contains two files, fbgrtest.bas, the test program and fbscrobj.bi, the object code. The test program will be used to test out the features of the screen object and will change since it is only a test bed and not a real application. The object code is the main focus and will expand over time as we add new features. So, in order to get set up properly let's take a look at the test program (fbgrtest.bas)to see how we need to set it up to include our object code.
' FB Graphics Series for DBFInteractive: http://www.dbfinteractive.com/
' Richard D. Clark
' Basic Graphics Framework
' GPL 3.0
' This program is free software; you can redistribute it and/or modify it
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
' =======================================================================================================
' This program is the test bed for a graphic screen object that will be used as a base for the graphics series.
' The series will use only the built-in graphics and the standard FB libraries.
' =======================================================================================================
' Include the screen object code.
#Include "fbscrobj.bi"
'Set the screen object namespace.
Using scrobj
' =======================================================================================================
' Main Program Code
' =======================================================================================================
'Init the random number generator.
Randomize Timer
'Create the screen object which will initialize and create the graphics screen.
Dim As screenobject aScreen = screenobject(640, 480)
'Make sure the screen intilizled properly.
If aScreen.GetStatus = FALSE Then
End
EndIf
'Draw a 100 screens
For i As Integer = 1 To 100
'Draw some random points to the screen.
For x As Integer = 0 To aScreen.GetWidth - 1
For y As Integer = 0 To aScreen.GetHeight - 1
aScreen.DrawToBuffer x, y, RGB (Rnd * 255, Rnd * 255, Rnd * 255)
Next
Next
'Copy the buffer to the screen.
ascreen.CopyBuffer
Next
'Clear the buffer.
ascreen.ClearBuffer
'Copy the buffer to the screen, should be black.
ascreen.CopyBuffer
'Wait for the user to end.
Print "Press any key"
Sleep
As you can see it isn't any different except that it doesn't have any object code. The important part here is the following snippet:
' Include the screen object code.
#Include "fbscrobj.bi"
'Set the screen object namespace.
Using scrobj
When the compiler sees the #Include statement, it will include our object code at the point of the statement, so in essence we still have the same situation as before where the object code is before our test code, but we don't have to clutter up the test code with the object code, and more importantly, the object isn't cluttered up with a bunch of code that isn't relevant to the actual object.
The Object CodeLet's take a look at the object code now to see how it looks in this new format.
' FB Graphics Series for DBFInteractive: http://www.dbfinteractive.com/
' Richard D. Clark
' Screen Object Graphics Framework
' GPL 3.0
' This program is free software; you can redistribute it and/or modify it
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
' =======================================================================================================
' This is the basic graphics screen object and graphics framework for the FB Graphics Series.
' =======================================================================================================
'Create our object namespace.
Namespace scrobj
'Include the FB graphics library.
#Include "fbgfx.bi"
'Include the CRT for memory functions.
#Include "crt.bi"
'Set the default namespace.
Using FB
'Boolean enumeration.
Enum sbool
FALSE = 0
TRUE = Not FALSE
End Enum
'Create the screen object definition.
Type screenobject
Private:
_width As Integer 'The screen width.
_height As Integer 'The screen height.
_buffer As UInteger Ptr 'The screen update buffer.
_initok As sbool 'Flag indicates screen set successfully. True, set ok, False error.
Public:
Declare Constructor (ByVal scrwidth As Integer, ByVal scrheight As Integer) 'Sets up a graphics screen.
Declare Destructor 'Cleans up created objects.
Declare Property GetStatus () As sbool 'Returns command status.
Declare Property GetWidth () As Integer 'Returns the screen width.
Declare Property GetHeight () As Integer 'Returns the screen height.
Declare Sub DrawToBuffer (ByRef x As Integer, ByRef y As Integer, ByRef clr As UInteger) 'Sets the x and y location of buffer to color.
Declare Sub CopyBuffer ()'Copies buffer to screen.
Declare Sub ClearBuffer ()'Clears buffer. Fills to 0.
End Type
'Screen object constructor.
'This sets up both the screen and the associated screen buffer.
Constructor screenobject (ByVal scrwidth As Integer, ByVal scrheight As Integer)
'Set the default status. An error will change to False.
_initok = TRUE
'Check the parameters to make sure that they are in bounds.
If (scrwidth > 0) And (scrheight > 0) Then
'Try and set the screen.
ScreenRes scrwidth, scrheight, 32
'Check to see if the screen was created successfully.
If ScreenPtr Then
'Set the screen width and height.
_width = scrwidth
_height = scrheight
'Create the update buffer.
_buffer = Callocate (scrwidth * scrheight, SizeOf(UInteger))
'Nake sure that the buffer was created.
If _buffer = 0 Then
'Set status to False, error.
_initok = FALSE
EndIf
Else
'Set status to False, error.
_initok = FALSE
EndIf
Else
'Set status to False, error.
_initok = FALSE
EndIf
End Constructor
'Screen object destructor.
'This will destroy any created objects like the update buffer.
Destructor screenobject
'Destroy the update buffer if initialized.
If _buffer Then DeAllocate _buffer
End Destructor
'Screen object status property.
'Returns the current status of object.
Property screenobject.GetStatus () As sbool
Return _initok
End Property
'Screen object width property.
'Returns the screen width.
Property screenobject.GetWidth () As Integer
Return _width
End Property
'Screen object height property.
'Returns the screen height.
Property screenobject.GetHeight () As Integer
Return _height
End Property
'Screen object DrawToBuffer sub.
'Copies color to x, y position in buffer. Provides clipping.
Sub screenobject.DrawToBuffer (ByRef x As Integer, ByRef y As Integer, ByRef clr As UInteger)
'Make sure the object was initialized.
If _initok = TRUE Then
If (x >= 0) And (y >= 0) And (x < _width) And (y < _height) Then
_buffer[y * _width + x] = clr
EndIf
End If
End Sub
'Screen object CopyBuffer sub.
'Copies the buffer to the screen.
Sub screenobject.CopyBuffer ()
'Make sue the object was initialized.
If _initok = TRUE Then
'Need to lock the screen before we copy the buffer.
ScreenLock
'Using the CRT memcpy to fast copy the buffer to the screen memory.
memcpy ScreenPtr, _buffer, _width * _height * SizeOf(UInteger)
ScreenUnLock
End If
End Sub
'Screen object ClearBuffer sub.
'Clears buffer by setting buffer to 0.
Sub screenobject.ClearBuffer ()
'Make sure the object was initialized.
If _initok = TRUE Then
'Using the CRT memset to set buffer to 0.
memset _buffer, 0, _width * _height * SizeOf(UInteger)
End If
End Sub
End Namespace
It looks like there isn't any difference at all, and there really isn't. It now has its own header comment and is in a separate file, but everything else is the same. If you are coming from a background where you just put everything in one big file this may seem like a lot of extra work, but in a project of any size, breaking things out into pieces and dealing with a piece individually pays dividends in trying to keep the code manageable when you are in the development stage. If your editor doesn't support projects, there are many free ones that do and work with FreeBasic.
Setting Up a Project in FbEditI personally use
FbEdit, a near professional grade editor for FreeBasic. It includes a lot of nifty features, including projects. This is a short step-by-step explanation on how to set up a project for our screen object. I'll assume that you have downloaded and installed fbEdit and have downloaded and saved the two project files somewhere on your hard-drive.
First, start fbEdit and you should get a blank screen. Select
File->New Project from the Files menu. You will see a blank project set up screen (see projscr.png). Enter in the
Project Name, ScreenObject, and the
Project Description, DBF Screen Object Code. In the
Project Path edit field, enter or select the folder where you put the code files. Uncheck everything except
Bak in the
Folder Creation, uncheck everything in the
File Creation section and select Win + Console EXX or Windows EXX in the
Project Type dropdown and then click OK.
We are going to use the EXX setting for development since it does bounds checking and validates pointers while running. It slows down the code, but will help us when we do something silly in the code. Now if you look in the folder where you set up the project you will see a file ScreenObject.fbp, which is FbEdit's project option file.
You should now see a blank screen with an empty Project tab on the right. Right click on this tab and select
Add Existing->File from the popup menu. Select the fbgrtest.bas file. Repeat the process and add the fbscrobj.bi file. You are now ready to start coding. You can switch between the test code and object code with the tabs across the top, and if you look to the bottom right, you can examine various code sections by selecting the appropriate filter from the dropdown.
SummaryThat wraps up the 1.0 section of tutorials. In the 2,0 series we will be looking at and using color, something most graphics programs need to master in order to do their work. If you remember, the _buffer variable is really a color buffer, so color is going to play a key role in our screen object.