freebasic-examples/src/screenres.fb.bas
2023-07-09 12:18:33 +01:00

569 lines
21 KiB
QBasic

/' ######################### ABSTRACT ##############################
File: ScreenRes_Width.bas Updated: 2015 Jan 03
Language: FreeBASIC 1.00.0 ( 32bit Windows ) By: Dean Saurdine
Purpose: Demonstrate font sizes in console and GfxLib gui screens
Skillset: beginning Beginner
Notes: 1) No copyright. Public domain. No warranty. Your risk.
2) Coded Courier New 10pt on 72 columns.
3) Ensure -s gui compiler switch is NOT set.
4) The three main program segments can be three different
program files and three different executables, if desired.
5) Appendix follows main program and can be read first, if
desired. Written for the beginning Beginner.
##################################################################### '/
REM####################### MAIN PROGRAM ############################
/' ********************************
***** FreeBASIC console screen *****
********************************
'/
REM setup FreeBASIC console screen
Screen , Rem default FreeBASIC screen
Width 43,28 Rem columns,rows
Color 0,15 Rem black foreground,white background
Cls
REM print box grid at font size
Color ,7 Rem light gray background
For false_loop As Integer = 0 To 0
Dim As Integer row = 0
Dim As Integer column = 0
Rem odd numbered rows
For row = 1 To 27 Step 2
For column = 1 To 43 Step 2
Locate row,column : Print Space(1) ;
Next column
Next row
Rem even numbered rows
For row = 2 To 28 Step 2
For column = 2 To 42 Step 2
Locate row,column : Print Space(1) ;
Next column
Next row
Next false_loop
'Print row Rem try compiling with this line uncommented
/'
Note: the variables false_loop, row and column are visible only while
the false loop runs, which is exactly one time. false_loop, row and
column are created once. This coding technique is efficient for
loop-in-loop with large counters and small steps, a common occurence
when creating "graphic" elements. The expense is the creation of
false_loop, which is a do-nothing variable. Alternatives to a false
loop? Will they obfuscate the code?
Counting "variable creations" can be considered as a first step in
managing the computer's memory space. Programs with well managed memory
space run faster and smoother, and the concept becomes increasingly
important as programs become larger and more complex. More advanced
memory space management methods are beyond this program's purpose.
'/
REM print text
Color ,15 Rem back to white background
'Color ,7 Rem try this for different visual effect
Locate 2,2 : Print "FreeBASIC console font size 8x12 pixels" ;
Locate 5,2 : Print "console 'Print' is opaque background" ;
Locate 10,9 : Print "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
Locate 12,9 : Print "abcdefghijklmnopqrstuvwxyz" ;
Locate 14,9 : Print "0 1 2 3 4 5 6 7 8 9 ~_+`-=" ;
Locate 16,9 : Print "!@(#)$[%]^{&}*<?>;':""|,\." ;
Locate 21,9 : Print "press a key to continue..." ; : Sleep
Locate 21,9 : Print " " ;
/' *************************
***** GfxLib gui screen *****
*************************
'/
REM sub definitions
Sub model( ByVal columns As Integer , _ Rem console layer
ByVal rows As Integer , _ Rem console layer
ByVal w As Integer , _ Rem font width in pixels
ByVal h As Integer _ Rem font height in pixels
)
REM set and display the different GfxLib gui screen font sizes
REM finish setup GfxLib gui screen.
'ScreenRes 336,336 Rem graphic layer x,y pixels
Width columns,rows Rem console layer for font size w x h
Color 0,15 Rem black foreground,white background
Cls
/'
Note: window, screen, and layer are different concepts. For now, we can
say "layers on a screen, screen in an operating system window." We can
also say "everything that can be done on the console screen is now done
on the GfxLib gui screen's console layer".
The first mnemomic will eventually become "viewport in a layer, layer on
a page, page on a screen, screen in an operating system window."
Viewports and pages are beyond this program's purpose.
Executing ScreenRes more than once may result in the GfxLib gui screen's
operating system window returning to its original position, if it has
been moved while the executable is running. Try it by uncommenting
ScreenRes in this code block.
'/
REM print text on console layer
Locate 2,2 : Print "GfxLib gui font size 8x" + Str(h) + Space(1) + _
"pixels" ;
REM draw text on graphic layer
Color 32 Rem bright blue foreground
Draw String ( (2-1)*w,(2-1)*h ), "GfxLib gui"
/'
Note: the GfxLib gui screen, as it is set in this program, has an
adjustable 256 color palette, with color index numbers from 0 to 255.
For now, we can say Color 0 and Color 15 are identical to the console
screens. Color 1 through Color 14 may look different. Adjusting the
GfxLib gui screen's color palette is beyond this program's purpose.
The Draw String should precisely overlay the first part of the Print.
The "math" inside the Draw String's outer braces converts a column,row
position to an x,y position, using the following general equations:
x = ( pseudo column - 1 ) * w
y = ( pseudo row - 1 ) * h
Pseudo because real columns and real rows are on the console layer.
The 1 is because the layers have different origin coordinate numbers:
The console layer's origin coordinate numbers are column,row = 1,1.
The graphic layer's origin coordinate numbers are x,y = 0,0.
The two origins are at the same place, which is the GfxLib gui screen's
upper left corner.
The w is because one console layer column is w pixels wide, and the h is
because one console layer row is h pixels high.
Pseudo column and pseudo row do not need to be integers in these
equations. The calculation results will be reduced to the next lower
integer when used for the x and y positions in a drawing command. Try
pseudo column = 2.6, pseudo row = 3.3, or some other fractions.
'/
REM draw box grid at font size on graphic layer
Color 7 Rem light gray foreground
Scope
Dim As Integer y = 0
Dim As Integer x = 0
For y = 0 To (rows-1)*h Step h
For x = 0 To (columns-1)*w Step w
Line (x-1,y-1)-(x+w-1,y+h-1),,B Rem B = hollow Box
Next x
Next y
End Scope
'Print y Rem try compiling with this line uncommented
/'
Note: the Scope...End Scope code block works the same way as a false
loop, and has the advantage of not creating a do-nothing variable.
Alternatives to Scope, without obfuscating the code?
Placement of the grid, for visual effect, depends on the font size
and the physical pixel size and shape. Different "screen" manufacturers
and/or models may have different physical pixel sizes and shapes.
code correct... Line (x,y)-(x+w,y+h),,B
move box one pixel left... Line (x-1,y)-(x+w-1,y+h),,B
then one pixel up... Line (x-1,y-1)-(x+w-1,y+h-1),,B
Remember: "good visual effect" may not always be "code correct".
'/
REM mixed printing and drawing on their respective layers
Color 0 Rem back to black foreground
'Color 0,7 Rem try this for different visual effect
Locate ( 5,2 ) : Print _
"console ""Print"" is opaque background" ;
Draw String ( (2-1)*w,(7-1)*h ), _
"graphic ""Draw"" is transparent background"
Draw String ( (9-1)*w,(10-1)*h ), _
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Draw String ( (9-1)*w,(12-1)*h ), _
"abcdefghijklmnopqrstuvwxyz"
Draw String ( (9-1)*w,(14-1)*h ), _
"0 1 2 3 4 5 6 7 8 9 ~_+`-="
Draw String ( (9-1)*w,(16-1)*h ), _
"!@(#)$[%]^{&}*<?>;':""|,\."
Locate ( 21,9 ) : Print _
"press a key to continue..." ;
Sleep
/'
Note: this coding style shows the coding similarities and differences
between printing text on the console layer and drawing text on the
graphic layer. What are they? Does printing and drawing order matter?
Recall the "math" inside Draw String's outer braces converts column,row
position to x,y position. Can you create general equations to convert
x,y position to column,row position? Where would they be used?
'/
End Sub
REM end of sub definitions
REM main program
REM start setup GfxLib gui screen
ScreenRes 336,336 Rem graphic layer x,y pixels
'Width columns,rows Rem in the sub definition
'Color foreground,background Rem in the sub definition
'Cls Rem in the sub definition
REM set and display the different GfxLib gui screen font sizes
model( 42,42 , 8,8 ) Rem console layer columns,rows for font size w,h
model( 42,24 , 8,14 ) Rem ditto
model( 42,21 , 8,16 ) Rem ditto
'model( 42,28 , 8,12 ) Rem try this illegal font size, with and
Rem without the other models.
REM end of main program
/' *****************************
***** GfxLib console screen *****
*****************************
'/
REM setup GfxLib console screen Rem closes GfxLib gui screen, if open
Screen 0 Rem GfxLib console screen
Width 80,25 Rem default columns,rows
Color 7,0 Rem default foreground,background
Cls
REM print text
Locate 2,2 : Print "GfxLib console font size 8x12 pixels" ;
Locate 21,2 : Print "press a key to end this executable..." ; : Sleep
REM end of main program
REM#####################################################################
REM######################## APPENDIX ###############################
/'
----------
"Graphic screen text is too small" usually means a lack of understanding
of how the GfxLib gui screen works. There is a lot to learn and this is,
fortunately, one of a very few times that interrelated concepts have to
be learned simultaneously.
This program belongs to the category of "study and play with this, then
see me if you have questions". It is written in the FreeBASIC (fb)
dialect of the BASIC coding language.
This appendix and main program's /'Note...'/ are meant to supplement the
existing wiki pages, and have evolved with "can you explain..." and "can
I see your 3-ring binder...". /'Note...'/ can be considered as footnotes
to specific code blocks. My questions and "try this" are meant to
stimulate thinking and creativity.
----------
Prerequisites, or keywords/keyboard keys "you are supposed to know".
Some do not have proper wiki pages as of this appendix's writing.
colon (statement termination = : = CR)
Enter key (statement and line termination = Enter key = CRLF)
underscore (statement continuation = _ = suppress CR in CRLF)
Rem (human readable comment, in the FreeBASIC variations)
Screen , (FreeBASIC console screen)
Width (screen size)
Color (screen Colors)
Cls (Clear the screen)
Locate (position screen cursor)
Print (Print something on screen)
Dim (variable definition)
Integer (variable or expression type)
String (variable or expression type)
Str (create String from number)
Space (flexible, human readable version of " ")
plus (String concatination = +)
Scope...End Scope (code block, localized new variable visibility)
For...Next (code block, looping with built-in counter)
Sub...End Sub (code block, branching)
Sleep (suspend program execution)
New keywords to learn:
ScreenRes x,y (GfxLib gui screen)
Screen 0 (GfxLib console screen)
Draw String (Draw text as String on graphic layer)
Line (draw Line or box on graphic layer)
----------
To be consistent with the corresponding compiler switches, which are
-s gui and -s console, the word "gui" is used to identify what other
coders may call "graphic" screens.
----------
"Terminal 8x12" is the intended font style and size for the console
screen segments of this program.
See my Console_Defaults.bas program for discussion of console screen
default settings (Windows operating system).
----------
Font size can be verified with this program's running executable. There
should be, for font size 8x12, four lines for every three lines of font
size 8x16. Eight lines for every six lines, sixteen for twelve...
"Four for three" is calculated from the Least Common Multiple (LCM) of
12 and 16. LCM is a concept from mathematics.
LCM( 12,16 ) = 48. 48 is the smallest common screen height, in pixels.
Then calculate the corresponding number of available screen rows from:
available rows = LCM / font height
8x12 font size: available rows = 48 / 12 = 4
8x16 font size: available rows = 48 / 16 = 3
----------
GfxLib is one of FreeBASIC's built-in libraries. GfxLib contains the
FreeBASIC gui screens and another FreeBASIC console screen. In this
appendix, the screens accessed via GfxLib are called GfxLib gui screen
and GfxLib console screen, and the default FreeBASIC console screen is
called the FreeBASIC console screen.
The GfxLib console screen can be considered as having the same default
screen settings as the FreeBASIC console screen, and these defaults are
set in the same way (via cmd.exe).
Use the FreeBASIC console screen if your program has no gui elements, as
GfxLib will bloat the executable. Use the GfxLib console screen if, for
any reason, you want to switch from a GfxLib gui screen to a console
screen.
----------
Initiating a GfxLib gui screen with the "Screen mode" statement is from
old BASIC dialects, and should only be used for initial translation of
old BASIC programs. The FreeBASIC way to initiate a GfxLib gui screen is
through the use of the ScreenRes keyword. ScreenRes can be used in a
simple way, as in this program, or ScreenRes can be more capable than
the various gui screens created from "Screen mode".
----------
The GfxLib gui screen can be considered as having one built-in unnamed
fixed-width font, whose style resembles Courier. Most text editors and
word processors set font size in points. GfxLib gui screen's font size
is set in pixels. This font size is represented by a box w pixels wide
and h pixels high. Characters, in the font set, fit into the box.
GfxLib gui screen's available font sizes are 8x8, 8x14 and 8x16. In
words, the available font width is w = 8 pixels and the available font
heights are h = 8, 14 and 16 pixels. The default height is h = 8 pixels.
The size of the GfxLib gui screen's built-in font can be adjusted by the
coder through the use of the "ScreenRes x,y" and "Width columns,rows"
statement pair. Adjusting the size of GfxLib gui screen's built-in font
is a purpose of this program.
The coder can, through advanced use of the ScreenRes keyword, introduce
and use other fonts. The coder can also use other libraries to introduce
and use other fonts (and screens). Other fonts and screens are beyond
this program's purpose.
----------
The following LCM table can be used to "rapid prototype" the GfxLib gui
screen, with built-in font size options to try for a common screen size.
LCM = Least Common Multiple, a concept from mathematics.
+--------------------------------+
LCM | rows ( for gui font 8 x h ) |
+-----------+--------------------------------|
| ScreenRes | | | |
| y | h = 8 | h = 14 | h = 16 |
| pixels | | | |
|============================================|
| 112 | 14 | 8 | 7 |
| 224 | 28 | 16 | 14 |
| 336 | 42 | 24 | 21 |
| 448 | 56 | 32 | 28 |
| 560 | 70 | 40 | 35 |
| 672 | 84 | 48 | 42 |
| 784 | 98 | 56 | 49 |
| 896 | 112 | 64 | 56 |
| 1008 | 126 | 72 | 63 |
| 1120 | 140 | 80 | 70 |
| 1232 | 154 | 88 | 77 |
| 1344 | 168 | 96 | 84 |
|======================+---------------------+
| x | columns |
+----------------------+
Read up for x and columns, for font width w = 8 pixels.
Read down for y and rows, for font height h = 8 or 14 or 16 pixels.
Code as: ScreenRes x,y
Width columns,rows
Example: setup GfxLib gui screen smaller than x,y = 800,600 and at font
size 8x14, using the LCM table.
code as: ScreenRes 784,560
Width 98,40
----------
x,y and columns,rows are calculated from the following equations, which
can also be used "fine tune" the GfxLib gui screen after deciding on a
particular font size:
either: columns = x / 8 and rows = y / h
or: x = columns * 8 and y = rows * h
where: h = 8 or 14 or 16
Code as: ScreenRes x,y
Width columns,rows
All equation elements need to be exactly integers (no fractions), or the
GfxLib gui screen font size may revert to the default 8x8. The available
columns,rows will then become the next lower integers, based on the
GfxLib gui screen's default 8x8 font size and the coder's x,y.
Example: setup GfxLib gui screen smaller than x,y = 800,600 and at font
size 8x14, using the equations.
columns = x / 8 = 800 / 8 = 100 ...all are exactly integers
rows = y / h = 600 / 14 = 42.86 ...fractions! Use rows = 42
then... y = rows * h = 42 * 14 = 588 ...all are exactly integers
code as: ScreenRes 800,588
Width 100,42
----------
Summary of FreeBASIC screen features ( for now... )
+-----------------------------------------------+
FreeBASIC Screens | console | GfxLib gui |
| ( Windows ) | |
+---------------------+===============================================|
| screen initiation | Screen , (FreeBASIC) | ScreenRes x,y |
| | Screen 0 (GfxLib) | |
|---------------------+-------------------------+---------------------|
| screen size | columns,rows | x,y |
|---------------------+-------------------------+---------------------|
| default screen size | set via cmd.exe | not defined |
|---------------------+-------------------------+---------------------|
| font style | set via cmd.exe | similar to Courier |
|---------------------+-------------------------+---------------------|
| font size | set via cmd.exe | adjustable 8x8 |
| | | 8x14 |
| | | 8x16 |
|---------------------+-------------------------+---------------------|
| default font size | set via cmd.exe | 8x8 |
|---------------------+-------------------------+---------------------|
| screen colors | fixed 0 to 15 (cmd.exe) | adjustable 0 to 255 |
|---------------------+-------------------------+---------------------|
| default Color | 7,0 if Color is used. | 15,0 |
| | Set via cmd.exe if | |
| | Color is not used. | |
|---------------------+-------------------------+---------------------|
| layer types | "console" | console |
| | | graphic |
+---------------------------------------------------------------------+
Whether or not "console" exists depends on the point of view you are
comfortable with. "Console" as shown here is consistent with the "layers
on a screen, screen in an operating system window" mnemonic. It is
equally correct to say "FreeBASIC console screens do not have layers".
See my Console_Defaults.bas program for discussion of cmd.exe settings.
----------
The following "code" is copy/paste from my template file, named
template_FreeBASIC.bas and saved as a "read only" file. The file helps
me code in a consistent style, and the file evolves as I learn.
REM setup FreeBASIC console screen
Screen , Rem default FreeBASIC screen
Width 80,25 Rem default columns,rows
Color 7,0 Rem default foreground,background
Cls
REM setup GfxLib gui screen
ScreenRes x,y Rem graphic layer pixels
Width columns,rows Rem console layer for font size w x h
Color 15,0 Rem default foreground,background
Cls
REM setup GfxLib console screen Rem closes GfxLib gui screen, if open
Screen 0 Rem GfxLib console screen
Width 80,25 Rem default columns,rows
Color 7,0 Rem default foreground,background
Cls
Comments are free! In my coding style, comments "to the left" describe
code blocks, while comments "to the right" are like sticky notes.
FreeBASIC code is letter-case insensitive, so I use REM "to the left" to
describe a code block and Rem "to the left" to describe a code block
within a code block.
----------
'/
REM end of appendix
REM#####################################################################
REM end of file