Protuberance Interface v1.0 Freeware

Fomalhaut Software 2002-2003

HTML Documentation

Contents:

1. Introduction
1. What is Protuberance Interface?
2. Features
3. Abbreviations
2. Starting
1. Requirements
2. Lauching and operating
2.1. Buttons
2.2. Inputboxes
2.3. Windows
2.4. Values
2.5. Switching screens
2.6. "Jammed" buttons
3. Structure
1. Basic objects description
1.1. Page
1.2. Box
1.3. Image
1.4. Message
1.5. Font
1.6. Background
2. Box
2.1. Creating/moving
2.2. Cloning
2.3. Position, size
2.4. Tag
2.5. Mode
2.6. Frame
2.7. Message / Label / Length
2.8. Alignment
2.9. Font
2.10. QuickNote
3. Image
3.1. Drawing mode
3.2. Type
3.3. Creating/moving
3.4. Sub-images, Items in a row
3.5. State effect
4. Window properties
4.1. Workspace, size
4.2. Magnification
4.3. Grid
4.4. Sub-workspaces
4.5. Arrangement
5. Font components
5.1. Size
5.2. Color
5.3. Horizontal spacing
5.4. Special symbols
5.6. Length mask
5.7. Layers and shifting
5.8. Font file name
4. Variables and constants
5. EMS Pages, handles
6. Programming
7. Procedures
1. Program
1.1. Initializing (PROGRAMINIT Sub)
1.2. Closing (PROGRAMCLOSE Sub)
2. Key pressing event (KEYPRESS Sub)
3. Page initializing (PAGEINIT Sub)
4. Resident (RESIDENT Sub)
5. Buttons
5.1. State (BTSTATE Function)
5.2. Pressing event (BTPRESS Sub)
6. Inputboxes
6.1. Value getting (VALGET Function)
6.2. Value setting event (VALSET Sub)
7. Scrollbars
7.1. Position getting (SCROLLBARGET Function)
7.2. Position setting event (SCROLLBARSET Sub)
8. Windows
8.1. Initializing (WNDINIT Sub)
8.2. Preparing for showing workspace (WNDPREPARE Sub)
8.3. Showing workspace (WNDITEMSHOW Sub)
8.4. Moving mouse cursor event (MOVEOVER Sub)
8.5. Mouse button pressing event (WNDPRESS Sub)
8.6. Dragging event (WNDDRAG Sub)
9. Alternate drawing
9.1. In-box graphics (BOXDRAWUSER SUB)
9.2. User frames (FRAMEDRAWUSER Sub)
9.3. User fonts (TPRINTFX Sub)
8. XMS Dynamic Arrays
9. Tutorial
10. Function reference
11. Troubleshooting
12. Bugs and limitations
13. Credits
14. Contact

Introduction

What is Protuberance Interface?

Protuberance interface is a shell in QBasic IDE. It's a system, that will help you to create user-friendly mouse-oriented programs without writing all that subrotinues to handle those infinite buttons, scrollers, windows etc. Protuberance is created to help programmers concentrate on the primary tasks like graphical design and program kernel.

Features

  • Created on the Future Library platform
  • Supports different screen resolutions (from 320x200 to 1600x1200 and so on)
  • Runs in 8Bit, 16Bit, 32Bit color modes
  • Graphical skins using (remember WinAmp?)
  • Advanced design system
  • Base elements: buttons, windows, inputboxes, scrollers
  • Unique windows handling (scrolling, magnifying with 3rd mouse button)
  • Flexible text printing system (horizontal spacing auto-select)
  • Lists with different styles of arrangement
  • Multi and monocolor fonts with variable length, layers
  • QuickHelp
  • XMS dynamic arrays
  • Fully customizable
  • Templates: screen mode selection, disk i/o

    Abbreviations

  • LMB - left mouse button
  • MMB - middle mouse button
  • RMB - right mouse button

    Starting

    Requirements

  • SVGA VESA-compatible video card
    VGA would work too. If the problems with hi-resolution modes will occur, download UniVBE driver from
    SciTech site
  • EMS manager
    If you encounter error message "No EMS manager" try typing in your config.sys file:
    DEVICE=C:\WINDOWS\HIMEM.SYS
    DEVICE=C:\WINDOWS\EMM386.EXE

    Change the paths if these drivers are in other location
  • Mouse
    In the plain DOS you need to load mouse driver first. Usual filename for this thing is MOUSE.COM or MOUSE.EXE

    Lauching and operating

    Editor is integrated program also based on the Protuberance Interface. In the startup screen you can choose resolution and color depth by clicking on one of the corresponding buttons. Then, you will choose: are you starting new project or load existed (once you save or load project, it will appear in the right-middle group of recent projects, so you can fastly load it later). To see how it all works you may try loading protuberance project or other projects and experiment with them (but remember, if you'll save changes of these projects, they may work incorrectly, so it'll be wise to create copies of them first).
    Some buttons are "hard to press". This mean, you must click both mouse buttons to activate these things. Usually, this feature belongs to importrant buttons, whose pressing can cause unconvertible consequences such as exiting program or deleting objects.

    Ok, if you want to create project, you need to enter its name. Click on the inputbox marked "Project name". It'll be selected by the dotted line and cursor will appear. This is a filename inputbox, so you can only enter symbols allowed in filename. When you entered project name and pressed ENTER to confirm it, you can change common directory name (default is "DATA"). This's directory, where most of additional files will be stored. You can either change inputbox by clicking on it or move dotted line cursor by pressing SHIFT+ARROW KEYS. When all the settings here is done, click "new project"

    Now you'll face the next importrant interface element: window. This window is for directory selecting. You can scroll window information (if window is viewing only portion of it) by holding MMB and drag the mouse or change the distance between directory names (change magnification level) by holding MMB+other one and drag. If you haven't middle mouse button you can use "`"(TILDE) key to switch on/off emulation of its pressing. Now enter the directory, where you want to locate your project and click on "Proceed".

    A directory with same name as a project will be created there. Then, all of the modules needed to run the interface will be copied to this directory and common subdirectory will be created. Some files will be added: project parameters file to the modules and interface elements files to common directory.

    Now you're in the main editor workspace. The program brings you to the settings screen so you can modify some constants according your targets. There's some other types of inputboxes, allowing to enter integer numbers. Notice two small +/- buttons near each inputbox. These buttons greatly helps, you can easily increase/decrease values with them by 1(RMB), 10(LMB), 100(Ctrl+RMB), 1000(Ctrl+LMB).

    Also you can see long bar and buttons with the pictograms near it. Editor is splitted into several screens (every of them allows you to edit certain objects) and these buttons are for switching between the screens. Long bar is for displaying and entering messages.

    Later you'll see inputboxes and buttons covered by black'n'white dots - they're 'jammed'. It means, you cannot use it now because of certain reasons. Now let's understand the basics of the interface structure.

    Structure

    Basic objects description

    Page can be imagined as a paper, where interface elements can be situated. You can have several pages in your project. In example, you can use first page for your main editor window, second for load / save dialog, third for defining options, etc.. Of course, you can switch the pages by events you choose.

    Box is a rectangular area on the page. Buttons, windows, scrollers, input fields and other things on page are boxes with different parameters.

    Image is also rectangular area, but on the special canvas called skin. Skin is a drawing, that define all raster graphics (appearance of boxes) of your interface project. You can modify standart skins for your purposes or create your own in one of your favorite painting programs.

    Message is simply a static text string. Messages are intended for box labels and quick notes (notes, that appear on the info box or simply near mouse cursor, when user points to certain boxes).

    Font consist of symbol image libraries and pack of parameters that defines how to print them.

    Box

    Clicking on the button brings you to the page editing screen. You can put boxes on the page by dragging mouse with pressed RMB from one corner of the box to opposite corner. However, boxes cannot overlap each other. If you press LMB on empty space and drag the mouse, selecting frame will appear. Release button to select all boxes covered by this frame (selected boxes will be marked with dotlines). Existed boxes (even several) can be moved (LMB) or resized (RMB).

    Also (and it easies the work very much) you can clone selected boxes. To do this, select boxes and drag LMB like moving them. Press F7 while dragging and boxes will be cloned to the choosen place when you release mouse button

    One selected box is marked by another type of dotline. Properties of this box is shown on working panel in the top of the screen. You can modify these parameters and changes will be applied to all selected boxes. Notice, if you press +/- buttons, corresponding parameter of every selected box will increase / decrease by same value, not equated as if you enter value in the inputbox.

    Workspace is marked by the grid, its parameters can be edited in options page. Purpose of the grid is simple - you can stretch the workspace to fit it in certain resolution only by changing grid cell size. X, Y - coordinates and Xsize, Ysize are measured in integer grid cells.

    The box in your program will be recognized by a tag. When user press button, enter value in the inputbox, move the scroller, corresponding sub will return tag number. I recommend giving every box its own unique tag to eliminate possible bugs. Later will be explained how to link buttons and inputboxes in groups with the tags.

    Box can act as

  • Button with
    1. Static message
    2. Dynamic message
    3. Static image
  • Inputbox, allowing to enter
    1. String
    2. Integer value
    3. Signed integer value
    4. Floating point value
    5. Signed floating point value
    6. File name
    7. File name + extension
  • Scroller
    1. Horizontal
    2. Vertical
  • Window
  • Panel (page-in-the-box)

    Frame is an image, that defines the box appearance (how it's done will be explained later)

    You can define a message or an image for button label. For inputboxes you defining the length of string (in symbols), that can be entered.

    Nine buttons in the center of the panel is for setting box alignment. The text in a boxes usually aligned to center of the box, but you can change it to the top, or bottom-left corner for example. The button switches align rectangle from all the box to space inside frame.

    You also can set the font for every button, so text there can be printed in different styles.

    QuickNote is message that pop-ups, when you hold the cursor on the button too long. It mainly used by novices for quick familarizing the program. You just enter message number in the box marked "Help".

    Image

    As have been said before, image is rectangular area on the skin. This area can be ported to a rectangular area (the box) on the screen. When sizes of the areas are the same, all is easy - program can simply copy part of the skin to the screen. But if rectangles are different - some tricks needed to acquire good scaling effect. Here's the list of the styles:
    1. Image will be cutted if it is larger than the box, else it'll be printed in the center.
    2. Box displayed as the filled rectangle with the color same as of the topleft pixel of the image
    3. Box appears as the gradient rectangle, using colors of the image corners.
    4. Box will be filled with vertical lines according to the colors of image top row.
    5. Same but for the horizontal lines and left column.
    6. Image cover the box as texture, e.g. it duplicates if box is larger than image and truncates otherwise.
    Image can be simple picture or frame. The frame is two sequental images, second inside first. Frame has 4 staic rectangles in corners, 4 stretchable bars on sides and stretchable field inside them. Experiment and see how the frame can be ported to the screen.

    Defining the image is easy - press RMB on empty area and drag mouse like creating a box. Moving (LMB) and resizing (RMB) is also similar to a box. However, selecting multiple images is not implemented.

    But every image is not simply a rectangular area, it's an array of areas. Sub-images are situated like cells in a grid. You can set InRow parameter, it defines how many sub-images are in one row of this grid. This table shows how items are numerated:

    00010203
    04050607
    08091011
    ...
    But buttons are usually not just static images - they sometimes been pressed and jammed. Protuberance has standart way to do both, but it sometimes looks crappy. Alternate way is changing button image. You can set rule for decrement image or sub-image number by value (0 - normal, 1 - pressed, 2- jammed, 3 - pressed and jammed).

    Window

    Windows can be used for serving a big bunch of different tasks: image editing, showing, file i/o dialogs, lists, etc.. Simple window has a rectangular workspace, that you "can see through" the box's inner area. If workspace is bigger than the window box, it can be scrolled, if workspace is smaller, it will be aligned by mode you set for the box. Position and size of the workspace can be entered in the editor, but usually it needs to be changed in the program.

    Window cam be magnified by user if the magnification bounds has been set (you can set them (and magnification level too) for X and Y axises separately). For default, they're all 1's (size is original). In example, if you set XMGNMAX to 2, user will be able to double workspace x-size in the program.

    You can set the grid for window workspace. In example, if you making an image editor for N*M images, it's good to have grid with N*M resolution for image editing window. The grid is implemented for ease the programming, its parameters affects only corresponding procedures.

    Yeah, window can hold a group of workspaces! It's very useful feature that allows you to make lists (of files, images, etc..). You can define (in editor or in program) quantity of workspaces and InRow parameter (workspaces in a row).

    Though you can set InRow number, you also can allow program to change it automatically, in other words items can be arranged to fit along the height or width of the box.

    Font

    Protuberance can handle multicolor (NxM pictures of letters ripped from the graphic image) and monocolor fonts (8xN Future Library fonts). But you also need to set some parameters. Size is just a h/v size of a every letter.

    Color is needed only for monocolor fonts - just enter RGB values. If it's 8bit color depth then nearest color of the palette will be used.

    You can define the spacing between letters. It's not just a value - it is interval. What is it for? Sometimes, text isn't fits the box, so it's good to reduce horizontal spacing to print it all. But if spacing is too low (it can be less than zero), text becomes unreadable, so set minimum value keeping this in mind. If minimum horizontal spacing is insufficient, some text will be cutted and "..." symbol will be printed.

    Special symbols are "..." (explained above) and cursor. You can set them selecting symbol in the upper window by LMB and pressing corresponding button.

    Length mask is another importrant feature - it's for defining every symbol his own length. You can create it with button and set symbol length by first setting its length in xsize (it will not affect the font that has lengthmask) and click RMB on the symbol in the upper window. For example, see how SMALL.PFN font in PROTUBERANCE has been set.

    Font may consist of several layers, e.g. several sequental fonts may be printed each over another. And you can relatively shift layers by alter corresponding values. In example, for "bump" font, you need to print grey-colored text shifted by one pixel down first, then black-colored with no shifting. To do it, make 1st font grey, set yshift to 1, layers to 2, make 2st font black. See how it done in protuberance fonts. You can also made "shadowed" or "true-bump" fonts. Try improvise with that.

    Filename is just Future Library font file ("FNT") or picture ("BMP","GIF","PCX"). In font design page you just can switch font filenames. They can be defined if file i/o page - select "font skins" and choose file in the filelist and press "Load". If it's Future Library font - it will be copied to the common directory, stored in the font file base and available for use. Graphic images must be "cutted" into several letters, so you must define how it will be done (set letter size, quantity and items-in-row (like as for images).

    Variables and constants


    sxres, syres, sbytes - current screen resolution (in pixels) and color depth (1 - 8Bit, 2 - 16Bit, 4 - 32Bit)
    scrxres, scryres, coldepth - screen resolution and color depth by default

    gxsiz, gysiz, sqsiz - current grid resolution (in grid cells) and cell size (in pixels)
    xp, yp - workarea shift (in pixels)
    xgrid, ygrid, sqs - grid resolution and cell size by default

    comdir$ - common directory
    pagefile$, skinfile$, imgfile$, wndfile$, msgfile$, fontfile$ - system files to load by default

    boxmax, pagemax, imgmax, msgmax, wndmax, fontmax, lenmaskmax - maximum of interface objects

    msgbuf - amount of XMS memory for messages
    pagebuf - amount of XMS memory for pages
    xmsiobuf - amount of base memory for XMS i/o operations buffer
    filemax - maximum quantity of files and directories that can be stored

    mx, my - mouse cursor coordinates (in pixels)
    mb - mouse button status (1 - right, 2 - left, 4 - middle button pressed)
    mmb - middle mouse button emulation (0 - off, 1 - on)

    exitcode - set it to non-zero to perform shell exit

    filequa - quantity of files and directories stored by DIRGET

    EMS pages and handles


    0 (bhn) - main screen buffer (sxres*syres)
    1 (dhn) - sensitive area (gxres*gyres)
    2 (shn) - skin
    3 (whn) - secondary screen buffer (sxres*syres)

    Programming

    For quick access to your project, modify PATH variable in your AUTOEXEC.BAT file in C: root directory. You'll probably encounter this string:

    SET PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\

    Insert there directory of your QB files, in example, if your QB is in the C:\QB\QB45 change the string to:

    SET PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\;C:\QB\QB45

    Then, copy there all *.LIB and *.QLB files (including PFL.LIB, PFL.QLB) that you use. Restart your machine. Now you can lauch QB with all these libs from any directory, in example, if your project is C:\QB\MYPROJ\myproj.bas you can lauch FAR or WC, go to C:\QB\MYPROJ\, type in QB /LFUTURE45.QLB, load file and start programming. If you'll lauch QB from its directory first, then your prog, you'll encounter problems with path to additional files in COMMON DIRECTORY of the project.

    It's also recommended to store LIB and QLB modified specially for this project (in case you want to add some modules in FLBUILD) in its directory. Here's the minimum list of modules required:

  • EMS library
  • SVGA library (3D, Mouse, Import graphics, Font loading)
  • XMS library

    So, you lauched QB with the library (to use this set of modules type QB /LPFL). Now open main module with name you choosed when created project. PROGRAM.BAS and ADMODULE.BAS also will be loaded. You'll substantially edit PROGRAM.BAS file. But you also can add other modules to your main file. To do this, load ADVANCED.BAS module using "Load File" command, then move subs you needed from this file to project's main module, then save all, unload ADVANCED.BAS using "Unload File" and save all again.

    In next chapter PROGRAM.BAS subs will be described. You will fill them with code gradually during your work.

    Procedures

    Program


    PROGRAMINIT () Sub - initializing
    Called:
    Once in the beginning.

    Mainly used for:
    Initialization code of your program - memory allocation, variables definition, DATA reading, etc.


    PROGRAMCLOSE () Sub - closing
    Called:
    Before exiting.

    Mainly used for:
    Memory deallocation and saving config.


    Key pressing event


    KEYPRESS (I$) Sub
    Called:
    When user presses a key.

    Parameters:
    I$ - the string, returned by INKEY$.
    I% - ASCII code for symbol keys and (300 + scancode) for others. In example, I% = 48 for "0" key (ASCII code = 48), I% = 375 for LEFTARROW key (scancode = 75).

    Note:
    Check shifters (SHIFT, ALT, CTRL) state with LSHIFTPRESSED, RSHIFTPRESSED, CTRLPRESSED, ALTPRESSED functions and SHIFTERSGET sub.


    Page initializing


    PAGEINIT (n%) Sub
    Called:
    Before page setting

    Parameters:
    n% - number of the page being set

    Mainly used for:
    Setting values


    Resident


    RESIDENT () Sub
    Called:
    Repetitive during the shell main loop.

    Mainly used for:
    Maintaining all parts of the program that must work "on the background" - such as sequental window refresh, infoboxes update (such as clock). It's recommended to reduce the time needed for one step of this sub. Try to split time-wasteful task in small but speedy steps. In example, don't draw whole image by one step - draw just horizontal line by step. Otherwise you'll notice how hardly mouse cursor and whole program will react on your actions.


    Buttons


    BTSTATE% (w%) Function - defining state of the button
    Called:
    When checking of the button state is needed

    Parameters:
    w% - number of the checking box
    tag% - tag of the box
    pressed% - set this variable to 1 for making the button 'pressed'
    jammed% - set this variable to 1 for making the button 'jammed'

    Returns:
    button state (1 * pressed% + 2 * jammed%)


    BTPRESS (w%) Sub - pressing event
    Called:
    When user press mouse button on the box

    Parameters:
    w% - number of the clicked box
    tag% - tag of the box


    Inputboxes


    VALUEGET$ (w%) Function - value getting
    Called:
    When checking of inputbox value is needed

    Parameters:
    w% - number of the box
    tag% - tag of the box
    vi% - for returning INTEGER
    vs! - for returning SINGLE
    v$ - for returning STRING

    Returns:
    box STRING


    VALUESET (w%,v$) Sub - value setting event
    Called:
    When user changes box value (and confirmes it)

    Parameters:
    w% - number of the box
    tag% - tag of the box
    vg% - 0 if direct input is used, 1 if increment/decrement is used
    vi% - box STRING converted to INTEGER
    vs! - box STRING converted to SINGLE
    if increment/decrement is used, vi% and vs! will be equal to this decrement

    Note: See tutorial for advanced value setting group (with +/- buttons) programming


    Scrollbars


    SCROLLBARGET% (w%) Function - position getting
    Called:
    When redrawing scrollbar

    Parameters:
    w% - number of the box
    tag% - tag of the box


    SCROLLBARSET (w%) Sub - position setting event
    Called:
    When user moves the slider

    Parameters:
    w% - number of the box
    tag% - tag of the box


    Windows


    WNDINIT (tag%) Sub - initializing
    Called:
    After loading windows bank

    Parameters:
    tag% - tag (number) of the window


    WNDPREPARE (w%) Sub - preparing for showing workspace
    Called:
    Before window refreshing

    Parameters:
    w% - number of the window box
    tag% - tag (number) of the window
    Col% - color to clear window with

    Mainly used for:
    All calculations and settings needed for displaying window


    WNDITEMSHOW (w%, num%, x1%, y1%, x2%, y2%) Sub - showing workspace
    Called:
    For every window workspace when refreshing

    Parameters:
    w% - number of the window box
    tag% - tag (number) of the window
    num% - number of the workspace (list item)
    x1%, y1%, x2%, y2% - coordinates of topleft and bottomright workspace corners


    MOVEOVER (w%) Sub - moving mouse cursor event
    Called:
    When mouse cursor is moving over the window

    Parameters:
    w% - number of the window box
    tag% - tag (number) of the window


    WNDPRESS (w%) Sub - mouse button pressing event
    Called:
    When user presses mouse button on window

    Parameters:
    w% - number of the window box
    tag% - tag (number) of the window
    v% - number of the workspace under mouse cursor


    WNDDRAG (w%) Sub - dragging event
    Called:
    When user drags mouse over the window

    Parameters:
    w% - number of the window box
    tag% - tag (number) of the window
    X1%, Y1% - windows coordinates of dragging start
    X2%, Y2% - window coordinates of mouse cursor
    dx%, dy% - difference between coordinates


    XMS Dynamic Arrays

    This pack of very useful subs allows you to store unlimited arrays with non-fixed length of items. You can store arrays of messages, scripts, different-size images, etc in XMS now!

    First you need to init XMS array by calling function XMSDAINIT that return XMS handle of the allocated XMS space (and you can refer to array by this handle). Parameter itemsmax% is maximum quantity of items in your array. Sizebyt% is size in bytes of the array stack (set it to maximum space you might use plus some more).

    Mow you can store items in array by XMSDAPUT and retrieve by XMSDAGET. Just specify the handle of array (handle%) and number of item (num%). Offset% and Segment% - address of base memory to get from / put to, sizebyt& - size of item.

    Troubleshooting

    I run my program and messages (or everything) disappeared!
    Perhaps you forgot to deallocate XMS memory (DeallocateXMS sub) or exited your program with Ctrl-Break several times. Try to save all and reload QB IDE.

    I have added some buttons and they are not visible under QB!
    It seems that you have running Protuberance Editor and QB IDE with your program simultaneously. Note that if you add some new objects in editor, maximum quantity of them stored in your project (*.PPR) file may be changed on disk but not in memory of QB IDE (project file is also used as INCLUDE for program). So, reload QB in this case (save all except PPR file). You can also alter the maximum quantities of objects in options page (in example, set the maximum boxes number to 100 to avoid these errors in future if you never have more than 100 boxes on a page)

    Bugs and limitations

  • Selectable screen mode template and disk i/o dialog can be used just together.
  • Deleting objects may cause errors
  • To import fonts you need to copy all needed font files to your directory manually.
  • There are bugs with font management in editor
  • If the drive isn't ready, sytem will hang

    Credits

    Protuberance is created by Matt Merkulov
    Using Future Library by Jorden Chamid and Michael Rye Sorencen
    Disk routines by Rich Geldreich

    I would like to greet Nyron, Redojeker, Orphus, Max Kechaykin, Nick Gorkun, Andrey Selyakin, and all QBers!

    Thanks Red Flag, Pain, To/Die/For, Sonata Arctica, Apocalyptica, Enigma, Blind Guardian, R. E. M., Zodiac, Vacuum, Metallica, Aerosmith, Scorpions, Electric Light Orchestra, Beatles, Dire Straits, Queen, U2, Alan Parsons, Gregorian, Theatre of Tragedy for their music.

    Contact

    I waiting for your impressions, comments, bug reports, created program submissions. Feel free to email or post messages on site messageboard. If you'll use Protuberance Interface, please give me a credit and mention FSoft site address.

    Fomalhaut Software Site: http://fsoft.cjb.net
    E-Mail: Agravein@fsoft.cjb.net

    2002-2003, Fomalhaut Software